Basic scene with three.js

If you haven't get in touch with three.js already this is for you! In this article I'll give you a quick introduction to the fantastic world of 3D in the web with three.js. Be sure to visit the website of ricardocabellov aka mr.doob the bright mind behind three.js.

First things first!

To get yourself up and running the first thing you have to do is include the three.js Library into your html file. Note: Load your scripts always at the bottom of your html file.

You can download the source code for this article here:

Github

Wanna dive in the code directly? You can view the Pen here

Codepen

renderer

Okay! With three.js in place we can start building our first scene. To intitialize the three.js renderer we create a new renderer Object like this: new THREE.WebGLRenderer(); and append it to the DOM. We have some options at this point, e.g. if we want shadows in our scene we have to enable it through the renderer manually. We can control the background Color with the .setClearColor(); method of the renderer. There is also the Canvas renderer available but it should only be used for simple scenes and if the Browser doesn't support WebGL.

scene and camera

Now we have a renderer for our 3D scene, let's create the actual scene where we can place our models and a camera to see these models. I want to have some perspective in the scene so I setup a perspective camera with a field of view(fov) 75.

The higher the fov the more distortion on the edges will appear. Human eyes have a fov ~75 (this depends on your viewport dimensions).

Our first cube!

We are now ready to rock the stage aka scene. Everything is there and we can show our first cube. Note: Objects in three.js have always two components. The geometry and the material.

Lights on!

A Spotlight will light our cubes (if you want to have shadows you turn them on manually).

runtime

Yeah! The first cube in space. We can add a render function to add a runtime to our scene. The Computer tries to run the render function at 60fps. If the machine is too slow for 60 it will automatically slow down. At 50fps the scene feels a bit sloppy and everything below >40fps is slow. Try to stay close to 60fps for a smooth Animation.

@paulirish wrote a great article about requestAnimationFrame and why you should use it.[1]

animate

Before we can call the animation function inside the render function we have to define it. I rotate the whole scene each time the animation runs(60fps) for 0.0005 increments around the y-Axis for a nice turntable effect.

That's it!

Your first 3D scene in the web, great! You are now ready to create your own scene with three.js. The base setup looks always like this but to give you some more useful tips right at the start I want to show you some methods how you can add multiple objects in a performant way.

Multiple Objects

Reminder: Meshes have always two parts: geometry and the material. If you want to add multiple cubes you don't have to create these two parts each time again, instead you can store the geometry and the material in a variable outside the for loop (e.g. geometry,material) to save some memory.

mesh.updateMatrix();

Did you see the mesh.updateMatrix(); and the mesh.matrixAutoUpdate = false;? This is for performance reasons. Every mesh updates itself frame by frame unless you are telling it not to do. Because our cubes are only static at this point we don't need that update and we can set the matrixAutoUpdate to false. But because we are adding multiple cubes in a for loop to the scene we have to update the cube before the next cube is added, otherwise we would end up with just one cube visually (500 cubes with the same position).

Control the camera

We have a bunch of cubes now but we can't control our camera to move in space. Three.js offers multiple ways to control the camera. For this scene I want to add an OrbitControl. Include the script for the OrbitControls.js in your document first and then you can add the controls to the camera.

The camera is an argument for the OrbitControls. This is important to note because if we want to switch the camera later on we have to update the controls, too! To prevent that the controls can go through the floor (we don't have one in our scene yet but maybe you add one later) we have to define a min and maxPolarAngle. Set the minPolarAngle to Math.PI/2.

Math what?! — Quaternions

Rotation in 3d space is not always as you might expect. Three.js works with Quaternions which tries to represent the orientation and rotation of objects in threedimensional space[2]. To calculate the correct values it takes 4 values x,y,z and w.

Rotation with Quaternions
90 * Math.PI/180 //=== 90°
30 * Math.PI/180 //=== 30°…

Pro Tip! Use your Console.

Have a look in your Dev Tools they provide us a great way to inspect our scene and helps us with properties of the objects. Especially when you're not familiar with the objects of three.js yet.

Hit 'alt'+'cmd'+'i' to open the devTools in Chrome and type in the name of your Mesh and you get the hole list of properties and methods.

console

You can download the source code for this article here:

Github

Wanna dive in the code directly? You can view the Pen here

Codepen