# Working with on-demand rendering loop

**URL:** <https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207>\
**Category:** Questions\
**Created:** [July 20, 2024, 10:17am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207 "2024-07-20T10:17:50Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![andrii](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/andrii/32/40655_2.png) [@andrii](https://forum.babylonjs.com/u/andrii)\
**Post date:** [July 20, 2024, 10:17am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/1 "2024-07-20T10:17:50Z")

</div>

For my application, I perform rendering only when there are changes in the scene.

Using this scheme:

```auto
engine.runRenderLoop(() => {
    if(isChangesInScene) {
        isChangesInScene = false;
        scene.render();
    }
});

```

However, when I change the material for a mesh (and set `isChangesInScene=true`), or add it to a HighlightLayer, the changes are not applied immediately, and the rendering that is called right after the changes does not reflect them. And since no more renderings are called (until the next changes occur in the scene), the scene remains rendered incorrectly.

To solve the problem when changing the material, I called `material.forceCompilation(mesh)`, but this didn’t help.

Is there perhaps some mechanism that allows tracking whether more frames need to be rendered to correctly display the scene with all the changes?

---

<div class="post-metadata">

**Author:** ![roland](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/roland/32/38940_2.png) [@roland](https://forum.babylonjs.com/u/roland)\
**Post date:** [July 20, 2024, 10:53am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/2 "2024-07-20T10:53:13Z")

</div>

You could render the scene multiple times. Set a `maxRenders` constant to limit the render count to this value.

---

<div class="post-metadata">

**Author:** ![andrii](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/andrii/32/40655_2.png) [@andrii](https://forum.babylonjs.com/u/andrii)\
**Post date:** [July 20, 2024, 10:57am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/3 "2024-07-20T10:57:00Z")

</div>

This doesn’t sound like the most elegant solution. Are there perhaps some events that allow us to understand whether the internal processing of the mesh has been completed?

---

<div class="post-metadata">

**Author:** ![roland](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/roland/32/38940_2.png) [@roland](https://forum.babylonjs.com/u/roland)\
**Post date:** [July 20, 2024, 11:10am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/4 "2024-07-20T11:10:59Z")

</div>

> [@andrii](#):
>
> This doesn’t sound like the most elegant solution.

But the simplest one and works for sure 😉

Not actual:

> However try this one: EDIT: I didn’t save the PG, wait a moment… This one doesn’t work.
> 
> EDIT2:  
> Working PG: [https://playground.babylonjs.com/#6N2UDN#1](https://playground.babylonjs.com/#6N2UDN#1)
> 
> EDIT3:  
> I have two PGs open with tha same code. In one of them it works in the second one it doesn’t… WTF! I’ve just created a screen recording but I’d rather investigate a bit more on the issue, don’t want to look like an idiot if I screwed up something obvious 😃
> 
> EDIT4: One of them didn’t stop the default render loop.

---

<div class="post-metadata">

**Author:** ![andrii](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/andrii/32/40655_2.png) [@andrii](https://forum.babylonjs.com/u/andrii)\
**Post date:** [July 20, 2024, 11:20am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/5 "2024-07-20T11:20:52Z")

</div>

If the change takes longer than the timeout, then there will be an incorrect result on the screen, and if we make a very large timeout, then there is too much unnecessary rendering, which negatively affects the battery life of mobile devices.  
When I worked directly with WebGL, after each change (loading textures, compiling shaders, and so on), I called a special callback that initiated a frame redraw. Is there something similar in Babylon?

---

<div class="post-metadata">

**Author:** ![roland](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/roland/32/38940_2.png) [@roland](https://forum.babylonjs.com/u/roland)\
**Post date:** [July 20, 2024, 2:36pm UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/6 "2024-07-20T14:36:33Z")

</div>

You could use a `numberOfRendersNeeded` variable instead of `isChangesInScene`. Or even better create a function called `function rerender(changeType)` and call this to queue some render cycles. Queue number of cycles according to `changeType`.

---

<div class="post-metadata">

**Author:** ![Joe\_Kerr](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/joe_kerr/32/39017_2.png) [@Joe\_Kerr](https://forum.babylonjs.com/u/Joe_Kerr)\
**Post date:** [July 22, 2024, 10:06am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/7 "2024-07-22T10:06:58Z")

</div>

> [@andrii](#):
>
> change the material for a mesh (and set `isChangesInScene=true`), or add it to a HighlightLayer

Can you poll [Babylon.js docs](https://doc.babylonjs.com/typedoc/classes/BABYLON.Material#isReady) / [Babylon.js docs](https://doc.babylonjs.com/typedoc/classes/BABYLON.HighlightLayer#isReady) isReady()?

* * *

More generally, is it really that we need actual renders? Or is it not rather some async stuff going on which takes a bit. So the problem would be to figure out how to measure precisely when the async stuff has finished.

---

<div class="post-metadata">

**Author:** ![roland](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/roland/32/38940_2.png) [@roland](https://forum.babylonjs.com/u/roland)\
**Post date:** [July 22, 2024, 10:39am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/8 "2024-07-22T10:39:36Z")

</div>

> [@andrii](#):
>
> If the change takes longer than the timeout, then there will be an incorrect result on the screen, and if we make a very large timeout, then there is too much unnecessary rendering, which negatively affects the battery life of mobile devices.

No timeout but render cycles. You might associate number of rendering cycles needed to the actions you perform. If you add a mesh to the `HL` it’s 2. If you move the mesh, it’s 1. So you render 2 times or once. If you perfrom these actions together call render (2 \> 1) 2 times.

---

<div class="post-metadata">

**Author:** ![Joe\_Kerr](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/joe_kerr/32/39017_2.png) [@Joe\_Kerr](https://forum.babylonjs.com/u/Joe_Kerr)\
**Post date:** [July 22, 2024, 10:51am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/9 "2024-07-22T10:51:09Z")

</div>

> [@roland](#):
>
> render cycle

Is that == scene.render()?

---

<div class="post-metadata">

**Author:** ![roland](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/roland/32/38940_2.png) [@roland](https://forum.babylonjs.com/u/roland)\
**Post date:** [July 22, 2024, 11:01am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/10 "2024-07-22T11:01:37Z")

</div>

Yes, it is.

---

<div class="post-metadata">

**Author:** ![Joe\_Kerr](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/joe_kerr/32/39017_2.png) [@Joe\_Kerr](https://forum.babylonjs.com/u/Joe_Kerr)\
**Post date:** [July 22, 2024, 11:24am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/11 "2024-07-22T11:24:35Z")

</div>

> [@andrii](#):
>
> However, when I change the material for a mesh (and set `isChangesInScene=true`), or add it to a HighlightLayer, the changes are not applied immediately, and the rendering that is called right after the changes does not reflect them.

Can you double check? [https://playground.babylonjs.com/#BZFHT1#2](https://playground.babylonjs.com/#BZFHT1#2)

---

<div class="post-metadata">

**Author:** ![dennemark](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/dennemark/32/10745_2.png) [@dennemark](https://forum.babylonjs.com/u/dennemark)\
**Post date:** [July 24, 2024, 12:15pm UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/12 "2024-07-24T12:15:31Z")

</div>

I have created a component for react-babylonjs that listens to movements and animations.  
in my own app (not react-babylonjs) i had a similar issue as yours. I made a global variable that I could change to force a rerender. something like:

```auto
let isForced = false

....
if(isChangesInScene || isForced){  
  isForced = false .... 
} 

....
function forceRender() { isForced = true }

```

some inspiration for render on demand

> <https://github.com/brianzinn/react-babylonjs/blob/master/packages/react-babylonjs/src/customComponents/RenderOnDemand>

related thread: [What is the correct way to render on demand - #22 by samevision](https://forum.babylonjs.com/t/what-is-the-correct-way-to-render-on-demand/17256/22)  
little video: [Render on Demand by dennemark · Pull Request #253 · brianzinn/react-babylonjs · GitHub](https://github.com/brianzinn/react-babylonjs/pull/253)

---

<div class="post-metadata">

**Author:** ![andrii](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/andrii/32/40655_2.png) [@andrii](https://forum.babylonjs.com/u/andrii)\
**Post date:** [July 25, 2024, 9:22am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/13 "2024-07-25T09:22:14Z")

</div>

Currently, I’m using isReady and running forceCompilation if !isReady. The callback of this function tells me when the compilation is finished, and I perform a redraw.

However, I wish Babylon.js had a mechanism that would allow intercepting all changes in the scene (shader compilation, texture loading, and other things). It’s a pity that it doesn’t exist. Without it, you constantly need to figure out which callbacks to attach to which events that might change the scene when rendering is complete.

---

<div class="post-metadata">

**Author:** ![andrii](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/andrii/32/40655_2.png) [@andrii](https://forum.babylonjs.com/u/andrii)\
**Post date:** [July 25, 2024, 9:23am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/14 "2024-07-25T09:23:27Z")

</div>

Nothing red appears.

---

<div class="post-metadata">

**Author:** ![andrii](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/andrii/32/40655_2.png) [@andrii](https://forum.babylonjs.com/u/andrii)\
**Post date:** [July 25, 2024, 9:26am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/15 "2024-07-25T09:26:31Z")

</div>

The problem is that something might load into the scene some time after the changes were made.

---

<div class="post-metadata">

**Author:** ![andrii](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/andrii/32/40655_2.png) [@andrii](https://forum.babylonjs.com/u/andrii)\
**Post date:** [July 25, 2024, 9:29am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/16 "2024-07-25T09:29:34Z")

</div>

For now, I’ve figured out the issue. It’s a pity that Babylon.js doesn’t have exactly what I was looking for, but your answers have given me an understanding of what to do next. Thank you all very much!

---

<div class="post-metadata">

**Author:** ![Joe\_Kerr](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/joe_kerr/32/39017_2.png) [@Joe\_Kerr](https://forum.babylonjs.com/u/Joe_Kerr)\
**Post date:** [July 25, 2024, 9:59am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/17 "2024-07-25T09:59:11Z")

</div>

> [@andrii](#):
>
> Nothing red appears.

 ![Screenshot 2024-07-25 115722](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/b/f/bf86a2fce3302e20e562c78ff188fd8e4f42d15d.png)

---

<div class="post-metadata">

**Author:** ![andrii](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/andrii/32/40655_2.png) [@andrii](https://forum.babylonjs.com/u/andrii)\
**Post date:** [July 25, 2024, 11:49am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/18 "2024-07-25T11:49:05Z")

</div>

I see. Even after 3 s nothing changes.

---

<div class="post-metadata">

**Author:** ![Joe\_Kerr](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/joe_kerr/32/39017_2.png) [@Joe\_Kerr](https://forum.babylonjs.com/u/Joe_Kerr)\
**Post date:** [July 25, 2024, 11:56am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/19 "2024-07-25T11:56:10Z")

</div>

Oh interesting! Checked in Chrome, not working. In Firefox, working.

---

<div class="post-metadata">

**Author:** ![roland](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/roland/32/38940_2.png) [@roland](https://forum.babylonjs.com/u/roland)\
**Post date:** [July 25, 2024, 11:59am UTC](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207/20 "2024-07-25T11:59:38Z")

</div>

> [@andrii](#):
>
> It’s a pity that Babylon.js doesn’t have exactly what I was looking for

I believe this functionality will be very welcomed by the community. Nowadays a lot of products are designed for mobile platform at the first place, desktop comes as second. Saving the battery by rendering only the necessary amount of frames could be a very useful stuff.

@Deltakosh what do you think about it? Can we somehow notify the client code that everything has been rendered? If so and we get enough votes and you give me some pointers where to start I’m willing to do the PR.

[Next page](https://forum.babylonjs.com/t/working-with-on-demand-rendering-loop/52207.md?page=2)
