Three.js 1 - Getting Started

Three.js - 1 - Getting Started





After Apple's war on Flash, relying on plugins in your web pages is just not a viable option. Flash (and maybe, thanks to Netflix, Silverlight) were the last of a dying breed of browser plugins. In their place are a host of new technologies being standardised as part of HTML5.

WebGL is one of these technologies, and is supported by all major browsers. Microsoft is even getting on board with IE 11. Combine that with the ever increasing performance of JavaScript engines and it is now possible to create some impressive 3D applications in a web browser without the aid of plugins.

Three.js is one of the more powerful and mature JavaScript 3D engines available. This article will show you how to get a simple 3D application running with three.js.

What to download

Using three.js requires only a single JavaScript file called three.min.js. You can grab the latest version of file from GitHub.

The HTML page

A three.js application is a DOM element that can be appended as a child of an element in your HTML page. This means that you can embed a 3D application in a web page like it was an image or video file. This gives you a great deal of flexibility when presenting your 3D application.

However, for this example we will create a very basic HTML page and add the three.js application as the only child. While basic, this configuration is quite suitable for full screen games or simulations.

As you can see, this is a very simple HTML page. The only code of importance here are the referenced to the two JavaScript files: the three.js library (three.min.js), and the JavaScript file that will hold our application (threejs-1.js).

  <title>Three.js - 1 - Getting Started</title>
  <script type="application/javascript" src="javascript/three.min.js"></script>
  <script type="application/javascript" src="javascript/threejs-1.js"></script>

The Components of a 3D Application

There are 4 important classes in three.js that make up a basic 3D application: the camera, the scene, the meshes, the geometries and the materials.

The Camera

This is exactly what it sounds like. The 3D world created by three.js is viewed as if through the lens of a video camera. In fact the camera has methods like .setLens() to set properties like focal length and frame size, which relate to a camera's field of view.

The Scene

The scene is the world that you will populate with 3D objects, lights and cameras.

The Meshes

A mesh defines the individual charictaristics  of a 3D object. These include things like the position, rotation and scale of the object. A mesh will reference a geometry to define the shape of the 3D object, and a material to define the appearance of the 3D object.

What is important to note about a mesh is that they can share geometries and materials. For example, to render a forest with a thousand 3D trees, you would need a thousand meshes, but potentially only 3 or 4 geometries (to represent the different types of trees) and 1 material.

The Geometries

The shape of a 3D object is defined by a geometry. Geometries define the various vertices and faces that make up a 3D model. Simple applications can make use of the build in geometry classes that describe a sphere, cube, cylinder and other common shapes. More complex 3D applications will load geometries created in 3D modelling applications.

The Materials

While a geometry defines the shape of a 3D object, the material defines the appearance. Materials can be a simple as a plain colour, or they can be complex shaders with reflections or animated appearances.

Putting it all Together

We start by assigning a function to the window.onload event. This is good practice when writing any JavaScript that manipulates the HTML DOM, as it is possible to start playing with the DOM before it is completely loaded. If you use jQuery, the ready() function is even better as it will allow your code to manipulate the DOM without having to wait for images to download. Since our page has no images, and we are not using jQuery, the window.onload event will work just fine.

The function assigned to the window.onload event will call two additional functions: init() and animate().

window.onload = function(){

The init() function is where we setup the components that make up the 3D application.

We create the camera, which is an instance of the PerspectiveCamera class. The 4 parameters supplied to the constructor are

fov - Camera frustum vertical field of view.
aspect - Camera frustum aspect ratio.
near - Camera frustum near plane.
far - Camera frustum far plane.
We then set the position of the camera down the z axis. This will allow us to position a 3D object at the origin and be able to view it.

camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
 camera.position.z = 1000;    

Next we create some geometry. Three.js provides a number of geometry classes that define a number of common shapes. Here we use the CubeGeometry class to create the geometry for a cube. The supplied parameters define the size of the cube along the three axes.

 geometry = new THREE.CubeGeometry( 200, 200, 200 );   

In order for the 3D object to be visible, it needs a material. The MeshBasicMaterial class allows us to create a simple material without the use of any external image files. The MeshBasicMaterial constructor takes an object whose properties define the appearance of the material. In this case we have set the colour to red, and specified that the material should display as a wireframe.

 material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );  

The mesh uses the geometry and material to create the 3D object that we will see on the screen.

mesh = new THREE.Mesh( geometry, material );   

Now that we have a 3D object to view, we need to create the scene that will hold it. The mesh is then added to the scene.

 scene = new THREE.Scene();
 scene.add( mesh );

Three.js can use a number of technologies to draw the 3D application within the browser. Each is provided by a renderer class. These different renderers are provided because not all browsers support all the HTML technologies that are available to libraries like three.js. For example, Internet Explorer won't support WebGL until version 11.

We have used the WebGL renderer here. This code will fail if it is run on any version of IE before 11, and future tutorials will provide workarounds for older browsers. For now though make sure you run the demo on Firefox or Chrome.

Because our application will take up the full browser window, we set the size of the renderer to the size of the browser window.

 renderer = new THREE.WebGLRenderer();
 renderer.setSize( window.innerWidth, window.innerHeight );   

The final step is to attach the renderer to the HTML DOM. In this case the renderer is attached directly as a child of the HTML body.

 document.body.appendChild( renderer.domElement );   

At this point we have created all the objects required by the 3D application. The next step is to animate the scene.

Just like a flip book, animation of 3D applications quickly taking snapshots of the 3D objects and displaying the snapshots on the screen.

HTML pages used to be fairly static, and only updated in response to some kind of user interaction (like clicking a button or submitting a form). This model doesn't work well for applications like the one we are creating, which expect to be able to update the browser page with each frame, independently of any explicit user interaction.

Modern browsers support this kind of application through the requestAnimationFrame function. This function takes another function as a parameter, and will call the supplied function when the browser page is available to be refreshed. The requestAnimationFrame function is not supported by all browsers, but three.js includes a shim (or workaround) for older browsers, saving us from having to deal with these incompatibilities.

So the animate() function is first called when the window is loaded, and is then scheduled to be recursively called each time we render a frame.

 requestAnimationFrame( animate );   

So we have something to look at, the cube is rotated slightly with each frame.

 mesh.rotation.x += 0.01;
 mesh.rotation.y += 0.02;  

Finally, the renderer takes the scene and the camera, and renderers the current frame to the screen.

 renderer.render( scene, camera );  

Final Words

The end result of this tutorial has been to display a single spinning 3D cube in a web page. While this is quite a trivial example of the three.js library, it does cover all the basic elements of a 3D application, and provides a useful starting point for building more complex 3D applications.
Post a Comment

Popular posts from this blog

Fixing OpenVPN "Authenticate/Decrypt packet error: cipher final failed"

MinHash for dummies

Exporting from MySQL to H2