Replies: 1 comment
-
With regards to instancing I think @superdump is taking a look at general mesh batching/instancing this cycle. Not sure how one can tell if a mesh has been instanced or not - maybe a label component |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
As previously mentioned, I'm working on porting my game/engine from three.js to Bevy. I'd like to get some advice on how to handle instancing.
Let me explain how the existing engine works: The game supports very large worlds (many kilometers) which are broken up into chunks called "precincts", each precinct is 64 x 64 meters. These are dynamically cached in memory as the player moves around the world. Within a precinct there are lots of instanced objects:
Each 1-meter section of wall in the screenshot is an instance of a GLTF model. Because the GLTF models often share the same textures, they are typically packed into a single .glb file - so for example, the "dungeon-walls.glb" file has about three dozen separate models which are referenced by name.
When a gltf file is loaded, the first thing that happens is that all of the materials are replaced. The GLTF
material.userData
field specifies the kinds of special effects (cartoon outlines, flame animation, glow effect, sprites, unlit, etc.) so each material is replaced with a custom material that implements that special effect, but otherwise keeps the same properties (color, texture, etc.)The precinct map consists of a list of instance placements - that is, the model id, position, rotation and scale of each instance. Models ids are integers which reference a table of asset keys, also stored in the precinct map.
Each precinct has an InstancedModels manager which maintains and update the list of instances. Instances are organized by model type, so for example all of the "straight-wall-section" instances are stored in a single map entry which has an array of transforms, one transform per instance.
Walls which have animated components (doors and gates) are not instanced, but instead are treated as normal scene graph elements. The instance manager handles this automatically by checking to see if the wall section has any properties which would make instancing impossible.
The actual rendering of instances is relatively straightforward using three.js's InstancedMesh class. The built-in three.js shaders are written such that they can be used for either instanced or non-instanced rendering, but only for models in which the instance data is a transform. For something like particle systems, where each instance has multiple parameters, a custom shader must be used.
So here's a list of problems I need to solve:
world
structure, but the data structures that Bevy provides are complicated and not easy to deal with. I'd need to build an index in order to avoid a linear search, and that index will need to stay in memory for as long as the GLTF asset is loaded.As you can see that's a rather daunting set of tasks, and I've left a lot out to keep this post from being any longer. But I'm interested in hearing any advice or guidance from folks who have more experience in Bevy/ECS/Rust than I do.
And if you're wondering, "why are you even doing this at all?", well there's a lot of reasons, but if you look at the second screenshot you'll notice there are no point-light shadows, because point-light shadow buffers are very expensive in three.js and you can't have very many of them. There are tons of other similar limitations in three.js and after three years I'm just tired of fighting with them.
Beta Was this translation helpful? Give feedback.
All reactions