I have used Three.js for some of my experiments, and it does a really great job of abstracting away the headaches of getting going with 3D in the browser. With it you can create cameras, objects, lights, materials and more, and you have a choice of renderer, which means you can decide if you want your scene to be drawn using HTML 5's canvas, WebGL or SVG. And since it's open source you could even get involved with the project. But right now I'll focus on what I've learned by playing with it as an engine, and talk you through some of the basics.
For all the awesomeness of Three.js, there can be times where you might struggle. Typically you will need to spend quite a large amount of time with the examples, reverse engineering and (in my case certainly) hunting down specific functionality and occasionally asking questions via GitHub. If you have to as questions, by the way, I've found Mr. doob and AlteredQualia are extremely helpful!
In our 3D world we will have some of the following, which I will guide you through the process of creating:
You can, of course, do some crazy things, and my hope is that you will go on to do that and start to experiment with 3D in your browser.
I'll assume you've chosen a browser that supports all the rendering technologies, and that you want to render with canvas or WebGL, since they're the more standard choices. Canvas is more widely supported than WebGL, but it's worth noting that WebGL runs on your graphics card's GPU, which means that your CPU can concentrate on other non-rendering tasks like any physics or user interaction you're trying to do.
So with that said, and on the assumption you have downloaded and included three.js in your HTML file, how do you go about setting up a scene? Like this:
So we have a scene, a camera and a renderer (I opted for a WebGL one in my sample code) but we have nothing to actually draw. Three.js actually comes with support for loading a few different standard file types, which is great if you are outputting models from Blender, Maya, Cinema4D or anything else. To keep things simple (this is about getting started after all!) I'll talk about primitives. Primitives are geometric meshes, relatively basic ones like Spheres, Planes, Cubes and Cylinders. Three.js lets you create these types of primitives easily:
Without doubt this is one of the most useful parts of Three.js. It provides for you a number of common (and very handy) materials to apply to your meshes:
There are more, but again in the interests of simplicity I'll let you discover those for yourself. In the case of WebGL particularly these materials can be a life-saver. Why? Well because in WebGL you have to write shaders for everything being rendered. Shaders are a huge topic in themselves, but in short they are written in GLSL (OpenGL Shader Language), which tells the GPU how something should look. This means you need to mimic the maths of lighting, reflection and so on. It can get very complicated very quickly. Thanks to Three.js you don't have to do this if you don't want to because it abstracts that away for you. If you want to write shaders, however, you can do that too with a MeshShaderMaterial, so it's a flexible setup.
For now, however, let's apply a lambert material to the sphere:
It's worth pointing out as well that there are other properties you can specify when you create a material besides the colour, such as smoothing or environment maps. You should check out the Wiki page for the various properties you can set on the materials and, in fact, any object that the engine provides for you.
If you were to render the scene right now you'd see a red circle. Even though we have a Lambert material applied there's no light in the scene so by default Three.js will revert to a full ambient light, which is the same as flat colouring. Let's fix that with a simple point of light:
We now actually have everything set up to render, remarkably. But we actually need to go ahead and do just that:
If you take time to look through the code for Three.js you'll see a lot of objects "inherit" from Object3D. This is a base object which contains some very useful properties, such as the position, rotation and scaleinformation. In particular our Sphere is a Mesh which inherits from Object3D, to which it adds its own properties: geometry andmaterials. Why do I mention these? Well it's unlikely you're going to want to just have a sphere on your screen that does nothing, and these properties are worth investigating as they allow you to manipulate the underlying details of the meshes and materials on the fly.
I just wanted to quickly point out a quick gotcha for Three.js, which is that if you modify, for example, the vertices of a mesh, you will notice in your render loop that nothing changes. Why? Well because Three.js (as far as I can tell) caches the data for a mesh as something of an optimisation. What you actually need to do is to flag to Three.js that something has changed so it can recalculate whatever it needs to. You do this with the following: