A Designer's guide to Three.js

A Designer's guide to Three.js

What is Three.js, and why should a designer use it?

Over recent years, browsers have acquired powerful and advanced features that can be accessed directly with the help of JavaScript. One can easily create simple and complex 3D worlds on a web page with few lines of code. Three.js is a powerful javascript library that makes it a lot easier to render 3D elements on a webpage. A designer's mind can do a lot of truly amazing things with Three.js —

  • Quickly develop interactive prototypes
  • Define interfaces in high-fidelity
  • Creating Virtual Reality (VR) and Augmented Reality (AR) scenes
  • Animating and moving objects through a 3D scene
  • Add physics and basic mathematics to your product to make it as realistically fun as possible

In this article we will learn the basic components that forms the structure of a Three.js app. Effectively coding with Three.js will require some basic knowledge of JavaScript topics like DOM, arrays, functions, loops, conditionals etc. (you can quickly revise the required javascript basics here by jumping in to the timestamps.

There are 7 core concepts in Three.js that are important to understand for beginners:

  1. Setting up the HTML Canvas and load Three.js
  2. Creating a scene
  3. Setting up the camera
  4. Setting up the renderer
  5. Adding an object to the scene
  6. Animating and rotating the geometry
  7. Adding Lights

1. Setting up the HTML Canvas and load Three.js

HTML Canvas is what allows us to create 3D art and with a little bit of coding, we can draw, animate and interact with this art. In the index.html file, the H1 element is defined like this:

<body>
<h1> Hello World</h1>
</body>

Similarly, when we are dealing the Canvas element, it will be wirtten like this:

<body>
  <canvas id="c"></canvas>
</body

Now, we will ask three.js to draw into that canvas. The height and width of this canvas element will be equal to the height and width of our browser window.

<script type="module">
import * as THREE from '../../build/three.module.js';

function main() {
  const canvas = document.querySelector('#c');
  const renderer = new THREE.WebGLRenderer({canvas});

</script>

WebGLRenderer uses WebGL (Web Graphics Library) to render 3D to the canvas.

2. Creating a scene

To actually be able to create anything with three.js, we need three things: scene, camera and renderer. A scene is like a container which contains all your objects, cameras and lights. Anything you want three.js to develop needs to be added to the scene.

const scene = new THREE.Scene();

3. Setting up the camera

In order to locate things inside a scene, we need a camera. There are different types of cameras in Three.js like ArrayCamera, CubeCamera, OrthographicCamera, PerspectiveCamera, and StereoCamera. The most common one used for rendering a 3D scene is PerspectiveCamera, which is designed to emulate how a human eyes would see. The code looks likes this:

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

The first attribute in the code is Field of View (FOV), which is the amount of the world which is visible at any given moment out of 360 degrees. It is measures in degrees. The second attribute is the aspect-ratio, which is based off of users browsers window. We can calculate it by window's inner width and inner height. The last two arguments are near and far. What that means is - that objects further away from the camera than the value of far, and the objects closer than the value of near will not be be rendered.

4. Setting up the renderer

Now that we have setup camera, we need the renderer to render out the graphics in the scene. We also need to set the size at which we want it to render our app - by mentioning width and height of the area we want to fill with our app, which in this case is the width and height of the browser window. We can also give setSize smaller values, like window.innerWidth/3 and window.innerHeight/3, which will make the app render at smaller size. Our camera is positioned in the middle of the scene, so now what we can do is move it along the z-axis:

const renderer = new THREE.WebGLRenderer();
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(renderer.domElement )  //rendering into HTML body
camera.position.setZ(30);

The final thing we do is use renderer's render function and pass scene and camera as the arguments:

renderer.render(scene, camera);

We will get the blank screen in the browsers as we not have any object to it. So lets add an object.

5. Adding an object to the scene

There are three basic steps to create an object.

Geometry: A geometry is a set of vectors that defines the geometry itself. Three.js has a bunch of built-in geometries like box, sphere, cones, rings etc. For eg. in order to create a boxGeometry we need to declare its vectors like this -

const boxWidth = 1;
const boxHeight = 1;
const boxDepth = 1;
const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);

Material: Material is like a wrapping paper for an object. We can use this to apply color using the standard CSS 6-digit hex color value.

const material = new THREE.MeshBasicMaterial({color: 0x44aa88});

Mesh: Mesh is a combination of Geometry and Material. Geometry is used to define the shape of the object. Material is used like a wrapping paper, to define the color, texture etc.

const cube = new THREE.Mesh(geometry, material);

We then finally add the mesh to the scene

scene.add(cube);

In order to actually see it, we need to rerender the screen.

renderer.render(scene, camera);

6. Animating and rotating the geometry

We don't want to call the render method again and again in our code, so a better approach here is to set up a recursive function that gives us an infinite loop that calls the render method automatically. Here is our loop:

function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}

animate();    //call the animate function

requestAnimationFrame is a request to the browser that you want to animate something. You pass it a function to be called. In our case that function is render.

Now let's add rotation to our object (cube). There are different properties like rotation, position, scale etc. If we change it's properties inside the loop, the shape will animate.

function animate() {
  requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.005;
  cube.rotation.z += 0.01;
  renderer.render(scene, camera);
}

animate();    //call the animate function

7. Adding Lights

There are many kinds of lights in Three.js like AmbientLight, HemisphereLight, DirectionalLight etc. Let's use Directional Light here. A Directional Light is often used to represent the sun. Here is how it is being declared:

{
  const color = 0xFFFFFF;
  const intensity = 1;
  const light = new THREE.DirectionalLight(color, intensity);
  light.position.set(-1, 2, 4);
  scene.add(light);
}

Directional lights have a position and a target. Both default to 0, 0, 0. Here we're setting the light's position to -1, 2, 4 so it's slightly on the left, above, and behind our camera. The target is still 0, 0, 0 so it is targeted towards the origin.

Three.js is a wonderful tool and a designer can do truly amazing things with the help of it. Please refer to the official Three.js documentation to learn the basics in depth. I am writing more tutorials on specific use cases as I am still learning new things every day. Happy blogging :)