Sep 23, 2014
Creating 3D Cube: A Practical Guide to Three.js with Live Demo
Have you ever created a 3D object using JavaScript? Of course, you might have done. But creating 3D with pure JavaScript requires a large amount of code, and that’s where Three.js shows its magic. With Three.js, you can build 3D environments in your browser with a very low level of complexity.
This tutorial is written with the intention of making you exposed to the power of Three.js. In this tutorial, I’ve covered:
- 1. What is Three.js?
- 2. Key Features of Three.js
- 3. Browser Compatibility
- 4. Getting Started With Three.js
In "Getting Started with Three.js" section, I’ve explained how to make a rotating 3D cube with live working code and demo, so you could understand how Three.js actually works. Hopefully, this tutorial will help you a lot especially if you’re new to 3D world.
Let’s start understanding Three.js!
What is Three.js?
Three.js is an open source and lightweight JavaScript 3D library that allows you to create and display animated, interactive 3D computer graphics on any compatible web browser without having to rely on proprietary browser plug-ins. While a simple cube in raw WebGL turns out hundreds of lines of Shader and JavaScript code, a Three.js equivalent is only a part of that.
Three.js runs in all WebGL supported browsers and enables you create GPU-accelerated 3D animations by making use of JavaScript as part of a website. With Three.js, you’ll be able to easily create objects, cameras, materials, lights, and much more. Best of all, you can use Three.js scripts in conjunction with the HTML5 canvas, SVG, CSS3D or WebGL.
Key Features of Three.js
Three.js has the following features:
- Renderers: <canvas>, <svg>, WebGL, CSS3D, DOM, Software; effects: stereo, crosseyed, anaglyph, and more.
- Scenes: Add/remove objects at run-time; linear and exponential fog.
- Cameras: Orthographic and perspective; controllers: FPS, trackball, path and more.
- Animation: Keyframe and morph.
- Lights: Hemisphere, directional, area, ambient, spot and point lights; shadows: cast and receive.
- Materials: Phong, face, depth, lambert and more - all with smooth-shading, texture, shininess and more.
- Shaders: Access to full GLSL capabilities: depth pass, lens flare, and comprehensive post-processing library.
- Objects: Bones, lines, meshes, sprites, particles, ribbons, and more.
- Geometry: Cylinder, cube, plane, torus, sphere, ring, 3D text and more; modifiers: extrude, lathe and tube.
- Loaders: Image, JSON, binary, XHR, scene and more.
- Utilities: Full set of time and 3D math functions that includes quaternion, frustum, triangle, matrix, ray and many more.
- Export/Import: 3D Max, CTM, Blender, OBJ, and FBX.
- Examples: 150+ files of coding examples plus textures, models, sounds, fonts, and other support files.
- Debugging: Three.js Inspector, WebGL Inspector, and Stats.js.
- Support: API documentation, public forum and wiki.
Browser Compatibility
Unfortunately, 3D animations are not supported by all browsers. Currently, we’re restricted to Google Chrome, Mozilla Firefox, Safari and Opera, while Internet Explorer 11 has partial WebGL support. In latest versions of Chrome and Firefox, WebGL support is enabled by default. As time goes by, hopefully full support on Internet Explorer will pick up in future.
In my experience, Chrome is the best browser to work with because its underlying JavaScript engine is blazingly fast and it supports WebGL, Canvas, and SVG. Firefox is my second choice as its JavaScript engine is little slower than Chrome’s, but even it’s a great browser in terms of which render technologies are supported. In addition, it’s getting faster with each new version.
Getting Started With Three.js
Before You Start:
In order to use Three.js, you need to reference its latest version in your HTML document.
Head over to the official three.js website. Then, download the latest version of Three.js and include it in your HTML like you would any other JS file.
<html>
<head>
<title>My first Three.js app</title>
<style>canvas { width: 100%; height: 100% }</style>
</head>
<body>
<script src="js/three.min.js"></script>
<script>
// Our Javascript will go here.
</script>
</body>
</html>
That's all. All the code we’re going to create will go into the empty <script> tag.
Creating the Scene:
To display anything with Three.js, you’re required to create three things: A scene, a camera and a renderer.
Doing so, you’ll be able to render the scene with camera. Let’s start with a scene:
var scene = new THREE.Scene();
After setting up the scene, you’ve to create a camera. Consider it as the viewpoint that users are looking from.
var camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight, 1,10000);
Let me explain what’s going on here. Three.js has a few different cameras, but in order to keep the code simple, I’ve used a PerspectiveCamera.
In the above code, there are four attributes: the first is the vertical field of view (from bottom to top) in degrees. The second one is the aspect ratio where the height of the element divides the width. The next is the near clipping plane, and the last is the far clipping plane. The near and far attributes control the rendering of objects. That means the object that is too far or too close to the camera won't be rendered.
After creating the camera, now I’m going to set up the WebGLRenderer. In addition to the WebGLRenderer, Three.js has some other renderers - like CanvasRenderer – which can be used as fallbacks for users whose browsers don’t support WebGL for some reason.
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
As you can see, in addition to creating an instance of the renderer, we also have to set the size at which we want the renderer to display our app. In this case, I’ve used the width and height of the browser window. Finally, I’ve added the renderer element to the HTML page. This is a <canvas> element used by the renderer to draw the scene.
Creating the 3D Cube:
After setting up the stage, now I’m going to create a 3D cube. For creating a cube, we need to use the BoxGeometry object that contains all the vertices and faces of the cube.
var geometry = new THREE.BoxGeometry(700, 700, 700, 10, 10, 10);
This method takes five constructor parameters: the first is the width of the sides of the cube on the X axis, the second is height of sides of the cube on the Y axis, and the third is the depth of the sides of the cube on Z axis. The last three optional parameters, whose default value is 1, are the number of segmented faces along the width, height, and depth of the sides respectively.
I’ve set up the geometry of the cube, now we need to color it using a material. Three.js comes with numerous materials, but I’m using the MeshBasicMaterial here.
var material = new THREE.MeshBasicMaterial({color: 0xfffff, wireframe: true});
For simplicity’s sake, I’ve only supplied a color attribute of 0xfffff that is blue. I’ve also set wireframe to true, so you could see the animating cube more clearly. The next thing we need is a Mesh.
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
In the above code, the mesh object takes two parameters: the first is the geometry and the second is a material applied to it. Finally, I’ve added the cube to the scene.
By default, when we call function scene.add(), it adds the cube to the to the coordinates (0,0,0). This causes both the cube and the camera to be inside each other. To avoid this situation, we need to set the camera position before rendering the scene.
camera.position.z = 1000;
As you can see, whatever code we’ve written above is extremely simple, that’s because Three.js keeps you away from all the complex stuff.
Rendering the Scene:
If you paste the above code into the HTML file (which I created in the first step of this tutorial), and test it in the browser, you’ll see nothing. That’s because we haven’t actually told the scene to render anything yet. To render the scene, we need a render loop.
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
render();
This code creates a loop that instructs the renderer to draw the scene. Here, you may get confused why didn’t I just use setInterval? That’s because using requestAnimationFrame instead of setInterval is beneficial in many ways. Most importantly, it pauses when a user moves to another tab in the browser, hence saving their precious resources.
Animating the Cube:
If you test the file in your browser, now you’ll see a blue box without any animation. Let's make it more exciting by rotating it. Just add the following right below the requestAnimationFrame(render) in the render function. This will run every frame and add a nice rotation animation to the cube.
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
The Result:
Congratulations! You have successfully built your first Three.js app. Here is the full code:
<html>
<head>
<title>My first Three.js app</title>
<style>canvas { width: 100%; height: 100% }</style>
</head>
<body>
<script src="js/three.min.js"></script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 1, 10000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.BoxGeometry(700, 700, 700, 10, 10, 10);
var material = new THREE.MeshBasicMaterial({color: 0xfffff, wireframe: true});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 1000;
function render() {
requestAnimationFrame(render);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
};
render();
</script>
</body>
</html>
Conclusion:
Now you can see a properly animating 3D cube in your browser. Watch the live demo of above code. You can play around with it to better understand how it works.
As you can see, this amazing JavaScript library doesn’t require you to be a highly-skilled JS developer. Anyone who has the basic working knowledge JavaScript can get started with it in minutes.
Enjoyed this post? Share your knowledge with these questions:
Have you created any 3D object using Three.js?
Do you know any other JavaScript 3D Library?
What you think about the future of Three.js?