Skip to content

renderAsync() should internally call waitForGPU() #32005

@PoseidonEnergy

Description

@PoseidonEnergy

Description

I think it's confusing to users to find out that just calling await renderer.renderAsync() alone does not actually wait until the image in the <canvas> element has been updated. If a user wants to render a frame and truly wait until the <canvas> has been updated, they have to do the following:

await renderer.renderAsync(scene, camera);
await renderer.waitForGPU();

Couldn't renderAsync() already do this internally? When would a user want await a call to render a frame, but not wait until the frame is actually visible?

In three.js examples across the internet I rarely will see an example that calls waitForGPU(), but a proper FPS counter or frame rate limiter must have that line, or else it will not be accurate. This is because callbacks passed to requestAnimationFrame(callback) will be fired faster than the <canvas> can update, which messes up a "true" FPS measurement.

This is very noticeable in a moderately complicated scene that has a bit of lag. First, record your scene with a screen recorder (e.g. Bandicam, etc.) with a super high capture rate (e.g. 120Hz). Make sure you are printing out each frame number to the canvas as well as the "measured" FPS. If you record for a few seconds, then play back the recording frame-by-frame, you will notice that the actual number of unique frames rendered in the <canvas> in one second will be much lower than the reported FPS.

Reproduction steps

Make a laggy three.js scene and make sure you are printing the frame number and FPS to the screen on each frame. Do not call renderer.waitForGPU() on each frame. Record the <canvas> with a screen recorder (e.g. Bandicam, etc.) with a high capture rate (e.g. 120Hz) for a few seconds, play the recording back frame-by-frame, and count the number of actual different frames in one second. Compare that to your reported FPS. The actual frame count in one second will be much lower than reported FPS. As soon as you add the line renderer.waitForGPU() after each render, your reported FPS will match the actual frame count.

Version

r180

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions