Issues related to baked animation instancing

Greetings.

I started putting all my project’s major features together to stress test my scene. I notice several issues and appreciate any helps.

I use a modified PG from @phaselock to illustrate the problems. https://www.babylonjs-playground.com/#X5XCVT#339

  1. Shadows of animation instances. The shadow of binding pose is casted. No animation. This is probably not supported in babylon. But could somebody provides guides on how I can approach this problem? E.g. Which source code files to look at to get familiar with how babylon implements shadow casting and how it might be extended to support shadows of animation instances.

  2. FPS drops as more animation instances are added. I notice the Meshes Selection time goes up as more instances are created. I was able to get good performance by adding scene.freezeActiveMeshes. However, my terrain, river, and trees are not rendered in different ways:

    Terrain: if I move the terrain position.y down, I can see the terrain. But when it is at position.y=0 or higher, the terrain seems disappeared.
    River: randomly generated based on path finding (flowing down from one edge to the other). It only shows the reflection/refraction texture.
    Trees: Thin instance. Can’t find them any more.

    Other instanced models like houses and baked animation instances are rendered correctly.

    If I use scene.freezeActiveMeshes(true, () => { }, () => { }, false), all the meshes are rendered correctly. But if I move the camera position, meshes initially outside camera view are not rendered.

    I am not able to reproduce all these in a PG. But the main overhead seems from increased number of animated instances. Is there a way to reduce Meshes Selection time for the animated instances without affecting other meshes.

  3. FPS drops as shadows are added. The draw calls are almost doubled after adding shadows. And I think similarly for WaterMaterial that supports reflection as well. Without shadows, 100 animated instances (and even higher number) are working fine. But after adding shadows, FPS dropped below 60 for 100 instances.

About 1. @Evgeni_Popov might be our best asset as he knows all about the engine :slight_smile:

About 3. Nothing we can do here, you need to render the meshes in the shadow map so it is totally expected.

About 2. sounds normal as well, instances help your gpu but not cpu time. The more animations, the more work to do on the CPU.

For 1/, use the ShadowDepthWrapper class to generate the correct data in the shadow map for your material:

https://www.babylonjs-playground.com/#X5XCVT#341

See line 215. Note that I moved the time increment in scene.onAfterRenderObservable so that it is done only a single time per frame. Doing it in material.onBindObservable observable may increment the value multiple times per frame.

It’s not the optimal way (perf wise) to do it, but doing better will require writing shader code: Shadows | Babylon.js Documentation (see “Optimizing further and standalone shadow depth wrapper”)

For the scene.freezeActiveMeshes() to work, you normally should set alwaysSelectAsActiveMesh = true on all your meshes so that all the meshes end up in the active list, even the ones outside the frustum, at the time freezeActiveMeshes is called.

You are using CSM with 4 cascades + 4096 texture size (so 4 cascades of 4096x4096) + PCF in high quality mode: that’s expected it takes some GPU resources! :slight_smile:

3 Likes

Awesome! Thanks @Evgeni_Popov !

I will try to integrate your fix into my scene and test it out.

For 2, I did add alwaysSelectAsActiveMesh = true for the terrain mesh. I will try to add it for all the meshes.

For 3, my question is more about the rendering performance drops as the number of instances increases. See PG below.

https://www.babylonjs-playground.com/#X5XCVT#343

In this PG, I now use the following settings instead. But FPS drops to 30 with 100 instances.

     const shadowGenerator = new BABYLON.ShadowGenerator(256, lightDirectional);
     shadowGenerator.filteringQuality = BABYLON.ShadowGenerator.QUALITY_LOW;
     shadowGenerator.usePercentageCloserFiltering = true;

I guess I will need to check your guide about the performance and do more learning on this topic. I was hoping to post my first video to the demo and projects topic. It is probably going to take longer. :sob:

It’s not the optimal way (perf wise) to do it, but doing better will require writing shader code: Shadows | Babylon.js Documentation (see “Optimizing further and standalone shadow depth wrapper”)