# Strange Animation Behavior On First Play

**URL:** <https://forum.babylonjs.com/t/strange-animation-behavior-on-first-play/47848>\
**Category:** Bugs\
**Created:** [February 5, 2024, 9:24pm UTC](https://forum.babylonjs.com/t/strange-animation-behavior-on-first-play/47848 "2024-02-05T21:24:28Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![notmike101](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/notmike101/32/22905_2.png) [@notmike101](https://forum.babylonjs.com/u/notmike101)\
**Post date:** [February 5, 2024, 9:24pm UTC](https://forum.babylonjs.com/t/strange-animation-behavior-on-first-play/47848/1 "2024-02-05T21:24:28Z")

</div>

In our project, we hide meshes that have a bounding sphere radius under a specific size. We check this using the `onAfterWorldMatrixUpdate` observable.

I’ve found that when this is in place, when playing an animation that includes meshes that are initially hidden because of this check, during the first time playing the animation, there seems to be a brief stutter or skip on the animation. Even in cases where the animation is reset and the meshes are hidden again, this does not reoccur, meaning it ONLY happens during the first time playing an animation.

Is this expected behavior, is something wrong with how Babylon is functioning, is there a better way to get this same functionality that I’m not seeing?

Playground: [https://playground.babylonjs.com/#MH5MCV#13](https://playground.babylonjs.com/#MH5MCV#13)

Edit: For a bit of context, we’re doing this as a method of reducing unnecessary draws.

---

<div class="post-metadata">

**Author:** ![docEdub](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/docedub/32/14525_2.png) [@docEdub](https://forum.babylonjs.com/u/docEdub)\
**Post date:** [February 6, 2024, 3:24am UTC](https://forum.babylonjs.com/t/strange-animation-behavior-on-first-play/47848/2 "2024-02-06T03:24:14Z")

</div>

I think what’s happening is when the animation first starts, the hidden mesh becomes visible, which causes its material to trigger a shader compile.

I’m not sure what’s the best way to avoid it. I tried using `mesh.visibility` in [https://playground.babylonjs.com/#MH5MCV#24](https://playground.babylonjs.com/#MH5MCV#24) and it seemed to help on Edge and Chrome, but it made almost no difference on Firefox.

@Evgeni_Popov might know a better solution.

---

<div class="post-metadata">

**Author:** ![notmike101](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/notmike101/32/22905_2.png) [@notmike101](https://forum.babylonjs.com/u/notmike101)\
**Post date:** [February 6, 2024, 5:34pm UTC](https://forum.babylonjs.com/t/strange-animation-behavior-on-first-play/47848/3 "2024-02-06T17:34:50Z")

</div>

Is there a functional difference between `mesh.visibility` and `mesh.isVisible`?

From my memory of why we’re doing this, we’re trying to reduce our draw calls and saw that `mesh.isVisible` was a way to accomplish that.

---

<div class="post-metadata">

**Author:** ![notmike101](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/notmike101/32/22905_2.png) [@notmike101](https://forum.babylonjs.com/u/notmike101)\
**Post date:** [February 7, 2024, 4:43am UTC](https://forum.babylonjs.com/t/strange-animation-behavior-on-first-play/47848/4 "2024-02-07T04:43:44Z")

</div>

Was working with one of my friends, we came up with another solution that addresses what @docEdub brought up regarding shader compiling.

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

Ultimately, creating a new mesh with the material of a mesh that would be hidden and adding that to the scene so we could force the shader to be compiled no matter what.

```auto
for (const mesh of assetContainer.meshes) {
  const materialBox = BABYLON.CreateBox('materialBox', {
      size: 0.2,
  }, scene);

  materialBox.material = mesh.material;
  materialBox.visibility = false;
}

```

If anyone can think of a better solution than this, please let me know.

---

<div class="post-metadata">

**Author:** ![labris](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/labris/32/12576_2.png) [@labris](https://forum.babylonjs.com/u/labris)\
**Post date:** [February 7, 2024, 5:00am UTC](https://forum.babylonjs.com/t/strange-animation-behavior-on-first-play/47848/5 "2024-02-07T05:00:49Z")

</div>

I believe you may try to dispose materialBox after compiling.

---

<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:** [February 8, 2024, 10:21am UTC](https://forum.babylonjs.com/t/strange-animation-behavior-on-first-play/47848/6 "2024-02-08T10:21:00Z")

</div>

There should not be any difference between `isVisible = false` and `visibility = 0`, because if any condition is true, the mesh won’t be considered as visible:

> <https://github.com/BabylonJS/Babylon.js/blob/master/packages/dev/core/src/scene.ts#L4057-L4062>

Instead of creating a mesh, at start time, you can call `Material.forceCompilation` or `forceCompilationAsync` and wait for the callback / promise to kick in before going on.

Note that `visibility` is not a boolean, it is a value between 0 and 1 and acts as an alpha value.

---

<div class="post-metadata">

**Author:** ![notmike101](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/notmike101/32/22905_2.png) [@notmike101](https://forum.babylonjs.com/u/notmike101)\
**Post date:** [February 12, 2024, 6:52pm UTC](https://forum.babylonjs.com/t/strange-animation-behavior-on-first-play/47848/7 "2024-02-12T18:52:06Z")

</div>

@Evgeni_Popov Using `forceCompilation` and `forceCompilationAsync` seems like a much better approach, thank you. Unfortunately, I am running into the following error while using it:

> pbrBaseMaterial.ts:1885 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘hasThinInstances’)

Not sure if that’s expected?

---

<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:** [February 13, 2024, 10:15am UTC](https://forum.babylonjs.com/t/strange-animation-behavior-on-first-play/47848/8 "2024-02-13T10:15:33Z")

</div>

This error means you are passing `undefined` for the first parameter of `forceCompilation`: you should pass the mesh for which the material must be compiled.

---

<div class="post-metadata">

**Author:** ![notmike101](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/notmike101/32/22905_2.png) [@notmike101](https://forum.babylonjs.com/u/notmike101)\
**Post date:** [February 14, 2024, 2:10am UTC](https://forum.babylonjs.com/t/strange-animation-behavior-on-first-play/47848/9 "2024-02-14T02:10:41Z")

</div>

@Evgeni_Popov Tried doing a playground with `forceCompilation`, seems like the issue still happens.

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

Am I just not doing something right or is an alternative method needed for this?

---

<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:** [February 14, 2024, 11:55am UTC](https://forum.babylonjs.com/t/strange-animation-behavior-on-first-play/47848/10 "2024-02-14T11:55:40Z")

</div>

You should wait for the compilation to finish: you should pass a parameter for `onCompiled` and continue only when it has been called.

It’s probably easier to call `forceCompilationAsync` for all your materials and wait for all the promises to resolve by using `await Promise.all(array_of_promises)`.

---

<div class="post-metadata">

**Author:** ![notmike101](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/notmike101/32/22905_2.png) [@notmike101](https://forum.babylonjs.com/u/notmike101)\
**Post date:** [February 19, 2024, 8:36pm UTC](https://forum.babylonjs.com/t/strange-animation-behavior-on-first-play/47848/11 "2024-02-19T20:36:52Z")

</div>

Hey @Evgeni_Popov , thanks for the suggestion.  
Unfortunately, I’m still getting the same issue while using that approach.

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

This is with calling forceCompilationAsync on each material and using `await Promise.allSettled` to wait for all of them to finish.

---

<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:** [February 20, 2024, 3:54pm UTC](https://forum.babylonjs.com/t/strange-animation-behavior-on-first-play/47848/12 "2024-02-20T15:54:53Z")

</div>

That’s not an easy one, because it uses the KHR material transmission extension, which triggers the creation of a render target texture under the hood…

You can do something like this to wait for this RTT to be ready for rendering:

```javascript
const opaqueTextureReady = () => {
    new Promise((resolve) => {
        const check = () => {
            if (scene._transmissionHelper.getOpaqueTarget().isReadyForRendering()) {
                resolve();
            } else {
                setTimeout(() => {
                    check();
                }, 100);
            }
        };

        check();
    });
};

await opaqueTextureReady();

```

However, this transmission helper uses a `setTimeout` call (with a 0 timeout) to setup the meshes for this RTT, and you will have to make sure these calls have been handled before calling `opaqueTextureReady`. The easiest way is to call `setTimeout` with a small timeout before doing `await opaqueTextureReady()`:

```javascript
    await new Promise((resolve) => {
        setTimeout(() => {
            resolve();
        }, 10);
    });

```

Putting it all together:

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

---

<div class="post-metadata">

**Author:** ![notmike101](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/notmike101/32/22905_2.png) [@notmike101](https://forum.babylonjs.com/u/notmike101)\
**Post date:** [February 29, 2024, 8:26pm UTC](https://forum.babylonjs.com/t/strange-animation-behavior-on-first-play/47848/13 "2024-02-29T20:26:01Z")

</div>

Hey @Evgeni_Popov , thank you for that info.

We did successfully get that implemented and resolved the issue, but created another issue at the same time.

There are some instances where `scene._transmissionHelper` is undefined indefinitely, causing some of our models to never actually render. Any ideas on what could be happening there or how to work past it?

---

<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:** [March 1, 2024, 12:22pm UTC](https://forum.babylonjs.com/t/strange-animation-behavior-on-first-play/47848/14 "2024-03-01T12:22:34Z")

</div>

`scene._transmissionHelper` will only exist if you load a glb file with a material that uses the KHR\_material\_transmission extension.
