Scroll to top

The Web’s complexity shifts daily and its possibilities grow just as quickly; particularly with 3D rendering. WebGL (Web Graphics Library) is a JavaScript API for rendering interactive 3D and 2D graphics. Three.js by Ricardo Cabello is a library built on top of WebGL, ensuring authored code is compatible across various browsers. 

Three.js is to WebGL what jQuery is to JavaScript, offering declarative syntax loved by so many, and abstracting away the headaches for 3D in the browser. Let’s review it, get a general overview of syntax and look at how to get started if you’re new to the game of 3D.

What We’re Working Towards

Take a look at the following demo on CodePen; use your mouse cursor to drag the model around, zoom in and out with your mouse wheel.

1. Setting the Scene

We’re going to be working in CodePen for the sake of ease; begin by linking to Three.js (CDN 126Kb) from your JS tab.

We begin by creating a scene, just like you start with a canvas in Photoshop. A scene is defined with a variable before any further code is authored. So, within your JS pane add:

1
var scene = new THREE.Scene();

Camera!

With the curtains up and ready for our performance we’ll need a way to view our awesomeness–time to introduce a camera. There are an array of cameras that Three.js comes bundled with, such as PerspectiveCamera, StereoCamera, OrthographicCamera and CubeCamera. For our purposes we’ll be using the PerspectiveCamera as it’s designed to mimic the way the human eye sees. Just like we define a scene with a variable, we do the same to define a camera:

1
var camera = new THREE.PerspectiveCamera();

Our PerspectiveCamera accepts four arguments: fov, aspect, near and far

  • The fov (field of view) is how much you can see around the camera’s center. Think in terms of a wide-angle lens on a camera versus a standard lens. 
  • The aspect is the ratio of the fov, or in other words the width to height of a screen (e.g. 4:5, 16:9). 
  • The last two, near and far, are the planes of a solid. Together they control if an object is rendered based on its distance from the camera. near is the closest an object or part of an object can be to the camera while still being rendered, far is the furthest an object can be from the camera and still be rendered. Together these define the camera’s viewing frustum.
viewing frustumviewing frustumviewing frustum
Viewing frustum

Here’s an example of the PerspectiveCamera arguments:

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

It’s not important to understand each value at this point except to be aware of the values that can be passed. Continuing on we’ll need to set the camera’s position.

1
camera.position.set(x, y, z);

This line is the object’s local position. This sets the xy and z coordinates of the vector. Without it the camera will see nothing.

2. The WebGLRenderer

The next important ingredient in our recipe is to create a WebGLRenderer. This is the piece that is responsible for the magic of displaying your creation.

1
var renderer = new THREE.WebGLRenderer();

The WebGLRenderer can also accept properties and values passed in as an object.

1
var renderer = new THREE.WebGLRenderer({
2
  alpha: true // remove canvas' bg color

3
});

There are quite a few property : value pairs that can be used–they’re listed in the docs should you decide to dive deeper at a later point (something I highly encourage).

With the renderer defined we can set methods to further customize our creation such as setSize; a method you’ll use in almost every Three.js project.

1
// Make scene renderer the size of the screen

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

There are many more methods you can use, but for our purposes we’ll stick with setSize()

3. DOM

Now that our desired size is defined we’ll need a way to attach it to the DOM.

1
document.body.appendChild( renderer.domElement );

This domElement property is where the renderer draws its output and will be in the form of a canvas element. Although I’m using document.body you could append or prepend the canvas element anywhere you like. It’s really up to you where you desire the placement based on your specific project needs.

Creating an Object

For the next step we need to create an object–since all we’ve done up to this point is declare a scene, a camera and a renderer. For demo purposes let’s grab a cell phone from 3D Warehouse so we can build a product previewer for people purchasing an iPhone online.

iphone 6 by Jeremie Piphone 6 by Jeremie Piphone 6 by Jeremie P
iPhone 6+ by Jeremie P

Typically you can use applications such as SketchUp or even Blender to draw your 3D objects, however there is a high learning curve to 3D drawing applications–a curve which is certainly outside the scope of this article.

If You Like Piña Collada

To insert our 3D object to the scene we have to use the ColladaLoader. It should be mentioned that any graphic you decide to use should generally aim to be under 1-2Mb and must be a Collada file in order to use with Three.js: these are files that end with the .dae extension. If you open up a Collada file you’ll see it’s actually written in XML.

We start by defining the ColladaLoader using a variable and calling the method along with defining another variable to represent the 3D graphic for referencing at a later point.

1
var dae, // graphic

2
    loader = new THREE.ColladaLoader(); // loader

This is a great start, but we have some more work to do in order for us to display the phone. Let’s make a function that will do just that:

1
function loadCollada( collada ) {
2
  dae = collada.scene;
3
  scene.add(dae);
4
}

For the next step we’ll use the load method, pass the URL of our Collada file, and then call our function by name as the second argument:

1
loader.load( 'https://myurl.com/file/iphone6.dae', loadCollada);

If you’d like to know more about the ColladaLoader you can dig through the source code on GitHub.

4. Render Loop

With our loader and graphic finally in place there is one last step; we need to create what is called a “render loop”. This is because we’re not actually rendering anything yet.

This “render loop” is what will cause the renderer to draw the scene sixty times per second. The following function will make our creation come alive (the best part of the entire process).

1
function renderPhone() {
2
  requestAnimationFrame( renderPhone );
3
  renderer.render(scene, camera);
4
}
5
6
renderPhone();

requestAnimationFrame has a number of advantages. The most important is that it pauses when the user navigates to another browser tab, ultimately not wasting their processing power and battery life.

Final Product

The result of all this work is a sweet rendering of a 3D iPhone that you can spin, rotate and zoom in and out of:

There are a few more bits that went into the final creation, so I encourage you to dive deeper into the JavaScript panel of the demo.

For example; Lighting (AmbientLight, HemisphereLight, PointLight), TrackballControlsAxisHelper and a Window Resizing event. Some of these mentioned items don’t contain documentation such as TrackballControls, but you can find all the properties available within the core JS file on GitHub. There are other really cool controls you can use, which are also listed on GitHub.

Inspiration

Sometimes you need a little inspiration to get the ‘ol brain to fire ideas at a rapid pace. The following are some of my favorite demos using Three.js that turn dreams into reality. 

httpspaperplanesworldhttpspaperplanesworldhttpspaperplanesworld
https://paperplanes.world
httpsthroughthedarkwithgooglecom grab your headphoneshttpsthroughthedarkwithgooglecom grab your headphoneshttpsthroughthedarkwithgooglecom grab your headphones
https://throughthedark.withgoogle.com (grab your headphones)
httpcarvisualizerplus360degreescomthreejshttpcarvisualizerplus360degreescomthreejshttpcarvisualizerplus360degreescomthreejs
http://carvisualizer.plus360degrees.com/threejs

Further Reading

Rachel Smith wrote a great article on CodePen about WebGL and I highly recommend giving it a read when you have free time. The tutorial is filled with simple language and is a thorough explanation of Three.js discussing scene, geometry, lighting, materials and animation that I certainly couldn’t cover in this short post.

You may also enjoy:

Credits

This article wouldn’t have been possible without the generous help from the Animation at Work Slack Community so I’d like to thank (in no particular order) Stephen Shaw, Jeff AyerLouis Hoebregts, Neil Pullman, Eli Fitch and Chris Johnson.

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.