ZEALS TECH BLOG

ZEALS Developers Blog

Getting started with Three.js basics.

This tutorial requires that you have a basic understanding of javascript and some knowledge of codepen and how to set up a project there. We’ll be recreating the project from the codepen below. It is quite simple and can be set up in around 15 minutes.

https://codepen.io/licebeam/pen/KGzWOw

Three.js is a javascript library that allows you to render 3d in html5 canvas dom elements using webGL. https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API

To setup, we need to create a basic html page that we can insert our "render" into via javascript. First we’ll add the following code to our index.html file.

 <html>
 
 <head>
 </head>
 
 <body>
 </body>

</html>

Secondly we’ll need to add a few css properties to our project. We’ll give the body a margin of zero to have it fill the page correctly. Additionally when we render our canvas element to the dom it will need to have it’s height and width set to fill the body. The code required is below.

body {
  margin: 0;
}

canvas {
  width: 100%;
  height: 100%;
}

Finally we can move on to setting up our Three.js project. Go ahead and add the Three.js cdn link to your javascript in the settings section. https://cdnjs.com/libraries/three.js/

To begin we need to create a new scene object in our javascript code.

var scene = new THREE.Scene();

The scene is where all of our other objects will render to in the future. Next we’ll set up our perspective camera, this will allow us to move around the scene as we please and it also allows us to change how much of the scene is viewable to the user.

var camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);

Next we’ll set up our webGL renderer which will in turn will allow us to render to our desired dom element.

var renderer = new THREE.WebGLRenderer();

We need to set the height and width of the renderer to match our window.

renderer.setSize(window.innerWidth, window.innerHeight);

Now we’ll create our canvas dom element to render into using document.body.appendChild.

document.body.appendChild(renderer.domElement);

Now that you’ve set up the rendering you’ll notice you still have nothing but a blank screen. This is because we need to create some geometry, meshes and materials to render to the screen don't worry it's easier than it seems. We’ll start with a simple square.

var geometry = new THREE.BoxGeometry(8, 8, 8);

The 3 values passed into BoxGeometry are the x, y and z scales of the object. You can make your geometry as big or as small as needed. Now that we have our cube we’ll need a material to apply to it. Think of a material as a skin that covers our cube's geometry.

var material = new THREE.MeshBasicMaterial({
  color: 0xff00f0,
  wireframe: true
});

Our material has two properties a color which takes a hex value and wireframe which is a boolean.

Material creation can be extremely daunting so I suggest you take a look at the different properties on the Three.js documentation here to gain a bit more understanding. https://threejs.org/docs/#api/en/materials/MeshBasicMaterial

Let’s create two more materials, we’ll use them for the other cubes we'll make later.

var material2 = new THREE.MeshBasicMaterial({
  color: 0xffff00,
  wireframe: true
});

var smallMaterial = new THREE.MeshBasicMaterial({
  color: 0xffffff,
  wireframe: true
});

Feel free to experiment with other properties sizes and colors for this example.

Next let’s try another method of creating geometry and create a triangle using vertices. Geometry is extremely complex and requires some knowledge of math in advanced situations. Take a look at the documentation for a more detailed example of what we’ll be doing next. https://threejs.org/docs/#api/en/core/Geometry

Let’s assign our new Geometry object to the variable smallGeometry.

var smallGeometry = new THREE.Geometry();

Each geometry has a property called vertices. Vertices are points in space that can be rendered. Essentially every polygon is made up of multiple vertices in different position.

Let’s make a triangle shape by pushing three vertices to the object in different positions. One thing to note is the term Vector3. If you are from a javascript background you may not be entirely familiar with this but simply put; it is just a set of x, y and z positions in space.

smallGeometry.vertices.push(
  new THREE.Vector3(0, 3, 1),
  new THREE.Vector3(-3, -1, 0),
  new THREE.Vector3(1, 2, 0)
);

Next we’ll push faces to our object, faces are just how each of our vertices connect. Allowing us to apply our materials over the faces of our object.

smallGeometry.faces.push(new THREE.Face3(0, 1, 2));

Next we’ll compute the boundaries of our object.

smallGeometry.computeBoundingBox();

Finally we need to create something to render with our new geometries and materials. We’ll begin by creating three different mesh objects that take two arguments: geometry and material, luckily we’ve already created these so feel free to mix and match.

var cube = new THREE.Mesh(geometry, material);
var cube2 = new THREE.Mesh(geometry, material2);
var centerCube = new THREE.Mesh(smallGeometry, smallMaterial);

Lastly we’ll add our new cubes to the scene so we can see them and setup our camera position to make sure they are in view.

scene.add(cube);
scene.add(cube2);
scene.add(centerCube);

camera.position.z = 5;

But wait, we should make them move. Animating your cubes is very simple. First we’ll create an animation function. Lastly when it comes to animation we’ll need to make sure we render the scene and camera correctly every frame with renderer.render.

var animate = function() {
  requestAnimationFrame(animate);

  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;

  cube2.rotation.x -= 0.01;
  cube2.rotation.y -= 0.01;

  centerCube.rotation.y -= 0.12;
  centerCube.rotation.x -= 0.0;

  renderer.render(scene, camera);
};

All we have to do now is call our animate function and our cubes should be animating on the screen.

animate();

Thanks for checking out this blog post, I hope it gave you a little bit of insight on how to set up a basic Three.js project.

-Dustin Front End Engineer at Zeals