Pick a theme:

Getting Started

by Lea Rosema

What's Three.js at all?

anchor

Three.js is a 3D engine for the browser that can use WebGL for graphics rendering. Next to WebGL, there are other renderers such as a SVGRenderer or CSS3DRenderer.

Three.js comes with geometries and rendering techniques and provides several cameras, materials, lighting techniques and more. It also provides a scene graph for organizing all your 3D data in scenes.

The official site features a lot of examples you can explore there.

In this chapter I will show a basic example of a three.js Hello World application.

First steps

anchor

Import three.js dependencies

anchor

This demo uses ES module imports, using the skypack cdn. In bigger products, you may want to use some kind of Parcel or Webpack toolchain for that. createapp.dev can help you with that.

I'm importing the core three js library and the OrbitControls.

The OrbitControls class is a helper class that adds the possibility to navigate through your scene.

import * as THREE from 'https://cdn.skypack.dev/three/build/three.module.js';
import { OrbitControls } from 'https://cdn.skypack.dev/three/examples/jsm/controls/OrbitControls.js';

Set up the renderer

anchor

To initialize Three.js, you will have to choose a renderer. Usually, you will choose the WebGL renderer. Another popular choice is the SVGRenderer.

// Create WebGL renderer
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

Init the camera

anchor

Initialize a camera with a perspective view. The parameters are

  • field of view
  • the aspect ratio
  • the near clipping plane
  • the far clipping plane

For more details on cameras, visit ThreeJS fundamentals

// Init perspective camera
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
camera.position.z = 5;

Create scene and add meshes

anchor

Three.js organizes every kind of 3d objects in a scene graph. Every mesh takes a material and a geometry. In the following example, I will create 50 spheres with a SphereGeometry and a MeshLambertMaterial using different colors.

const scene = new THREE.Scene();
const geometry = new THREE.SphereGeometry(0.2, 16, 16);

for (let i = 0; i < 50; i++) {
  const material = new THREE.MeshLambertMaterial({
    color: (Math.random() * 0x1000000) | 0,
  });
  const bubble = new THREE.Mesh(geometry, material);
  bubble.position.x = (-0.5 + Math.random()) * 5;
  bubble.position.y = (-0.5 + Math.random()) * 5;
  bubble.position.z = (-0.5 + Math.random()) * 5;
  scene.add(bubble);
}

Setup lights

anchor

The following section sets up a directional light and an ambient light.

  • ambient light: light with no direction, fixed-intensity and fixed-color light source that affects all objects in the scene equally
  • directional light: A directional light source illuminates all objects equally from a given direction. Comparable to the sun.
// Setup lights
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);

const dirLight = new THREE.DirectionalLight(0xffffff, 1);
dirLight.position.set(0, 10, 10);
dirLight.target.position.set(-5, 0, 0);
scene.add(dirLight);

Setup the OrbitControls

anchor

The OrbitControls is a control to navigate through the scene using the mouse or finger on touch devices.

const controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 0, 0);
controls.update();

Init event handlers

anchor
window.addEventListener('resize', this.onResize, false);

// rerender as soon as the camera position is updated
controls.addEventListener('change', this.render, false);

Resize the canvas

anchor

On resize, you will need to adjust the renderer viewport with the renderer.setSize method. Also, you will need to update the aspect property in the camera to the screen's aspect ratio.

renderer.setSize(window.innerWidth, window.innerHeight);
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();

Rendering the scene

anchor
renderer.render(scene, camera);

Dispose all the things

anchor

In the demo, dispose is never called, but if you're using some kind of client side navigation where the Three.js element is destroyed and re-initialized (this also happens a lot with dev servers using hot reload), you will need to clean up all aquired three.js resources. Also, you will need to take care of disposal as soon as you remove meshes from the scene:

  • Geometries need to be disposed
  • Materials need to be disposed
  • Textures need to be disposed
  • See the three.js manual for details: How to dispose of objects

CodePen Demo

anchor

See https://codepen.io/terabaud/pen/abNZjWm.