— 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.