Skip to content
Home » Create smooth Threejs camera movement using Blender

Create smooth Threejs camera movement using Blender

I still remember my first “3D” website. It was in 2013, at the time of Flash (we’re not getting any younger…), and I had to make a circular image carousel. I had two options: move the camera or move the images. I decided on the second one, but with hindsight, it wasn’t the best choice.

For this project, the movement was quite easy. A bit of trigonometry and it was done. But nowadays, with the power of WebGL, it’s usually not “simple” carousels, but complex 3D scenes.

This was the case for the last project with the great Akufen team, Stéphane Demotte and Emmanuel Durgoni. Stéphane had to develop a nice continuous movement around a building.

Produced by the NFB and created by akufen.

What are the technical solutions to achieve this type of movement?


100% Threejs solution

Threejs offers the possibility to create curves. The one I use most often is CatmullRomCurve3. You just have to give it a list of coordinates and it will compute a nice trajectory passing through all these points. All that’s left to do is to get the positions along it using the getPoint or getPointAt methods and to make the camera follow it.

Example of how to use this technique.
Check “animationView” to see the camera move.

You’ll say to me, “that’s all very well, but how do I define this list of points?!” And you’re right, that’s where it gets complicated. Moreover, it means that you will not be able to work with a 3D animator.

This does not mean that it is impossible, but I wish you luck!
https://mobile.twitter.com/Samsyyyy/status/1248616247295533056


50% Threejs / 50% Blender solution

I recently started learning Blender. My goal was not to become an expert, but rather to understand the mechanisms of 3D creation software. In order to better communicate my technical needs with the 3D artists.

This allowed me to discover the technique that I will present below. To summarize, we are going to create in a few minutes a camera movement from blender, then use it with Threejs.

Blender side

We start by creating a scene with some elements. I’ve put 3 cubes and a camera.

Just starting out? Here are some shortcuts to know.
X = delete
Shift+A = add an element (shape, light, camera, etc)
Cmd+G = move
Cmd+R = turn
Cmd+S = enlarge
(for the last 3 commands, then press x, y or z to move in one direction only)

Blender scene panel

Now the important step: camera animation!
Use the Animation tab to see the timeline appear at the bottom of your screen. Click the Auto Keying button (the little button with a circle at the bottom), and place yourself on the first keyframe. Then position your camera as desired. The positions/rotations will be saved automatically. Move to another keyframe, and repeat the exercise, until you are satisfied with the result.

More information on moving the camera in the timeline.

Blender animation panel

Finally, export your scene in “glTF” format.

Click on File, Export, then glTF 2.0.
Select the glTF Embedded format, select Cameras, then export.

Blender export panel

Threejs side

Find all the source code and the Blender file of this demo on Github

I am not going to detail the whole code, but I would like to draw your attention to 3 key points.

The camera

This allows you to have the same fov, near and far parameters as in Blender.

The animation

Although the camera is at the root of the Blender scene, after export to glTF format, it is automatically added in a container object. The animation must therefore be applied to this camera.parent container.

Showtime !

All that remains is to increment animationMixer.setTime based on the total time of the animation (in seconds). In the demo, we use a percentage corresponding to the user’s scroll.

Et voilà ! It’s ready.

Demo of camera scrolling
Demo of camera scrolling

Thank you for reading!

If you liked this article, don’t hesitate to share it on your social networks, it helps me a lot.

Share

Leave a Reply

Your email address will not be published. Required fields are marked *