A Noob’s Guide to Three.js

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.

A Noob’s Guide to Three.js

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:

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:

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.

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.

// Make scene renderer the size of the screen
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.

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.

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.

var dae, // graphic
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:

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), TrackballControls, AxisHelper 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.

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.