Please enable JavaScript to use CodeHS

Create 3D Objects with Three.js

In this tutorial, you'll learn about the Three.js JavaScript library and create a 3D model. You'll use geometric shapes, point lights, and a scene camera to develop a 3D scene that includes a geometric object.

By Matt Arnold

Curriculum Developer

Three.js Library

Using the import declaration at the start of a JavaScript (JS) program, you can access a variety of JS libraries. Three.js is a JavaScript library that simplifies the ability to code and create animated 3D graphics within a web browser. The library utilizes a web graphics technology known as WebGL. Similar to an HTML canvas, WebGL lets developers render 2D and 3D interactive graphics in a web browser.


In this tutorial you’ll use JavaScript and the Three.js library to create a basic 3D cube. You’ll set up the WebGL scene, add lighting to the scene, and incorporate object materials to add some realism.

Import Three.js

Before you begin, you’ll need to import the Three.js library at the top of your JavaScript program. There are multiple CDN (content delivery network) services where you can retrieve the library, but for this tutorial you’ll use one from Cloudflare.

Note: Every Three.js JavaScript program you create must include this import declaration at the start in order to access the library.

// Import the Three.js library
import * as THREE from 'https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.module.js';
JavaScript

Set Up a 3D Scene

In order for any 2D or 3D objects to be seen on a web page with Three. js, you’ll first need to establish a scene, a camera, and a renderer. For each of these, you’ll declare a global constant variable.

Note: You’ll want global scope variables for this program to allow multiple functions access to them, like main, animate, and update functions.

A new element is assigned to each variable by calling the THREE library to use its Scene(), PerspectiveCamera(), and WebGLRenderer() functions.

// Global Variables - add scene, camera, renderer, and world light
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
JavaScript
  • Line 2: The scene variable is assigned a new Three.js scene object. This allows you to add elements, like 3D models and lights, to the scene later in your program using the scene.add() function. You can also adjust elements in the scene, such as the background color. Think of the scene as a container or box that stores all of the elements that are added and created within the graphical environment.

  • Line 3: For the PerspectiveCamera() function, you’re also passing some arguments. These attributes specify the camera’s field of view (75), aspect ratio (window.innerWidth / window.innerHeight), and near (0.1) and far (1000) clipping planes. We won’t get into the specifics of each attribute in this tutorial, but if you have difficulty loading the graphics, you can reduce the far clipping plane value to something like 500 instead of 1000.

  • Line 4: The renderer variable is assigned a new WebGL renderer system. This allows you to call on the Three.js rendering system multiple times for animations and movement in the scene. It’s also used to specify the rendering size of the scene - the width and height. The renderer is added to the browser as a web page DOM element.

Geometries

The Three.js library comes with a variety of 2D and 3D geometrical shapes that can be altered and manipulated to create complex graphical objects. For this tutorial, you’ll start by adding a basic box to your 3D scene.


To create most geometric shapes in Three.js, you must create three global constant variables that establish the 3D object’s geometry, material, and mesh. The latter pulls the geometric shape and material together to form a cohesive 3D mesh object.

// Global Variables - cube or geometric object
const geometry = new THREE.BoxGeometry(2, 2, 2);
const material = new THREE.MeshPhongMaterial({color: 'purple'});
const cube = new THREE.Mesh(geometry, material);
JavaScript
  • Line 2: The variable is assigned a new box geometry by calling on the library’s BoxGeometry() function. The attributes passed to the function set the lengths for the box’s x-, y-, and z-axis. Play around with these values later to change your box’s size.

  • Line 3: Three.js provides various model materials for rendering 3D objects. In this tutorial, you’ll use the MeshPhongMaterial() function to add some color to it. This mesh material is based on the Blinn-Phong model, hence the function’s name. You can change the purple color to one of your choosing. The function accepts any JS color name, hex color code, or RGB color code.

  • Line 4: The final geometric shape variable for your box model calls the Three.js Mesh() function. This function basically uses the geometry and material values to create a final mesh of your 3D geometric object.

Main Function

Now that you’ve declared the essential global variables needed to create your scene and 3D model, you’ll create a main() function that initializes the scene, camera, renderer, lighting and object. Run the program below and adjust some of the attributes in your elements.

For example, change the BoxGeometry() attributes to adjust the size of the box. Try changing the color of your box. Can you change the position or rotation of your box or camera using some of the code within the main() function?

Breakdown Main Function

There are a lot of elements added to the 3D scene and initial positioning of items in the main() function. Let’s breakdown each snippet of code to analyze more what’s happening.

  • Line 18: Since Three.js uses WebGL to render graphics in the browser, this code removes any HTML <canvas> that may be lingering in our JS graphics output.

  • Lines 22: This sets the background color for the scene using a hex color code, but you can change this to any color you want - similar to the cube’s color.

  • Lines 23-24: The first line sets the renderer size to the full width and height of the window. The second line adds the renderer DOM element to the body of an HTML page, in this case the output window.

  • Line 27: Sets the camera’s position using attributes for the x, y, and z axes of the camera in the 3D scene or world.

  • Lines 30-31: In order to see a 3D object’s material when using the MeshPhongMaterial() function, you’ll need to add some light to your scene. Three.js includes several different light types, but for this tutorial, you’ll add a basic world light - think of it as the sun.

    The world light is created using the library’s HemisphereLight() function. There are three attributes you’re passing to the function that determine the color used for the brightest surfaces (#FFFFFF), the color used for the darkest surfaces of your object (#757575), and the brightness value for your light (1.7). You can adjust these attributes and see how they change your 3D object’s appearance in the scene. The last line in this block of code adds the light to the scene.

  • Lines 34-36: This block of code sets the x, y, and z positions of the center of our cube within the 3D scene. Here, the value for each axis is 0 placing the cube in the center of the scene. To better see that this is a cube and not a square, the cube’s rotation is set to 0.5 along the x-axis. The y and z axes are both set to 0. This tilts the cube forward slightly. You can play with these three axis values to render your cube in different, tilted views. Lastly, the cube is added to the scene.

  • Line 39: This code renders the WebGL scene on the page.

  • Line 43: To begin the program, you must call the main() function.


Now that you know a little more about how this program is written, try changing more attributes for the cube to place it in different positions with different viewpoints. How does the world light reflect off the 3D object as you change positions and rotations?

Challenge: Torus Knot

Can you create a different geometric 3D model using Three.js? Replace the cube’s code in the above program with the following code to create a torus knot.

// Global Constant Variables
const geometry = new THREE.TorusKnotGeometry(10, 3, 100, 16);
const material = new THREE.MeshPhongMaterial({color: '#3498eb'});
const torusKnot = new THREE.Mesh(geometry, material);

// Add to the main() function
scene.add(torusKnot);
JavaScript

Hint: To best see the torus knot, you may need to move the camera back by increasing the z-axis position from 5 to something like 30.

Animate the Cube

Proceed to the Animate 3D Objects with Three.js tutorial to create an update() function that will allow you to update your 3D object’s position, rotation, and user orbiting each frame - creating a dynamic and animated 3D model.

Three.js Docs

Be sure to check out the full Three.js library documentation for assistance and manuals.