Why is "Mesh Selection" time so high and how to reduce it?

Hi Guys,

Apologies for the lack of Playground with this one but you can see the issue in question in action at this page: Storybook

You can open the inspector by clicking the small FPS counter in the top left.

The issue is we are seeing very high relative “Mesh Selection” times in our total frame time:

This issue persists even if you set chrome CPU to be 6x slower:

As I understand it “Mesh Selection” time is basically the time it takes to calculate and cull what is in the camera frustrum before being sent to the GPU and according to these docs we should be able to skip this culling step by setting the mesh.alwaysSelectAsActiveMesh to be true.

So we did this along with setting the scene to intermediate mode as per this suggestion but still nothing.

I even added this little freeze button:

image

Which does the following when clicked:

 scene.freeActiveMeshes();
 scene.freezeMaterials();
 scene.freeProcessedMaterials();
 scene.freeRenderingGroups();
 console.log("FROZEN!");

But it does nothing.

Is there something else going on here? How can we reduce this rather large part of the frame time?

Can someone who knows more look through our scene in the inspector (link provided at the top) and see if there is something in there we arent doing correctly?

Cheers

Mesh | Babylon.js Documentation (babylonjs.com)
1 | Babylon.js Playground (babylonjs.com)
If you can load the model and try to release the comments for each row separately to see the Selection time, the latter two options take almost twice as long.
However, this may cause inaccurate picking, please see the documentation link.

I think you meant freezeActiveMeshes? You should see a difference if you use freezeActiveMeshes (note, however, that the time spent in meshes selection is quite low to start with).

Oh wow how stupid! You are quite right it should be “freeze” not “free”.

Now an interesting thing happens when I press the “freeze” button on the hud:

See the video above. The Mesh Selection time drops to 0 as expected but the animations stop which I wouldnt have expected. Also the animation time is still really high.

Whats going on?

P.S. You mention:

(note, however, that the time spent in meshes selection is quite low to start with).

This is true if you are talking about absolute time but I am on a very powerful PC, many of or players are on much worse machines and we are building for mobile too, so I am more interested in the relative percentage of frame time and in particular CPU bound operations.

The model animation stopped because you froze the material, which invalidated the shape key change.
Baked Texture Animations | Babylon.js Documentation (babylonjs.com)
Using GPU animations should optimize animation performance.

You can try to call skeleton.prepare() yourself (in scene.onBeforeRenderObservable, for eg) once you have frozen the active meshes. When active meshes are frozen, this method is not called anymore, and it is what makes the animations run.

1 Like

@mikeysee, let me tell you that your game is amazing and so pretty !!!

2 Likes

wow! that did the trick! A MASSIVE increase in performance, our players are going to love us.

The only issue now is (as you can see above) everything else is now hidden and only sometimes shows up (which is really strange), for example see the cannonball right at the end only shows up just before it hits the water, then other times it shows up before, its almost as if its only being turned on and off on a 500ms timer or something.

Is there a way to force update just selected mesh’s as “alwaysSelectAsActiveMesh” doesnt seem to do the trick?

EDIT: Manually calling skeleton.prepare() does seems to increase the time spent in “Animations” but im hoping that this will go away when we do the below VAT optimization.

Yes! We have this on our list to look at next and as we arent using blended animations it hopefully will be a good candidate for us.

alwaysSelectAsActiveMesh make sure the mesh will always pass the culling stage and will eventually be drawn. However, you should set this property to true for all your meshes before calling freezeActiveMeshes, as only the meshes that were active will be drawn afterwards. Also, if you create new meshes after freezeActiveMeshes has been called, they won’t be visible! You will have to unfreeze, set alwaysSelectAsActiveMesh=true for all new meshes and call freezeActiveMeshes again:

The box (created after freezeActiveMeshes have been called) won’t appear:

The box will appear:

If that still does not work, I think we will need a repro to be able to help more.

Oh indeed this does work! I have to unfreeze the scene then freeze it again after every mesh creation.

Is there any automated way to do this built into the engine?

Sorry for the offtopic but what kind of game is that? :smiley: Some kind of battleship game?
Is it online so I can play it? :wink:

Yes indeed :slight_smile: its https://battletabs.io/

We are currently getting close to a mobile release too, using Bablyon of course

2 Likes

No, there’s no automated way, as it could be slow to unfreeze/freeze each time a new mesh is created, in case you create several meshes at once.

Okay, thats a shame but understood.

Ughh… this really is very messy.

I have to freeze and unfreeze too when a mesh becomes visible or invisible and then there are still lots of issues

There has got to be a better way of getting rid of this mesh selection time surely?

If you have a lot of meshes, implementing scene.getActiveMeshCandidates could help (see Curious about this.totalVertices.addCount() in the evaluate active mesh loop - #27 by Evgeni_Popov).

@JCPalmer has also tried something of his own, perhaps that might be of use to you?

There’s always the possibility of overloading scene._evaluateActiveMeshes with your own implementation, removing anything you don’t need.

It would also be useful to take a performance snapshot and see where most of the time is spent in the _evaluateActiveMeshes function (this function is doing mesh culling, animates skeletons, dispatch sub-meshes, etc).

Okay thanks, ill look into these suggestions

ye it looks like @JCPalmer was right on the same thinking train as me. I dont know if he is still lurking around on these forums but ill see if he custom Scene implementation works (if I can work out how to slot that into the codebase).

I have also seen the @brunobg name come up in a few places on this forum too when dealing with performance issues around CPU bottlenecks (Mesh Selection and Animations baking etc). I wonder if he has any ideas