Shado - 1 million instances, 20k+ rendering, auto VAT, full custom properties, dynamic WebAssembly

Hello hello everyone, I am emerging from the depths – I was pretty active awhile back working on a game and supporting frameworks and got sidetracked with work and then RL, and somehow after our new child was born recently I’ve had enough time to collect the various parts that had supported that and publish a release version of the package extension for BJS core I’ve been using. In the meantime the pre-release version is something I’ve been able to integrate into my work and will be using the package for future-forward 2d/3d visualizations for high scalability and high performance rendering.

Introducing Shado ( https://www.npmjs.com/package/@knervous/shado ) major release, available for public use and maintenance / requests.

Shado is a full plugin extension for BabylonJS. I’ve been working on this from the ground up in different ways for a few years tackling different problems separately. It is not for every use case, and requires to stay inside its framework to be useful to the full extent. Shado is right for you if:

  1. You are rendering hundreds / thousands of actors of the same entity type that differ in ways not currently exposed via BJS core (thininstances support base attributes like location, rotation, scale, rudimentary animation controls), and would benefit from concepts like many (50-100k) entities “defined and live in runtime” but not rendered at any given moment.
  2. You are willing to dive into a more technically-complex solution in a trade for high performance scaling (comfortable with writing some custom shader logic and reading / understanding assemblyscript - not a hard requirement but streamlines dev)
  3. You are looking for full-stack messaging solutions that scale well beyond existing frameworks like protobuf, flatbuffers, capnp etc. This is an advanced feature to sync backends with a shared message format that reduces deference timing and GC alloc that “solves” a lot of network backend scalability for higher level language backends like TypeScript/JS in nodejs for a backend high throughput server like an MMO server.

Before going through the whole spiel, a picture’s worth a thousand words:

51k instances, all unique animations and skins and held items (sword, mace, spear, etc.) running at 60fps while 11k of them are rendered on screen. The AssemblyScript/WASM culling reducer is a sidecar layer for the underlying memory structure that gives a very fast hot loop scan and trading 2ms / tick for 50k instances can effectively radius cull our rendered instances while still keeping them alive in memory.

Here’s the PG and here’s what it’s doing:

  1. Has a set of .glb’s that back the set of demo models - complete with textures / animations etc.
  2. Bakes them to VAT (a new format, potentially 4x smaller via dual quaternion VAT baking and float16) and creates a Shado wrapper
  3. Updates UI panel to allow for inspection and loading more models, including stock BJS PG assets or bring your own glb to see how it works - change armor, held items, name, etc.

How I got here, a walk down memory lane:

While working on the game port a few years back, I found some areas I wanted to really hone in on.

  1. Animation / instancing - VAT as a substitution model: Optimizing VAT Baking to near-instant and using Float16 for 50% memory savings - #9 by knervous
  2. Basis texture arrays - This is the current bake model native in the framework, creating a texture array atlas and mapping to textures for a baked entity - Support for RawTexture2DArray with compression from basis textures - #3 by Deltakosh
  3. Unified memory usage, field definitions. The start of Shado - conceptualized a “define once, use everywhere” model of C-like structs where we can use the same object from TS/JS in code (actor.armor = 2;) as in shader language code (auto generated now in Shado) and in WebAssembly by sharing memory. That is now how Shado works, one memory for each group of actor types used across all three domains. JavaScript/TypeScript object mapping in GPU Shader structs for complex binding
  4. Nameplates. I noticed a bottleneck in current MSDF is scaling unique msdf instances - in practice in my game, entity names are unique most of the time. I can’t have nameplates.forEach(render) running in the hot loop with 500+ NPCs. Nameplates are now baked in as a sidecar in Shado that require only 1 complete additional draw call and allow modifying names in runtime (try in the PG!): 10k+ Instances with MSDF Text Nameplates and inline WASM compilation
  5. Particle system integration and layered sockets/particles across a scene - This is next up once it surfaces in a use case in my game. Will be fun to scale out gpu particle systems to o(1), these are some rudimentary proofs of concept from a long time ago GPUParticleSystem syncing with VAT animations on mesh instances

The npm library should be well-documented and ready to plug in use cases. The repo is a subdirectory in my game repo which is in rough dev right now: GitHub - knervous/eqrequiem: EQ Requiem · GitHub - subdir shader-object

My WIP game I’m churning through is https://eqrequiem.com - a legacy project being overhauled to transition to a new game with this framework.

Glad to be back among the babylonians and hopeful I can appear and contribute accordingly in future weeks, months, years. I see much has changed and can’t wait to dive into Lite and get a lite package for this as well!

Cheers,
Knervous

7 Likes

This could be used for Babylon - Total War! Super impressive :slight_smile:

3 Likes

Really good performance!
I think I will use some of your ideas for my Lite Instancer.

There are already some experiments with massive VAT scenes like Unarmed VAT Arena Crowd but I am sure that I’ll be able to rise a perf greatly due to your findings.

Thank you!

2 Likes

Your recent post was inspiration to get this over the finish line! Great work yourself, spent a good bit going through your impl. Good news is I believe we are solving separate problems, would be happy to collab on any common efforts or chat about arch!

2 Likes

This is insane !!!

1 Like

Man! This is amazing. really. I will reserve some time today to go over the examples in more detail

CC @PirateJC for visibility

1 Like

Thanks @labris for some good feedback via PMs :slight_smile:

Been iterating on the next minor version 1.1.0 with lots of performance improvements. Notes are in the changelog, here is 140k+ entities in memory and 11k+ on screen rendered with different animations and texture sets

And support for lite now as well!

2 Likes

I’ve been trying to get something similar for BATs animations. I was able to do something similar with VATs, but BATS has been a different story. I was able to condense 300+ skeletal animations into a single BATs image. It’s a huge file, but you only need it once for every player. It’s the only method I think will work for getting Unreal 2k4 multi part player character assets working.

If you have these models hosted anywhere would love to take a look!

Probably final pass for awhile, went through last optimizations, now have over 1 million instances hot in memory and 20k rendering at 60~ FPS!

Initial PG still works and targets latest shado

3 Likes