Michael Barry

CS525D · Spring 2014

three.js native 3D rendering for the browser

three.js is a JavaScript library designed to simplify 3D rendering in the browser using WebGL. WebGL has a low-level, imperative JavaScript API which makes it relatively difficult to use on its own compared with a higher-level declarative technology like SVG. three.js provides a straightforward and concise API that (while still imperative) makes setting up 3D scenes using WebGL much simpler.

WebGL renders scenes to a single <canvas> DOM element that contains the entire visualization on the page, unlike SVG which is composed of a separate DOM element for each element of the visualization. This means that CSS can not be used to style a WebGL visualization and all style must be set up programatically in JavaScript.

Most modern desktop browsers support WebGL - although as of March 2014, most mobile browsers do not. When a browser does not support WebGL, three.js's modular architecture allows swapping in an HTML5 canvas renderer.

Your browser supports WebGL all examples will work as intended.

Your browser does not support WebGL all WebGL examples will be replaced png or animated gif images. To view examples as they were intended, please enable JavaScript and WebGL, or download a modern browser.

This page explains some of the core concepts behind setting up a scene using three.js and populating it with objects. It builds up a simple example of a spinning sphere and concludes with links to further examples and documentation.


Installation

A three.js visualization is just a web page consisting of HTML, CSS, and JavaScript. Include the three.js script on your page before any scripts that use it. Find the latest three.js build here.

<html>
  <head>
    <title>Page Title</title>
    <style>
      html { height: 100% }
      body { height: 100%; margin: 0; padding: 0 }
      canvas { width: 100%; height: 100% }
    </style>
  </head>
  <body>
    <script src="three.js"></script>
    <script>
      // insert code for the three.js visualization here
    </script>
  </body>
</html>

Setting Up the Scene

Before creating any objects in your visualization, you must first set up the scene, camera, and renderer. The scene is a generic container for the visualization which can optionally have "fog" that dims remote objects. The camera defines the aspect ratio and field of view as well as near and far clipping distances to avoid rendering objects that should not be visible. You can also configure the camera's focal length in units that correspond to mm for a 35mm camera.

Finally you need to create a renderer that will take the model you build and render it to the screen. The WebGLRenderer uses hardware-accelerated WebGL. The CanvasRenderer can be used if the browser does not support WebGL. The renderer provides the canvas DOM element for rendering that must be added to the page to see the visualization.

// create the scene
var scene = new THREE.Scene();
// create the camera with 45-degree field of view and an aspect ratio that matches the viewport
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
// move the camera 10 units back from the origin
camera.position.z = 10;
// create the renderer
var renderer = new THREE.WebGLRenderer();
// make the renderer fill the viewport
renderer.setSize(window.innerWidth, window.innerHeight);
// add the DOM element that the renderer will draw to to the page
document.body.appendChild(renderer.domElement);
// set the background color to almost-white
renderer.setClearColorHex(0xEEEEEE, 1.0);
renderer.clear();

Filling and Lighting the Scene

After setting up the scaffolding for a scene, you can use geometries, materials, and mesh to add objects to it. A geometry is the shape of an object. three.js comes with built-in functions for creating common geometries like a cube, circle, cylinder, plane, ring, sphere, text, etc. You can also use a geometry loader to load custom geometries from files or load data files and create the geometries from them. A material is the image texture, flat color, etc. that is draped over the geometry to produce a solid object. A mesh takes a geometry and material and creates the solid object that can be rendered to the screen at a particular location.

Finally, a light provides illumination for the objects in the scene, which will otherwise show up as black.

// create a solid-white sphere mesh composed of a geometry with radius 3 and 32 horizontal and vertical segments
var cube = new THREE.Mesh(
  new THREE.SphereGeometry(3, 32, 32),
  new THREE.MeshLambertMaterial({color: 0xffffff}));
scene.add(cube);

// add a spotlight to the scene
var light = new THREE.SpotLight();
light.position.set( -10, 20, 16 );
scene.add(light);

Rendering the Scene

Once the scene has been created and populated, you need to explicitly tell the browser to render it. To render it once simply add renderer.render(scene, animation) to the end of your code.


Animation

To animate a three.js visualization, you must explicitly draw it many times per second. The recommended way to do this is to use requestAnimationFrame which attempts to invoke a function up to 60 times per second. In this animation loop you should respond to browser resize events and perform necessary animation calculations.

This snippet starts an animation loop that responds to browser resize events and rotates the camera continuously around the sphere.

function animate(t) {
  // update the aspect ratio and renderer size in case the window was resized
  camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 1000 );
  renderer.setSize(window.innerWidth, window.innerHeight);
  // spin the camera in a circle
  camera.position.x = Math.sin(t/500)*10;
  camera.position.y = 0;
  camera.position.z = Math.cos(t/500)*10;
  // point the camera at the origin
  camera.lookAt(scene.position);
  // render the scene again
  renderer.render(scene, camera);
  // request the next animation frame to render again
  window.requestAnimationFrame(animate, renderer.domElement);
};
animate(new Date().getTime());

Putting it all together

The finished product, complete with animation and lighting (or view full screen).


Visualizing Data with three.js

three.js provides the basic building blocks needed to create 3D data visualizations. Once you understand the basics it is fairly easy to programatically construct visualizations driven by the dataset you are interested in. Here is screen capture (view full screen demo) of a simple 3D scatterplot derived from housing price data vs. proximity to work locations and pupil to teacher ratio provided by UCI Machine Learning Repository.

More facilities are provided by three.js for adding text labels, legends, user-controlled motion, etc. Below are some more polished visualizations using three.js from across the web.



metropolitain.io

Visualization of the Parisian subway system created by Dataveyes.

World Population

3D visualization of population distribution, created by the Google Data Arts Team.

100,000 stars

3D interactive tour of the galaxy created by some space enthusiasts at Google.


Learn More

This page only begins to scratch the surface of what is possible with WebGL and three.js. Check out the full three.js documentation for a complete reference. Introduction to three.js also gives a good overview for beginners.