Instancing mesh when loading from AssetContainer for mesh with skeleton + animations

I’m using an AssetContainer to create animated character meshes and add them to the scene (GLB model, inclusive of skeleton and several animations).

I realised that creating additional character meshes to my scene was having a very negative impact on the FPS, so started looking into instancing them.

I seem to be unable to create them as instances - setting the value of options: { doNotInstantiate } doesn’t seem to be having an effect, as the returned root mesh is always isAnInstance == false.

The documentation for instantiateModelsToScene reads:

Instantiate or clone all meshes and add the new ones to the scene. Skeletons and animation groups will all be cloned

Is the correct interpretation of this “skeleton and animation groups will always be cloned, rather than instanced”? If so, does that mean it’s cloning the character mesh rather than instancing, simply because it has a skeleton and animations associated with it?

I also attempted to call mesh.createInstance on an existing character mesh and get greeted by hundreds of occurrences of this warning in the browser console: Instances should only be created for meshes with geometry. - any idea why this is happening?


On a slightly unrelated note, are animations expensive? If I wanted to have many copies of a particular mesh playing the same animation in my scene, is there a way to utilise instancing to speed that up? What if I wanted them to play the same animation, but at different offsets? I’m guessing in this case I would simply have to deal with the extra draw calls that are required to render each mesh at their differing stages of the animation (and maybe at best, instance those meshes that are exactly in sync with each other)?

Is it possible your root mesh doesn’t contain any geometry data, but rather a parent holder of multiple child meshes? In this case you need to create instances for each child mesh.

On a slightly unrelated note, are animations expensive? If I wanted to have many copies of a particular mesh playing the same animation in my scene, is there a way to utilise instancing to speed that up?

Yes, animations are computed in JS by default. Playing same animation at different offsets would required multiple computation of the same animation. So its expensive.

You can look at babylon’s baked texture animation which reads animation transformation matrix from texture on GPU. This will help to run different animations on large number of instances.

2 Likes

Correct. An instance is a light copy of a mesh. There are a (large) number of parameters and transformations that cannot be achieved with an instance. In which case, BJS is smart enough to actually ‘automagically :magic_wand: transform them’ into a clone. Typically, objects with animated parts or object to be merged cannot be worked as instances.

So an instance is basically related to the way it is rendered at the graphic level. It would basically render with “instances” meaning one draw call for all the objects instead of one per object.

The performance gain comes with a draw back which is every thing needs to use the same shader/material.

Most of the transform related operations will therefore work but none of “material” based ones.

2 Likes

You explain things just so much better than I will ever do :teacher:

Hey there @sairens just checking in if you have any more questions about this subject :slight_smile: