Animation performance drop by translation/rotation

As I briefly mentioned in another thread my bottleneck in a scene is the animation:

This scene has two instanced animated objects (plus the original mesh) loaded from a gltf file with BABYLON.SceneLoader.LoadAssetContainer and container.instantiateModelsToScene. At first glance I thought this was caused by the bone animation, but it turns out this is not the case.

The problem is reproduced here: https://www.babylonjs-playground.com/#4ZVNJJ#3 Moving the meshes (by setting their position and direction) makes the fps fall to around 30 to 40fps. If they are static the performance is back to 60fps. There’s a flag animate to control this behavior (note that the objects are not visible with animate = true, they’re off screen).

What is going on? What can be done to improve this?

1 Like

The console says d is not defined. Here it works:

https://www.babylonjs-playground.com/#4ZVNJJ#4

Edit: never mind, the lag is there still

1 Like

When you animate the root meshes, you are updating their world matrix and then all their children and the children of their children need to rebuild their world matrix

So this will trigger the rebuild of the entire hierarchy of world matrix per frame

So this is expected as it put a lot of pressure on the CPU,
A good idea would be (if possible) to simplify the hierarchy?

1 Like

And you also have 600 bones animated per frame :slight_smile:

1 Like

I’m seeing the interpolate to be #1 (makes sense with 600 bones):

1 Like

More details:

1 Like

And as you can see in the previous capture, computeWorldMatrix is #3

1 Like

Don’t the children inherit the world matrix from the parent with something like a glPushMatrix/PopMatrix?

Is there a way to collapse the hierarchy in BJS? Merge the geometry?

It’s not the most optimal object in the world, I know :slight_smile: It’s an object I downloaded from a repository and I had no control over its creation. But the bone animation is not a problem, BJS handles it pretty well.

I’d expect this to be a big problem anyway, but if the objects are animated but not translated there’s no performance hit and the demo runs at 60fps. I originally imagined it was the bone animation that was making things slow, and was surprised that the first PG I built didn’t reproduce the issue.

Well so in your case the world matrix computation seems to be the problem

yes this is exactly what happens. But this is not magic. the system need to multiply all the matrices into one per mesh to send it to the shaders

1 Like

Okay, but what could be done other than editing the model on a 3D modeler? Is it possible to collapse the nodes? Merge the geometry? Freeze the submeshes so the matrices are cached other than one parent transformnode multiplication?

1 Like

Well you should NOT animate the root nodes but instead the root mesh for your manta ray (which is named node250 :))

Something like that: (the idea is to get the root bone)
https://www.babylonjs-playground.com/#4ZVNJJ#5

3 Likes

Also why are you disabling the first one? Why not just use it (you are wasting memory here)

LIKE these PERF OPS THREADS!!!

FOR REVIEW (for me to learn) and for others:

  • easy to get SNAPSHOT, challenging to know what to look for to optimize.

STUFF TO LOOK FOR to OPTIMIZE:

  • COUNT YOUR CHILDREN: simplify hierarchy to reduce “WM” calls.

  • COUNT YOUR BONES: nuff said

  • COUNT your BONE CONNECTIONS (<4?)

  • I do not know what that means.

  • Look for: _interpolate, _animate, and computeWorldMatrix - runtime snaps.

  • BASELINE: 0.8ms is slow? Oh. Good to remember that.

  • Look. 0.1ms seems like a good TARGET.

AND

  • count your vertices for MESH. But also…

  • count your vertices for UV Texture maps (@gryff).

Is that all?

Oh wait, BAKING, FREEZING…

YOUR Water FX is AWESOME (to me): https://www.babylonjs-playground.com/#S1W87B#3

Luv it.

What else?

:eagle:

1 Like

Sorry, can you clarify a couple of points please?

First you wrote:

Then

So is the root node or the root mesh that I should animate?

I understand that instantiateModelsToScene returns a list of root nodes which may or may not be meshes. Is that correct? Is there an automatic way to find the root [mesh|node] (whichever is correct) automatically? I assumed whatever was returned in the .rootNodes was actually the root and not something in the hierarchy, so I’m kind of lost here.

I thought it had an issue with RTT if I used the original object, but apparently not, I misunderstood it. But it turns out that container.meshes have completely different objects than mantas. So what exactly instantiateModelsToScene returns? Can use the original mesh and the instances together on an array and treat them just alike, or are there any restrictions?

Thanks Deltakosh :smiley:

The one with the smallest hierarchy (hence the root mesh FOR the bones). You need to get the skeleton attached to your mesh, get the first bone (root bone) and then get the bone.transformNode to get the root node to animate

No restriction

It returns all the meshes created by the function. Mantas are more transformNode and not really meshes in your case

2 Likes