CPU Optimizations for animated meshes

Hey everyone,

I’ve recently discovered a CPU spike that occurs when other player models are in the client scene, and I’m wondering how to optimize it CPU-wise. I don’t fully know what all is done on CPU or GPU, so I’ll outline what I have and think may be going on.

Here’s a PG that shows the player model:

If you open the performance monitor in chrome, after 3 seconds the new players will spawn in and you will see a little bit of a spike in CPU usage. Nothing crazy, but if you add it in to a scene with a bunch of other things happening, it creates a bit of lag.

Here are my questions:

  • What processes are heavy on the CPU for this example? I believe the animations are done on the GPU, the frustum check shouldn’t really effect it because I have it set to alwaysSelectAsActiveMesh, so that leaves me to believe it’s probably the WorldMatrix calculation?
  • If I’m correct in assuming it is the WorldMatrix calculation that is most CPU heavy, how can I optimize this?
  • Does it matter that the character is composed of like ~30 meshes that are all just parented to the main body mesh? Would it be more efficient CPU wise if I joined all of the meshes into 1 mesh?

Also, if you check out my playground and notice anything about that player model that could cause lag, or have any ideas on how to optimize the model, I would appreciate all of the help I can get!

The spike is probably about the buffer creations (You are cloning the character and even if this is fast it stills require some work for the driver)

I do not think this is related to animation. I’m more incline to think it is because of the refreshBoundingInfo which force the skinning to be computed CPU side

Oops, I should have been more specific. The lag spike isn’t just on creation, it’s constant. Also I meant to remove the refreshBoundingInfo part, that was some code from an old test. In the production version, that function only runs once every few seconds, so it shouldn’t effect the overall CPU performance too much, right?

Here’s a screenshot of the performance profile:

Hopefully that helps

Here’s with some of those expanded:

For some reason, the pointermove event is really when the lag shows. If I just sit still, the CPU might sit at around 60% for example, and as soon as I move the pointer around (in a pointerlocked camera), the lag will show tremendously. I can move the camera’s position with no lag at all, but when the pointer moves, all of a sudden packets are being blocked and the CPU usage spikes to like 95+%

easy test, add this code:

scene.pointerMovePredicate = function() {
return false

That didn’t seem to have an effect.

the mouse move is still making things worse?

I think your lag comes from the picking element
Do you manually call scene.pick somewhere?

1 Like

Yes, so originally I had a scene.pick() that was called every render loop, to display to the user any hovered object info. I had it this way for over a year, with no lag issues. At some point in the last couple of months a massive lag emerged, where basically everything was being blocked (packets included) when the pointer was moved. So I went in and optimized the picking function to only call every 12 renders, only test picking against objects within a close distance to camera, and only after a flag has been raised to pick (from pointer move or from player position move). This seemed to help the lag issue for the most part, but now we found it will be much more laggy when players are in the scene. You may be right, and I just need to go without picking entirely, but I believe it’s stemming from an issue somewhere else, because:

  1. If I disable picking entirely, the lag will still occur sometimes, just not as severely, or as often.
  2. When I was picking from the scene every render loop, the lag ONLY existed on mouse move.

I thought I hadn’t changed anything on the game since the lag had started, but I had updated the player model a few months prior, and we realized when you’re in an area without any other players, the scene usually doesn’t lag, but if a player is around, it usually will.

I timed the picking functions:
scene.pick() takes 31.110000010812655 ms
my optimizedPick() takes 0.6250000151339918 ms

I would strongly suggest that you merge those meshes into a single one as well.
~30 meshes is quite a lot for a simple character like that.


I will do that and see if it helps.
On the playground most of the meshes are disabled, the rest of the meshes are tools, weapons, pieces of armor, etc. If you want to have a look at what I mean, you can see the different mesh names by viewing the playerMeshes array in the dev console. To see one, just call player1.meshes[‘sword’].setEnabled(true); and replace sword with whatever mesh name you want to see.

I originally did it this way because it seemed like the most forward approach, and allows me to modify the materials much easier.

I will combine it into 1 mesh and just modify the materials another way I guess.

1 Like

Ideally if you can replicate in a obvious way the slow down in the PG it could help a lot

Here’s the best I could come up with:

If you pointer lock and then rotate your camera, you will see a CPU spike. For me it’s from about 55% to about 70% CPU usage.

Here’s a demonstration:

In the production environment there’s a bit more going on, so in production it’ll sit at around 55% but then jump up to over 90%.

Since the pointerMovePredicate isn’t having a strong effect, maybe it has to do with the Universal camera? Maybe there’s an event that’s called on the camera rotate that picks or something CPU heavy? I have experienced rotate lag in Firefox when pointer moving/camera rotating. I’ve also seen many other posts with similar issues, but none of the ones I’ve seen have had a solution

So a few questions to narrow it down:

  • Does it happen without pointerlock?
  • Does it happen if debug tools (f12) is not open?

I can’t reproduce what you show in your video, I stay around 60% CPU all the time.

What if you freeze everything (meshes, materials)? Does the CPU still spike?

Would you be able to reproduce the quick moves of the mouse but programmatically, to see if the problem comes from the mouse itself or from the quick moves?

Also, what if you disable picking in the PG?

  • Does it happen without pointerlock?
    Yes, just tested it and it seems the same without pointerlock.

  • Does it happen if debug tools (f12) is not open?
    Yes, it actually feels more laggy with debug tools closed.

I froze meshes, materials, and mesh world matrices:
Babylon.js Playground (this example also doesn’t pointerlock)

The scene sits at around ~35% cpu and when I rotate the camera it jumps up to ~55%.

Programmatically rotating the camera seems to not cause lag:

If I add the code Deltakosh mentioned:
scene.pointerMovePredicate = function() {
return false;

The lag still exists when I move the mouse with my pointer. I’m not sure how to disable picking in the scene entirely.

Based on these tests it seems to me like there is something (probably picking) being called somewhere in the pointermove call stack, that is outside of the pointermove predicate.

Have you tried to disable picking with this code:

    scene.onPrePointerObservable.add((pointerInfo) => {
        pointerInfo.skipOnPointerObservable = true;

Yes, but that disables pointer moving entirely, so it’s not a viable solution