Three.js or There’s a hypercube in my timeline and I can’t get out

Roxanne Turner
5 min readMar 19, 2018

--

Three.js makes WebGL 3D easy. It’s been around since 2010, but it feels like it’s everywhere all of a sudden. Even Facebook’s new 3D posts use the Three.js WebGL renderer, and now that WebGL is supported on every major mobile browser, not to mention almost every desktop browser, it’s probably time to hop on board.

the power of cubes, combined

Wait, what?

Three.js is a library, WebGL is the API that lets us use JavaScript to leverage graphics hardware when creating our 3D objects, scenes, and cameras. Before WebGL that was largely out of reach from the browser, unless you were using third-party plug-ins like Flash. So WebGL lets us use the power of a graphics card, and Three.js helps us avoid most of the boring, difficult, repetitive parts of dealing with WebGL. Take a quick peek around the spec if you don’t believe me about the boring and repetitive.

Thinking in 3D

First the good news: it’s not rocket science. But the bad news is you’re going to have to remember some simple geometry. We’re working in three axes: x for the horizontal, y for the vertical, and z for the depth to make it 3D magic. The intersection of the three is the origin, or 0, 0, 0. If pictures aren’t doing it for you, there’s always an example or three to help along the way.

Beyond axes, you’ll want to pick up some simple vocabulary. Vertices are points (vertex if it’s singular,) and we need at least three to make a face. That three vertices face is going to be a triangle which you’ll soon come to love, because everything is triangles, all the way down. A square is two triangles (but only four vertices) and a cube is twelve triangles across the cube’s six faces (but only 8 vertices.) The more complex your shape is, the more triangles you’re going to be building up, but you’ll also be rewarded with a higher resolution image. Do an image search for the Stanford bunny for a treasure-trove of low-poly (fewer triangles) and high-poly (more triangles) examples. Or dive deeper into the rabbit hole and learn about the Utah Teapot if you’re looking for the ‘Hello World’ of 3D modeling.

Getting Started

Getting started is as simple as importing the library in your HTML header, and adding a container for your rendered scene. For simplicity’s sake I like to start with the CDN but you should check out the website and GitHub repo once you’ve gotten your feet wet.

As far as your markup goes, that’s it! If you want your threeContainer div to fill your screen and don’t know how CSS-Tricks has got you covered.

Where the magic happens

We’re going to wait for our window to load, and then initialize our Three.js scene with a few things: a scene which will contain our camera and the renderer, a light, and an object.

Lights, camera, boxes, it’s time to make a scene.

Our scene, light, and box functions are going to need access to one another, so before we move on we’re going to declare these in the global scope along with the renderer, and some controls.

First I’m using the browser width and height to set the camera’s aspect ratio. Then we’re creating a scene and a perspective camera which takes parameters to define its viewing frustrum -the field of view, aspect ratio, as well as near and far planes. Next set the camera’s coordinates. Finally create a renderer, and attach it to your div container.

We’ll need a box to live in our scene to reflect some of our soon to be created sunlight. If you’re a 3D modeler, or at least comfortable with the tools you can bring in your own creations, but for our purposes we’re going to use Three.js primitives. We’ll need a geometry and a material, which we’ll pass into a mesh and add to our scene.

Last but certainly not least, let there be a light. There’s a world of choices to make when you’re choosing lights for a 3D project, much like making a film. Is it a dramatic scene? Try a spotlight. Want a cartoon feel? Then a hemisphere light might be the way to go. Here we’ll use a directional light, which most closely mimics sunlight.

Saving the best for last

If we opened our project in the browser right now, we’d be greeted with a big black nothing. And while calling renderer.render( scene, camera ) at the bottom of our light function would give us a view of our new box, we’re only going to get a single face head on.

Not much fun for a 3D project. Instead, I’ve downloaded OrbitControls and added it to the header of our index.html file. It’s going to give us the ability to orbit our camera our scene in a moment. But before we get there, we’ve still got to renderer.render, with a little bit of time on the side.

You could call setInterval here, but requestAnimationFrame has the added bonus of pausing when users switch to another tab cutting down on the processing power (that hardware we talked about earlier) and battery our Three.js scene uses.

The big reveal

Et voila! Now a visit to index.html gives you complete access to a spinning cube, complete with mouse orbit control. If your scene isn’t coming together at this point try referencing the full gist.

Go wild

Try adding another light. Then another box. Next a different shape and a new material. What happens if you pass your directionalLight into controls instead of camera? Can you figure out how to make the background of your renderer transparent? Maybe your scene needs a little fog, for ambiance? Build up a composition with a bit of your own style, and then come back for part 2 on building up more complex meshes from primitive geometries and thinking in 3D.

--

--