-
-
Notifications
You must be signed in to change notification settings - Fork 36k
Description
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