I’m building a Three.js viewer for a static building model using postprocessing
and n8ao
. Since the model doesn’t animate, I want to render only once when the user stops moving the camera — not every frame like a traditional requestAnimationFrame()
loop.
What I want to achieve:
- While the user is moving the camera: no rendering.
- When the camera stops: render once with
composer.render()
.
What I’ve tried:
let sleep = 0;
world.camera.controls.addEventListener("update", () => sleep = 0);
world.camera.controls.addEventListener("sleep", () => sleep = 1);
function animate() {
if (sleep === 1) {
composer.render();
}
requestAnimationFrame(animate);
}
animate();
This renders properly, but keeps rendering every frame when the camera is resting (sleep === 1
). That’s a waste of performance.
So I tried removing the animation loop and just rendering once:
world.camera.controls.addEventListener("sleep", () => {
composer.render();
});
This runs and logs correctly, but nothing updates visually on the canvas.
If I use renderer.render(scene, camera)
instead of composer.render()
, it does update correctly — but then I lose postprocessing.
The question:
Why does composer.render()
not visibly update the canvas when called just once (outside of a loop)?
How can I call composer.render()
once (e.g. on camera “sleep”) and have the frame actually stay rendered?