Performance with animations

Hello there,

I am having a performance issue with animations in a multiplayer game. When a considerable amount of people join the game (10-20 players), the performance drops down to levels that are incomprehensible.

I have checked a couple of posts and something is mentioned related to it.
https://forum.playcanvas.com/t/does-animation-speed-affect-performance/28272/2

The animations are evaluated even for characters that are off-screen (we have a ticket to change that), but the bones are not updated and uploaded to GPU so you save some performance here. Also, because you provide AABB, we can skip aabb calculation based on the skeleton, which is not super cheap either

We already have custom AABB on the models and it seems it is not related to GPU performance. I was wondering if there is any other way to optimize animations.

I was thinking of some sort of culling. If there is any way to detect if an object is being rendered, to stop the animator or start it.

Here are some screenshots of the Performance Recordings I have done.

Without users

MicrosoftTeams-image (1)

With 20 users

What you see is the animation being evaluated on the bones, which takes place even for invisible characters. We have a ticket to do something about it, but there was no work done on this yet: Expose option to disable animation playback on invisible characters · Issue #3563 · playcanvas/engine · GitHub

I think perhaps the best way would be for you to do something like this:

  • update your camera (perhaps in update)
  • update your character positions (perhaps in update)

in postUpdate perhaps test if characters are visible, and disable them if not. That should work.
You can get a Frustum by cameraEntity.camera.frustum, and that has containsSphere code to test against a sphere based on the aabb.

2 Likes

And I think in addition to what Martin shared, reducing the amount of bones / complexity of the skeleton may help.

Also we have a system in our Solar Tools SDK where we patch the PlayCanvas engine to reduce the frequency of the animation update based on the camera distance. This works as a sort of animation LOD:

https://twitter.com/PlayingInCanvas/status/1564178828217524224?s=20

1 Like

I was trying to use the variable meshInstance.visibleThisFrame is there any diference between it and cameraEntity.camera.frustum?
I found this post:

Uranus Tools as you mention on the Twitter post is deprecated

It has been renamed to Solar Tools and it’s available here (indie and enterprise licenses), we actively work on that: Tech - Solar Games

Uranus Scripting for PlayCanvas is an older open source extension that we released a couple of years ago, that is deprecated.

1 Like

Any other free choices?

visibleThisFrame is a value from the last frame, which could work in many cases

1 Like

I made it work with visibleThisFrame. Performance is working as expected.

1 Like