Animate TresJS Objects with the useRenderLoop Composable

Alvaro Saburido
InstructorAlvaro Saburido
Share this video with your friends

Social Share Links

Send Tweet
Published 8 months ago
Updated 2 months ago

In this TresJS lesson, we explore how to animate 3D objects in a scene using the render loop.

We'll cover:

  • Using the useRenderLoop composable and onLoop callback to run code every frame
  • Creating refs with useRef to reference and modify 3D object properties like position and rotation
  • Handling varying device frame rates with delta or elapsed time for consistent animation speed

By the end of the video, you'll be ready to create smooth animations in your own TresJS scenes.

[00:01] To animate our cube inside of the Trust CS scene, first, we need to understand how the render loop works on over the hood. So to do that, I present you mister Egghead. So what is happening in the render is that it's taking a snapshot [00:20] of your scene like this. So the first frame is gonna be mister egghead like this. And then a moment later, we're gonna render a frame 2. In this frame 2, we are modifying a [00:40] characteristic of our egg head, character. So in this case, let's make it go up a little bit the hand. So it's moving a little bit. And then we are taking another snapshot, and we call it frame 3 where the hand is a [01:00] little bit up. So how, the render loop works under the hood is that it's taking a snapshot of your scene with the movement of the character of your 3 d object in something that we call frames per second. [01:21] So frame rate is typically a state as the frequency rate in which consecutive images or frames are captured and displayed. In this case, rendered by the 3 g s render. This image right here exemplified the difference between a lower frame rate versus a higher one. In the higher one, you can [01:40] observe that we have more data to construct an animation. So this animation will be smoother just by the amount of data that we have into. You probably heard before, the term frames per second because it's commonly used in cinema, for example, when the common rate is 24. [02:00] Also, in gaming, you can hear players using 120 frames per second, and sometimes also free 60 frames per second in the browser. So it also depends on the frame rate or refresh rate of your monitor. For example, in my laptop right [02:20] now, I'm rendering at 120 frames per second. To be able to access the callback that is trigger every frame per second on our, we're gonna use a composable that is available on the core package called use render loop. The way we're [02:40] gonna use it is we're gonna deconstruct the object that is returned, and we are gonna access a method called on loop from the use render loop. This method is gonna set one parameter, which is the function of the callback. So inside here is where our [02:59] animation is gonna live. But first, we need to decide which property of our object we want to animate and also get the reference from that object. For that, we are going to create a ref using view ref. So it's gonna be box ref ref, and we need to import [03:19] this from view. K. So this variable here will hold the reference from the 3 g s instance that is created and mounted on the custom render. So we need to pass a property called ref here and just pass the box ref. To see that it works, we're gonna [03:39] use watch effect. So watch effect is just a method that allows you to trigger an action when the reactive object has changed. So in this case, we're gonna do a, simple console log, and we're gonna put box ref dot value. So hit save, and [03:59] then we're gonna toggle the developer tools and see what we have inside of the console. So here we can see the prompt of the mesh object, okay, that is initialized here and passed as a template graph. And we have access to certain properties that we could animate, like the position and the rotation right here. So let's just do [04:19] that. We're gonna go here to the code. And in the on loop, we're going to ask if the box ref exist. Okay? So if box ref value doesn't exist, just return. But if it does, let's take the box ref value, [04:39] and we're going to modify or animate the rotation in the y axis. So we're gonna use an arbitrary number for now, and we should use a small number because think that this has been triggered 120 frames per second, meaning that it's gonna be quite fast. So if we put the, bigger number, it's not [04:59] gonna be visible. So if we hit save, now we can see that our cube is rotating, counter clockwise, okay, in the y axis. So, we have succeed. It's working. There is a problem by using a hard coded value here. And is that depending on the frame rate of the device of the your user, [05:19] the animation speed is gonna be different from a device that is more performant to one that is less. So to avoid that, we are going to remove this value here, and we are going to use a property that is being returned it, on the on loop callback called delta. So [05:39] delta is basically the time that has passed between one frame and the last one. So this allows you to standardize or, like, maintain a stable no matter what the device frame rate is. So it's always going to rotate at this speed. Another property that we can use [05:59] is elapsed. So elapsed works similar to how the delta works. But instead of using the time between 2 frames, it's using the time since the animation start. So let's rotate the zeta axis here. And instead of [06:19] using the plus equal sign, let's use equal. So now the cube is gonna rotate in 2 different axis and is going to use the delta for, the y axis and the elapsed time for the.