I can’t find an official answer of document for this, although many asked this question before, boss’s answer always mentions camera.onViewMatrixChangedObservable or scene.onPointerObservable, or You can use scene.render() anywhere you want.
scene.onPointerObservable is over working with some issue. Over working means that mouse move event also fire this observable to render but camera’s view has not changed. Issue means that this method can not handle camera’s inertia, the view changed by inertia will be queued to the next pointer event.
Three.js make this much more simpler with OrbitControl.addEventListener( 'change', () => renderer.render(scene, camera) ) and it works very well.
User can not fire this observable in some specific circumstances
Which is why it would be useful to have a simple live example where it is not working. That way a possible bug can be more easily detected and corrected.
Good question.
This is something i am interested in as well but haven’t dug into yet.
The battery on my laptop has seen better days and rendering at 60FPS eats through it (not to mention fan noise…).
I would like for a scene to only be redrawn if there is actually something that /needs/ to be redrawn.
@hjlld You’ll get better help from the Babylon devs if you reproduce the issue in https://playground.babylonjs.com/ .
They are busy people and you are trying to get them to help so if we all stick to the same tool it is more efficient for them.
Unfortunately because scene rendering is done in automatically in the background of the playground @dunk’s problem cannot easily be shown in a PG hence the codepen example.
As far as I can make out, the camera view matrix is updated during scene.render() so that if the scene is not rendering there is no change in the view matrix to observe. Also any changes you make to your meshes have to be done explicitly somewhere. As a first step force the view matrix to change by getting it in the engine render loop and put the scene render in the observable.
var renderLoop = function () {
camera.getViewMatrix(true);
frames -=0.01
Cube.rotation.x = frames*2
Cube.rotation.y = frames*2
Cube.rotation.z = frames*2
torus.scaling.x = Math.abs(Math.sin(frames*2))+0.5
torus
cylinder.position.y = Math.sin(frames*3)
cylinder.rotation.x = frames*1
};
engine.runRenderLoop(renderLoop);
let camera = scene.activeCamera;
camera.onViewMatrixChangedObservable.add( () => scene.render() )
However this version still means that rotations are carried out every frame whether or not the camera view is changing. Further attempt next.
And in my real case (with many meshes), I found it can improve perfomance dramatically to replace scene.render() with scene.render(false) for avoiding duplicated camera updating (because camera has been updated by render loop). See: https://www.babylonjs-playground.com/#UNB24W#6