Determining NullEngine fps

Hi everyone!

Just a quick question about the best way to determine NullEngine fps. I just would like to assure that the engine runs in a stable fps all the time… Not sure if the best way is to console log the engine.getFps().toFixed() what I tried to do just a few minutes ago :sweat_smile: … Any tips for this?

Also a continuation why I’m asking; getting a fluctuating NullEngine fps of ~40, even though it is supposed to run at 60 fps…

Answering a bit to the question; node --inspect works wonders on creating a node process where you can hook your regular Chrome debug tools:


There is still the problem of “how to see the NullEngine fps reliably part” :smiley: Also curious on how the camera processing works in the NullEngine…

getFps is the way to do it and in nullengine everything but gpu operations are executed.

It might be your RAF equivalent not being fast enough ? cause it looks like your full frame runs in about 3ms

Hmmm, it is a bit hard pickle. I do have a lot of instanced meshes in the scene, but somehow I thought that not actually rendering would not eat my performance so much… :smiley: Here is even bigger picture:

Can you provide any insight in what could be done, other than reduce mesh amount… :sweat_smile:

at least in node you could freezeActiveMeshes() on the scene to bypass your biggest cost. Babylon is actually CPU bound so I am not surprised your frames are pretty similar.

Nice, that did the trick with the meshes problem! Fps is around ~53 now!

Now the bottleneck seems to be the Recast blackbox. I guess the animation section might be in relation with this as well, as I should have disabled all the animations in the server side :thinking: I’m kind of curious how much power the crowd calculation is taking since there is just one agent standing, not doing anything :smiley:

Let s check this one with @Cedric

It seems that I have not paused the animation correctly…


^ That is the idle animation of my main character… Is there a global way to destroy/stop all animations in the scene? :smiley: Currently trying to do this in every turn and it is not doing the trick:

let animations: AnimationGroup[] = task.loadedAnimationGroups
if (animations && animations.length > 0) {
  animations.forEach((animationGroup: AnimationGroup) => {
    animationGroup.stop()
  })
}

Seems as if the initial animations cannot be stopped… Weird.

But yeah there is also the Recast thing I would like to get some insight on :slight_smile:

scene.stopAllAnimations() should do

Are you using the latest version of recast available?
Can you try to set the recast update time step to 0 (with setTimeStep) and profile again?

To improve quality, it’s possible to split deltaTime into smaller substeps. This might be the reason for the time spent here.

I’ve updated the Recast two months ago in my project, has it received soma major updates? I’m already using the setTimeStep with 0 :slight_smile:

const r = await Recast()
navigation = new RecastJSPlugin(r)
navigation.setTimeStep(0)

Could this have something to do with the quite large navmesh area I have?

I’ve updated the npm package some weeks ago. If you have no agent, do you have the same trace?

Removing the agent did give a small 0.3ms boost to the Recast calculations… My crowd is initialized like this:

crowd = navigation.createCrowd(100, 0.1, scene)

Here is the current graph, without agents:

Do you think the newer Recast version could help with performance?

Also I noticed that I should probably strip the models off their materials… Don’t really need the PBR calculations on the server side, right? :sweat_smile: Is there some global way to do this, or do I have to tinker with the models by hand?

yes, test with latest version, to be sure.

wait, recast update takes roughly twice the time of NullEngine.GetRenderHeight? how much time is it?

Now that I tried again it is around 0.4ms for the update without any agents:


Total renderloop time is 0.9ms.

It seems that the performance is a lot better with the new version of recast-detour. This is with the agents involved! :slight_smile:

0.3ms renderloop time woop woop!

All in all this was a pretty cool investigation. If someone stumbles here trying to debug the NullEngine, some tips:

  • Use the engine.getFps().toFixed() to get the fps
  • Use the node --inspect handle to start Node.js in debug mode, then you can use the Chrome devtools to debug your Babylon stuff.
  • Do not use actual models/meshes in server side / NullEngine unless it is needed for some reason, for example I have map tiles that are shaped in certain way and cannot be substituted with placeholder meshes.
  • Stop the animations of the loaded models and make sure they are stopped. No need to animate models server side, but they might auto-play when imported.
  • Remove expensive materials (pbr in my case) from loaded models.
  • Try to think if you can freezeActiveMeshes on the server side. For example, my game map is composed of a lot of instanced meshes, so I could easily freeze them after creation.

Also use the latest package versions at all times :wink:
Thank you @sebavan and @Cedric for your time and help as well! :pray: :heart: