WEBGL AND THREE.JS INTRO PART 2

This is a series of tutorials on WebGL using the three.js library – you may also be interested in Part 1 

In my previous post we discussed the history of WebGL and looked at a number of libraries to make working with WebGL as easy as possible.

We will be working with the three.js library so the first thing you will want to do is head over to http://threejs.org/ and download the latest version of three.js.

There is a little download link on the left hand side of the page you want to click on to which will give you a zip file containing the latest three.js library and a heap of examples.

Let me start by saying that Three.js is an awesome project, it has a team of very active developers, a big community and some great examples – there is a big but coming however..

Image

Three.js’s documentation sucks. Really sucks – in fact it sucks more than White house down which is the worst movie I have seen this year. I’d love to help the three.js guys fix up the documentation but just don’t have enough knowledge to assist in this area yet so will just whinge (and warn you) about it right now..

It is worth mentioning that three.js does have an enormous number of examples available which is arguably better than documentation anyway. However I found that its not that obvious how some of them work as there is little in the way of explanation of some of the maths involved. This coupled with bad documentation can make for a frustrating process of trial and error to work out how to use the various features. I found a collection of some more readable examples at http://stemkoski.github.io/Three.js that you may want to check out.

So before we get any further I want to save you a lot of time & effort & recommend a book to you – Chris Storm’s 3D programming for kids.

Don’t worry I wont tell anyone you downloaded a programming book aimed at kids (I do have my doubts how many 10 year old’s will cope with matrix projections but I digress..).

Don’t let the title put you off – this is by far the best introduction I have read of three.js and contains a number of very useful examples that will save you heaps of time working out how to do common tasks such as animating a group of objects, move a character around & collision detection. This book also has a very readable explanation of some of the maths involved in 3D programming – its also apparently used as a university text in an introduction to 3D programming course so don’t feel too bad..

In our first example we will draw a wire frame sphere on the screen.

Why? – well why not and we’re not going to be coding GTA V in our first example.

The end product will look like this:

Image

Start off by creating a new html page – note you don’t need jQuery but it will save some typing later on:

<!DOCTYPE html>
<html>
<head>
<title>Hello three.js</title>
</head>
<body>

<script src="three.js"></script>
<script src="jquery-2.0.2.js"></script>
<script src="helloExample.js"></script>

</body>

</html>

Now create a JavaScript file called helloExample.js and add the following code:

(function() {

"use strict";

var camera,
scene = new THREE.Scene(),
renderer = new THREE.WebGLRenderer(),
aspect = window.innerWidth / window.innerHeight,
container,
light,
sphere,
sphereMaterial;
camera = new THREE.PerspectiveCamera(75, aspect, 1, 1000);

camera.position.z = 300;
scene.add(camera);

light = new THREE.PointLight(0xFFFFFF, 1);
light.position.set(0, 0, 200);
scene.add(light);

sphereMaterial = new THREE.MeshBasicMaterial({
color: 0x000000,
wireframe: true,
wireframeLinewidth: 2

});

sphere = new THREE.Mesh(new THREE.SphereGeometry(100, 16, 16), sphereMaterial);
scene.add(sphere);

container = document.createElement('div');
container.id = "container";
document.body.appendChild(container);
container.appendChild(renderer.domElement);

renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);

})();

So what’s going on here?

Well before we run through the code let’s recap on how coordinates work. We will need a way of telling three.js where we want objects on the screen.

Three.js’s coordinate system looks like this:

coordinates

So there are 3 axis’s that allow you to position objects on the scene. Three.js also contains some scale methods to make working with different size objects easy that we will use later on.

I think this is fairly straight forward & familiar to most programmers but dont worry this will quickly become complex later on when we want to point the camera at a specific object for example 🙂

OK now we have this foundation stuff out the way let’s look at the code.

First up we create and initialize a number of objects we will make use of later:

var camera,
scene = new THREE.Scene(),
renderer = new THREE.WebGLRenderer(),
aspect = window.innerWidth / window.innerHeight,
container,
light,
sphere,
sphereMaterial;

We then create a new PerspectiveCamera (there is also another type of camera called OrphographicCamera which doesn’t render perspective but don’t worry about that for now) that tells three.js where we are looking at:

camera = new THREE.PerspectiveCamera(75, aspect, 1, 1000);

The first parameter (75) refers to the vertical field of view of the camera (FOV), the second represents the aspect ratio of the screen and the 3rd and 4th parameter tell three.js we want to see objects between 1 and 1000 z position – this can be important for performance (why render stuff really far away?) and certain effects. Hmm wtf does all that mean? Well Jeff Atwood (coding horror) has a good diagram & explanation of FOV & aspect ratios that you should check out.

Next up we move our camera nearer to us (e.g. back) by changing the z position. We then add it to our scene:

camera.position.z = 300;
scene.add(camera);

It’s important with three.js to remember to add a light to a scene otherwise we won’t see anything so lets do that:

light = new THREE.PointLight(0xFFFFFF, 1);
light.position.set(0, 0, 200);
scene.add(light);

There are a number of other types of lights and you can also play with the colors to create some great effects.

Next up we create a material (kind of what we will paint our object with).

In this example we will indicate that we  want a wire frame version of the object as we are hipster like that:

sphereMaterial = new THREE.MeshBasicMaterial({
color: 0x000000,
wireframe: true,
wireframeLinewidth: 2
});

Now up lets create our sphere by creating a mesh (think of meshes as a scaffold for the object based on a collection of x,y & z points – called Vertices in 3D speak) based on one of three.js’s primitives – SphereGeometry:

sphere = new THREE.Mesh(new THREE.SphereGeometry(100, 16, 16), sphereMaterial);
scene.add(sphere);

The 100 specifies the size of the object and the 16’s how many parts or segments make up the sphere – more parts = smoother sphere but potentially more memory to store object & slower to render.

Finally we need a way of getting this onto the page itself so lets create a div & append our renderer we created earlier to it:

container = document.createElement('div');
container.id = "container";
document.body.appendChild(container);
container.appendChild(renderer.domElement);
renderer.setSize(window.innerWidth, window.innerHeight);

This will all get rendered in a canvas element that three.js will create for us inside the container div.

Finally we need to tell three.js we want to render our content:

renderer.render(scene, camera);

And we are done!

Although there is a fair bit of code most of its around setup and you will need something similar each time so you will quickly get used to it.

Next time we will look at animation!

Advertisements

One thought on “WEBGL AND THREE.JS INTRO PART 2

  1. Very cool information!I am also interested in threejs and i can totally agree with you about the awful documentation. Hope you continue your updates!

Comments are closed.