# Baked animation performance

**URL:** <https://forum.babylonjs.com/t/baked-animation-performance/32023>\
**Category:** Questions\
**Created:** [July 8, 2022, 6:57pm UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023 "2022-07-08T18:57:36Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![slin](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/slin/32/36084_2.png) [@slin](https://forum.babylonjs.com/u/slin)\
**Post date:** [July 8, 2022, 6:57pm UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/1 "2022-07-08T18:57:36Z")

</div>

Hi babylon team,

Happy Friday!

I could only run ~2000 instances before FPS drops below 60 in the PG below. This PG is taken from [babylon baked texture animation](https://doc.babylonjs.com/divingDeeper/animation/baked_texture_animations):

> **[Babylon.js Playground](https://playground.babylonjs.com/#CP2RN9%2320)**
>
> Babylon.js playground is a live editor for Babylon.js WebGL 3D scenes

I found this [tweet](https://twitter.com/lusionltd/status/1440316604395360263?lang=en) about baked animation in WebGL and then linked to their playable demo: [https://exp-abduction.lusion.co/](https://exp-abduction.lusion.co/). I checked the index.js file of their code, the following are the number of instances used in the scene.

> Lowest: 8192,  
> Low: 16384,  
> Medium: 32768,  
> High: 65536,  
> Highest: 131072,  
> Extreme: 262144

Can we also support this level of instances?

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [July 11, 2022, 3:01pm UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/2 "2022-07-11T15:01:24Z")

</div>

Probably 🙂 we will need first to investigate with the profiler to see where the perf hit is

Wanna check the f12 profiler and see where we are spending most of the time? We have a lot of options to optimize rendering

---

<div class="post-metadata">

**Author:** ![slin](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/slin/32/36084_2.png) [@slin](https://forum.babylonjs.com/u/slin)\
**Post date:** [July 11, 2022, 5:04pm UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/3 "2022-07-11T17:04:27Z")

</div>

Hi @Deltakosh

Is there a way to profile the GPU performance? I tried to profile the PG. As I increase the number of thin instances, I don’t see any JS function consume significantly more time. In the inspector, I see GPU frame time and inter frame time both going up with more instances.

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [July 11, 2022, 5:17pm UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/4 "2022-07-11T17:17:18Z")

</div>

So this is probably due to the shader complexity  
also to compare with Abduction we have to be sure they are using the same number of everything (joints, bones, animations, etc…)

---

<div class="post-metadata">

**Author:** ![slin](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/slin/32/36084_2.png) [@slin](https://forum.babylonjs.com/u/slin)\
**Post date:** [July 11, 2022, 5:50pm UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/5 "2022-07-11T17:50:52Z")

</div>

I can prepare a PG by taking their lowpoly model and baking some simple mixamo animations. If this helps, I would make one when I have time.

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [July 11, 2022, 5:52pm UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/6 "2022-07-11T17:52:32Z")

</div>

yes and then we can have a look as the perf of the shader to see if we can do better (for instance I’m pretty sure they are not using a PBR shader )

---

<div class="post-metadata">

**Author:** ![carolhmj](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/carolhmj/32/25918_2.png) [@carolhmj](https://forum.babylonjs.com/u/carolhmj)\
**Post date:** [August 10, 2022, 2:10pm UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/7 "2022-08-10T14:10:57Z")

</div>

Hello @slin just checking in if you’d like any more help with this?

---

<div class="post-metadata">

**Author:** ![slin](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/slin/32/36084_2.png) [@slin](https://forum.babylonjs.com/u/slin)\
**Post date:** [August 17, 2022, 2:22am UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/8 "2022-08-17T02:22:59Z")

</div>

Hi @carolhmj

Thanks for asking. It is on my side to do more investigation. I don’t have question right now. I am a bit overwhelmed by two kids during the summer and my wife is happier seeing me practicing LC&SD instead of showing her 3D warrior models running all over the place. 🥲

---

<div class="post-metadata">

**Author:** ![carolhmj](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/carolhmj/32/25918_2.png) [@carolhmj](https://forum.babylonjs.com/u/carolhmj)\
**Post date:** [August 17, 2022, 10:13am UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/9 "2022-08-17T10:13:18Z")

</div>

Good luck! xD We’ll be here if you need anything 😛

---

<div class="post-metadata">

**Author:** ![slin](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/slin/32/36084_2.png) [@slin](https://forum.babylonjs.com/u/slin)\
**Post date:** [November 5, 2022, 2:15am UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/10 "2022-11-05T02:15:12Z")

</div>

Hi @Deltakosh, Hi @Evgeni_Popov,

Can you have a look at this PG: [https://playground.babylonjs.com/#9QCNHK#110](https://playground.babylonjs.com/#9QCNHK#110)

I am able to run with FPS 60 with this PG on my computer. But if I comment out the line below, FPS drops significantly down to 50. Also it remains FPS 60 if I crease instance number to 20k with the following line. If the following line is commented out, FPS for 20k instances drops to ~28.

`meshes[1].computeBonesUsingShaders = false;`

So I guess this performance issue has something to do with bone computation using shaders? Do you have any suggestions what to investigate next?

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [November 5, 2022, 10:07am UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/11 "2022-11-05T10:07:55Z")

</div>

It’s kind of expected.

1. When `computeBonesUsingShaders = true`, the code is doing 4 texture reads PER vertex PER instance per frame.

2. When `computeBonesUsingShaders = false`, there’s no texture reads anymore but the vertices are transformed according to their bones on the CPU and the final vertex positions are uploaded to the GPU once per frame.

As 2 is independent from the number of instances and has a fixed cost (depending on the number of vertices), there’s a point where 2 will be faster than 1, and it will be more and more in favor of 2 with increasing number of instances.

As your mesh has a very low number of vertices, 2 is very fast and outperforms quickly 1 (also depending on the GPU - I’m still at 60fps with 20k instances and bones computed in shader).

You can try another option:

- `mesh.computeBonesUsingShaders = true`
- `mesh.skeleton.useTextureToStoreBoneMatrices = false`

In this configuration, bones will be applied on the GPU but using a static bone array, there’s no texture read involved. It will likely be faster than 1 but probably not than 2 given that your mesh has a very low vertex count.

Note that this latest configuration will set a limit to the total number of bones a skeleton can have (which depends on the number of uniforms a vertex shader can take).

---

<div class="post-metadata">

**Author:** ![slin](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/slin/32/36084_2.png) [@slin](https://forum.babylonjs.com/u/slin)\
**Post date:** [November 5, 2022, 3:24pm UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/12 "2022-11-05T15:24:14Z")

</div>

Hi @Evgeni_Popov

Thanks a lot for your inputs.

> In this configuration, bones will be applied on the GPU but using a static bone array, there’s no texture read involved.

I thought about this as well. For the `mesh.skeleton.useTextureToStoreBoneMatrices = false` configuration, do you mean it will use the `mBones` array in [the else branch of BONETEXTURE](https://github.com/BabylonJS/Babylon.js/blob/master/packages/dev/core/src/Shaders/ShadersInclude/bonesVertex.fx)? I also thought this else branch could be faster than texture2D() calls.

But I tried to apply this parameter in my PG, I don’t see any difference in FPS:

```auto
    meshes[1].computeBonesUsingShaders = true;
    meshes[1].skeleton.useTextureToStoreBoneMatrices = false;

```

Is there a way to verify if setting `useTextureToStoreBoneMatrices = false;` does use the bone array instead of texture read?

> (also depending on the GPU - I’m still at 60fps with 20k instances and bones computed in shader)

That’s the other thing I want to find out. 🤣 I use Chrome on Mac with the following:

![Screen Shot 2022-11-05 at 8.15.38 AM](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/0/6/0695e3c1f8e6675d5317596d13a450104761072b.png)

Is windows generally better than Mac? What is your graphic card like for running 20K instances at 60 FPS?

BTW, I just tested on Safari with `meshes[1].computeBonesUsingShaders = true;` (bones computed in Shader). It was able to stay on 60 FPS for 10K instances. Dropped down to 36 FPS for 20K instances. My original post was tested on Chrome: 50 FPS for 10K instances. 27 FPS for 20K instances.

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [November 5, 2022, 5:39pm UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/13 "2022-11-05T17:39:00Z")

</div>

> [@slin](#):
>
> do you mean it will use the `mBones` array in [the else branch of BONETEXTURE](https://github.com/BabylonJS/Babylon.js/blob/master/packages/dev/core/src/Shaders/ShadersInclude/bonesVertex.fx)?

Yes indeed.

> [@slin](#):
>
> Is there a way to verify if setting `useTextureToStoreBoneMatrices = false;` does use the bone array instead of texture read?

Use Spector.js =\> [https://spector.babylonjs.com/](https://spector.babylonjs.com/)

That’s really the best tool you can use to see what’s going on under the hood in your frame.

> [@slin](#):
>
> Is windows generally better than Mac? What is your graphic card like for running 20K instances at 60 FPS?

Windows is not better nor worse than Mac, it’s different 🙂

My GPU is a NVidia 3080Ti, so not a bad GPU.

I can see in your screenshot that you have two GPUs: are you sure to use the Radeon in your testing and not the Intel integrated Graphics, as the Radeon is probably faster than the Intel?

---

<div class="post-metadata">

**Author:** ![slin](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/slin/32/36084_2.png) [@slin](https://forum.babylonjs.com/u/slin)\
**Post date:** [November 6, 2022, 4:52pm UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/14 "2022-11-06T16:52:58Z")

</div>

@Evgeni_Popov

Thanks a lot for helping. I will check with spector.js. Hopefully accessing the bone matrix array will give better performance.

> are you sure to use the Radeon in your testing and not the Intel integrated Graphics, as the Radeon is probably faster than the Intel?

Yes. Babylon.js inspector shows Chrome is using Radeon.

> My GPU is a NVidia 3080Ti, so not a bad GPU.

Your GPU seems to win with a big margin. 😀

 ![Screen Shot 2022-11-06 at 8.47.21 AM](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/8/e/8e5462e0ca500581f8c4faeeaf9aa5dbb64c48a2.png)

---

<div class="post-metadata">

**Author:** ![carolhmj](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/carolhmj/32/25918_2.png) [@carolhmj](https://forum.babylonjs.com/u/carolhmj)\
**Post date:** [November 7, 2022, 10:38am UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/15 "2022-11-07T10:38:28Z")

</div>

This is such good information I think we should add in the docs expanding this section here: [Bones and Skeletons | Babylon.js Documentation](https://doc.babylonjs.com/features/featuresDeepDive/mesh/bonesSkeletons#performance-considerations) 😃

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [November 7, 2022, 1:48pm UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/16 "2022-11-07T13:48:28Z")

</div>

Done:

> <https://github.com/BabylonJS/Documentation/pull/701>
>
> See https://forum.babylonjs.com/t/baked-animation-performance/32023/11

---

<div class="post-metadata">

**Author:** ![slin](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/slin/32/36084_2.png) [@slin](https://forum.babylonjs.com/u/slin)\
**Post date:** [November 7, 2022, 5:04pm UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/17 "2022-11-07T17:04:34Z")

</div>

@Evgeni_Popov

In your documentation PR:

> 1. When `computeBonesUsingShaders = true`, the vertex shader code is doing 4 texture reads **PER** vertex **PER** instance **PER** frame.

Is it right that it might be multiple “4 texture reads”, depending on the number of bones that have influences on the vertex? So the total is 4 \* NumberOfBoneInfluences texture reads.

---

<div class="post-metadata">

**Author:** ![slin](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/slin/32/36084_2.png) [@slin](https://forum.babylonjs.com/u/slin)\
**Post date:** [November 7, 2022, 6:15pm UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/18 "2022-11-07T18:15:29Z")

</div>

Hi @Evgeni_Popov

I tested the following 2 PGs with spector.js Chrome extension. The performance gain is not very promising. 💔

[mBones array](https://playground.babylonjs.com/#9QCNHK#116) FPS: 51.5 - 52

[texture read](https://playground.babylonjs.com/#9QCNHK#117) FPS: 50.5 - 51

I recorded the following screenshot for the two test PGs above. It seems to show two different bone matrix reading technics are applied corrected for the two test PGs.

read from mBones array:

 ![Screen Shot 2022-11-07 at 9.27.09 AM](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/f/e/fe078f3327d38a414a3ed7917e34249ee521c851.jpeg)

texture read, which is implemented in readMatrixFromRawSampler

 ![Screen Shot 2022-11-07 at 9.28.05 AM](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/5/1/51d202cdf9f3fce4c73122c163e378b0dc1d6d53.jpeg)

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [November 7, 2022, 6:28pm UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/19 "2022-11-07T18:28:57Z")

</div>

> [@slin](#):
>
> Is it right that it might be multiple “4 texture reads”, depending on the number of bones that have influences on the vertex? So the total is 4 \* NumberOfBoneInfluences texture reads.

No, it is 4 texture reads if you have 4 bone influences or less and 8 reads if you have more than 4 (and less than 8, as we don’t support more than 8 bone influences per vertex).

> [@slin](#):
>
> I tested the following 2 PGs with spector.js Chrome extension. The performance gain is not very promising. 💔
> 
> [mBones array](https://playground.babylonjs.com/#9QCNHK#116) FPS: 51.5 - 52
> 
> [texture read](https://playground.babylonjs.com/#9QCNHK#117) FPS: 50.5 - 51
> 
> I recorded the following screenshot for the two test PGs above. It seems to show two different bone matrix reading technics are applied corrected for the two test PGs.

Yes, the first screenshot corresponds to bones being passed through a uniform buffer and not doing texture reads, and the second screenshot to bones being passed through a texture.

That means you are really bound by the vertex shader (the number of instructions in the vertex shader) and not the texture throughput. So, the solution for you is to use CPU bones calculation if you want the best performances.

---

<div class="post-metadata">

**Author:** ![slin](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/slin/32/36084_2.png) [@slin](https://forum.babylonjs.com/u/slin)\
**Post date:** [November 7, 2022, 9:38pm UTC](https://forum.babylonjs.com/t/baked-animation-performance/32023/20 "2022-11-07T21:38:22Z")

</div>

> [@Evgeni\_Popov](#):
>
> No, it is 4 texture reads if you have 4 bone influences or less and 8 reads if you have more than 4 (and less than 8, as we don’t support more than 8 bone influences per vertex).

Hmmm, I think each bone influence requires 4 texture2D calls. Because a texture2D call returns a vec4, a bone matrix will required 4 texture2D calls to build up a 4 \* 4 transformation matrix. You can see this [in the readMatrixFromRawSampler implementation](https://github.com/BabylonJS/Babylon.js/blob/master/packages/dev/core/src/Shaders/ShadersInclude/bonesDeclaration.fx).

For example, the last screenshot that calls readMatrixFromRawSampler has 4 influences. It calls readMatrixFromRawSampler 4 times. So in total texture2D has been called 4 \* 4 = 16 times.

[Next page](https://forum.babylonjs.com/t/baked-animation-performance/32023.md?page=2)
