— for the impatient : a rotating cube —
We would like to make simple 3D applications that can be executed in a browser. The preferred way to do this in 2013 (that is, without resorting to things such as Flash or Java applets) is to use JavaScript and WebGL. The latter being a somewhat low-level API, we will use one of the many WebGL frameworks available so we don't waste our time on trivialities. There doesn't seem to be a preferred JavaScript 3D library yet, so the choice of a particular one is difficult (StackOverflow has plenty of questions about the choice of a WebGL framework). Here are a few that seem popular at the time of writing :
So what will follow is a brief tutorial on how to use Three.js to make small 3D applications. This tutorial is meant to cover only the very basics, just enough to do interesting things later.
The first thing we have to do is to download the Three.js file and link it as an external JavaScript file in our HTML code the usual way. We do the same for the TrackballControls.js file, which will provide a simple way to navigate around the 3D scene using the mouse (so we don't have to implement this part ourselves). Our HTML file should look something like this :
<html> <body> <script src="./path/to/Three.js"></script> <script src="./path/to/TrackballControls.js"></script> <script> // JavaScript code, coming soon </script> </body> </html>
That is all we need as long as HTML is concerned. Coming now is some example JavaScript code for a minimal toy application. The code is heavily commented in order to be self-explanatory.
// create a new application var renderer = new THREE.WebGLRenderer(); // we want it fullscreen renderer.setSize( window.innerWidth, window.innerHeight ); // put the application at the end of the <body> element document.body.appendChild( renderer.domElement ); // create the camera var camera = new THREE.PerspectiveCamera( 45, // field of view window.innerWidth / window.innerHeight, // aspect ratio 0.01, // near plane 1000 // far plane ); // the camera by default is at (0,0,0), // so we put it a bit further away from the origin camera.position.set( 0, 0, 10 ); // mouse controls (needs TrackballControls.js) var controls = new THREE.TrackballControls( camera ); // create the scene containing the models to be displayed var scene = new THREE.Scene(); // create a cube and add it to the scene var cube = new THREE.Mesh( new THREE.CubeGeometry( 1, 1, 1 ), new THREE.MeshBasicMaterial( { wireframe: true } ) ); scene.add( cube ); // create an axis helper and add it to the scene scene.add( new THREE.AxisHelper() ); // main loop function animate() { // the function must be called every frame requestAnimationFrame( animate ); // update the controls controls.update(); // rotate the cube a little bit cube.rotation.x += 0.01; cube.rotation.y += 0.01; // render the scene renderer.render( scene, camera ); }; // launch the animation animate();
That is all ! What this code does is displaying a rotating wire-frame model of a 3D cube, along with an axis helper (red-green-blue segments for the x-y-z axis), and it is possible to navigate around this scene using the mouse (left-click to rotate, right-click to pan, and wheel to zoom). Check app1.html to see it in action.
A few more things to know for using Three.js :
animate
, is in charge of what needs to be done at every frame,
e.g. rendering the objects on the canvas, or maybe updating the orientation or position of some object
if we want it to be rotating or moving (like the cube in our example).
THREE.Object3D
,
the base class for most 3D objects.
When 3D models are created using constructors like
THREE.Mesh(
geometry,
material )
or THREE.Line
,
it is subclasses of THREE.Object3D
that are returned.
It is also possible of
subclassing
the THREE.Object3D
class, or a subclass of it, to make our own 3D objects constructors.
A simple example of this can be seen by looking at the code for the
THREE.AxisHelper
constructor.
THREE.Object3D
are :
.position
is the 3D vector specifying the position of the object.
.rotation
is the 3D vector specifying the orientation of the object,
in Euler angles.
.scale
is the 3D vector specifying the x-y-z scaling of the object.
THREE.Object3D
is .children
, which is an array containing other instances
of THREE.Object3D
. An object can be added or removed to this array using the .add(object)
and .remove(object)
methods. This way, an instance of THREE.Object3D
can be used
as a container for smaller, individually articulated objects, which is what we will do later when implementing a
"polygonal chain" class.
I think this should be enough for introducing Three.js. For more help with using the library, the reader is advised to look at the wiki, the documentation, the many examples on GitHub, the relevant tag on StackOverflow, and so on. Please note that Three.js is still in constant development, so the documentation isn't always up-to-date and features can appear or disappear from one version to the next. Because of this, in order to understand better how to use it it is often useful to not only rely on docs and tutorials but to also take a look at the Three.js source code.