NOTE: This question is more about requestAnimationFrame than Three.js, but it was an example from the Three.js docs that caused me to scratch my head. Maybe this will be useful to others starting out in this area, too.


At the top of the docs page for the Timer class, it has the following example usage:

const timer = new Timer();

function animate( timestamp ) {

	requestAnimationFrame( animate );

	// timestamp is optional
	timer.update( timestamp );

	const delta = timer.getDelta();

	// do something with delta

	renderer.render( scene, camera );

}

In every other example (outside of Three.js) for requestAnimationFrame() I can recall, the animation callback calls requestAnimationFrame() at the end of the function, rather than the beginning.

How come it’s called immediately here?

1 Like

either way you place requestAnimationFrame( animate ); first or last is the same.

If at the end, then if will be error then script stop. If at the begining then if error then ok. Requestanimation will be executed after 0.16 fps or more if code still calculates.

1 Like

But doesn’t it make more sense to run the first callback, and then queue up the second callback at the end of whatever work gets done (in animate)?

I don’t understand quite what you mean. There is no error handling in the example.

Can you rephrase?

Excuse my english. If the check is at the end, then if an error occurs the script will stop. If the check is at the beginning, the error is detected earlier and the rest of the script can continue. requestAnimationFrame is called roughly once per screen refresh (typically every ~16 ms, i.e. ~60 FPS). If your frame callback takes longer to compute, the effective frame rate will drop (for example, a 160 ms frame corresponds to about 6 FPS).

1 Like

In a normal situation it should not matter where the request is triggered - in the beginning, middle or end of your function. This method just registers a request, nothing more, no processing is done, just an id is returned (most people do not need it). At some later point, after the execution of your function is completed, the browser will process the request.

However, in Three.js it is better to use .setAnimationLoop, which uses rAF internally. This method works fine for mono and stereo modes. rAF is OK for mono modes, but for stereo you need to spend some efforts managing rAF.

2 Likes

I always use trycatch in the loop so if an error occurs the process continues;

function animate() {
    stats.update();
    if (mixer) mixer.update(clock.getDelta());
    requestAnimationFrame(animate);
    try {
        renderer.renderAsync(scene, camera);
    } catch (error) {}
}
1 Like

Of course!

It doesn’t matter because it simply schedules the callback for whenever the browser decides.

Thanks :folded_hands:t4:

2 Likes

I will just throw this out there..
I try to call raf first in the loop.. my reasoning is that.. it’s like getting in line for the next RAF, along with all other systems that might be requesting as well. We want to get in line first, even if our frame render takes some extra time. If we call it after all our frame processing, we might get scheduled a frame later. I don’t know if this is really how things work under the hood.. but that’s my reasoning.

1 Like