# Prevent excessive \`onViewMatrixChangedObservable\`

**URL:** <https://forum.babylonjs.com/t/prevent-excessive-onviewmatrixchangedobservable/53790>\
**Category:** Questions\
**Tags:** engine, performance\
**Created:** [September 27, 2024, 6:53am UTC](https://forum.babylonjs.com/t/prevent-excessive-onviewmatrixchangedobservable/53790 "2024-09-27T06:53:27Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![zb\_sj](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/zb_sj/32/28923_2.png) [@zb\_sj](https://forum.babylonjs.com/u/zb_sj)\
**Post date:** [September 27, 2024, 6:53am UTC](https://forum.babylonjs.com/t/prevent-excessive-onviewmatrixchangedobservable/53790/1 "2024-09-27T06:53:27Z")

</div>

My project occasionally runs some heavy `pickWithRay` in `onViewMatrixChangedObservable`.

I had to profile to improve my project’s performance.

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/0/5/05bbf31c4a141e78adcd7877bd39e65cc8f8e709.png)

I’ve found some logic `scene.render()` with `camera.getViewMatrix` somehow calls `Observable.notifyObservers` multiple times in a single frame.  
I’ve already changed every `camera.getViewMatrix()` in my domain to `camera._worldMatrix` to prevent infinite `onViewMatrixChangedObservable.notiftyObservers`.

1. Why does the engine call `onViewMatrixChangedObservable.notiftyObservers` inside `getViewMatrix`?
2. Why does the engine update the camera before `this.onBeforeRenderObservable.notifyObservers(this);` and run `_processSubCameras` after.
3. What is the best refactoring for me to fix this problem?

Any suggestions or inputs are appreciated 🙇‍♂️

---

<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:** [September 27, 2024, 8:59am UTC](https://forum.babylonjs.com/t/prevent-excessive-onviewmatrixchangedobservable/53790/2 "2024-09-27T08:59:14Z")

</div>

`onViewMatrixChangedObservable` should be notified only when the view matrix changes, or when `true` is passed to `getViewMatrix` (`force` parameter). The first three lines of this function are:

```typescript
        if (!force && this._isSynchronizedViewMatrix()) {
            return this._computedViewMatrix;
        }
        <onViewMatrixChangedObservable is notified in later code>

```

If you can setup a repro, we can have a look at why you get too many notifications.

Regarding 2/, `scene.render` first update all cameras of the scene, then loop over the cameras and call `_processSubCameras`

---

<div class="post-metadata">

**Author:** ![zb\_sj](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/zb_sj/32/28923_2.png) [@zb\_sj](https://forum.babylonjs.com/u/zb_sj)\
**Post date:** [September 27, 2024, 9:08am UTC](https://forum.babylonjs.com/t/prevent-excessive-onviewmatrixchangedobservable/53790/3 "2024-09-27T09:08:50Z")

</div>

I think changing camera matrix in `beforeRender` causes another onViewMatrixChangedObservable notification.

The naming or method `getWorldMatrix` is misleading and has sideffects.

I’ve refactored my code to

1. flag whenever `onViewMatrixChangedObservable` is notified
2. move original observers to `beforeRender` and run only if the flag is true
3. and release the flag after each frame

How about we do the similar in the engine?  
Do notification in scene render or some places that insures frame cycle.  
It might be a breaking change, but I plead it clears things out.

---

<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:** [September 27, 2024, 9:20am UTC](https://forum.babylonjs.com/t/prevent-excessive-onviewmatrixchangedobservable/53790/4 "2024-09-27T09:20:13Z")

</div>

As explained, with the existing code, the view matrix should only be recalculated when necessary. It would be great if you could setup a repro of your bug so that we can fix it on our side!

---

<div class="post-metadata">

**Author:** ![zb\_sj](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/zb_sj/32/28923_2.png) [@zb\_sj](https://forum.babylonjs.com/u/zb_sj)\
**Post date:** [September 27, 2024, 10:28am UTC](https://forum.babylonjs.com/t/prevent-excessive-onviewmatrixchangedobservable/53790/5 "2024-09-27T10:28:55Z")

</div>

My current project is complex to replicate the whole reproduction in playground.

let me give you worst case scenario:

[onViewMatrixChangedObservable causing Maximum call stack size exceeded | Babylon.js Playground (babylonjs.com)](https://playground.babylonjs.com/#26JHWG)

some mild one:

How am I supposed to know Camera.getDirection might cause viewMatrixChanged?

[excessive onViewMatrixChangedObservable | Babylon.js Playground (babylonjs.com)](https://playground.babylonjs.com/#26JHWG)

current workaround:

[workaround excessive onViewMatrixChangedObservable | Babylon.js Playground (babylonjs.com)](https://playground.babylonjs.com/#26JHWG#2)

I know some logic like changing matrix inside notification is better to be avoided.  
It should be at least documented.

---

<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:** [September 27, 2024, 11:04am UTC](https://forum.babylonjs.com/t/prevent-excessive-onviewmatrixchangedobservable/53790/6 "2024-09-27T11:04:47Z")

</div>

More minimal [https://playground.babylonjs.com/#26JHWG#3](https://playground.babylonjs.com/#26JHWG#3)

I would say on the one hand this is expected behaviour. You are calling the function that triggers the callback from within the callback. But on the other hand, would be nice if Babylon caught the recursion.

---

<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:** [September 30, 2024, 9:25am UTC](https://forum.babylonjs.com/t/prevent-excessive-onviewmatrixchangedobservable/53790/7 "2024-09-30T09:25:09Z")

</div>

You can check reetrance more easily:

> **[Babylon.js Playground](https://playground.babylonjs.com/#26JHWG%234)**
>
> Babylon.js playground is a live editor for Babylon.js WebGL and WebGPU 3D scenes

I also update the doc for the observable:

> <https://github.com/BabylonJS/Babylon.js/pull/15647>
>
> See https://forum.babylonjs.com/t/prevent-excessive-onviewmatrixchangedobservabl…e/53790/6
