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:
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:
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 thefov
, or in other words the width to height of a screen (e.g. 4:5, 16:9). - The last two,
near
andfar
, 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.

Here’s an example of the PerspectiveCamera
arguments:
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.
camera.position.set(x, y, z);
This line is the object’s local position. This sets the x, y 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.
var renderer = new THREE.WebGLRenderer();
The WebGLRenderer
can also accept properties and values passed in as an object.
var renderer = new THREE.WebGLRenderer({ alpha: true // remove canvas' bg color });
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:
function loadCollada( collada ) { dae = collada.scene; scene.add(dae); }
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:
loader.load( 'http://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).
function renderPhone() { requestAnimationFrame( renderPhone ); renderer.render(scene, camera); } 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
), 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.
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 Ayer, Louis Hoebregts, Neil Pullman, Eli Fitch and Chris Johnson.