WebGL With Three.js: Textures & Particles

Since its introduction, 3D graphics in the browser has been a popular topic. But if you were to create your apps using plain old WebGL it would take a very long. But now we have some pretty useful libraries that we can take advantage of, like Three.js. So in this series I will show you how to create stunning 3D experiences for the browser.

I do expect you to have a basic understanding of 3D space before you start reading this tutorial, as I won't be explaining things like coordinates, vectors etc.

Preparation

We will start with the code from previous part of this series. Also, grab the assets I provided and put them in the same folder as your app. Now, since we will use images here you will have to put your app on some static server (may be local), because unless you start the browser with enabled file access from files (for example using the --allow-file-access-from-files flag in Chrome) CORS will not let you load them from file. That's all you need to do before proceeding.

Step 1: Loading the Texture

If you've ever got so bored that you went with creating something using pure OpenGL, you probably remember how much pain it is to load a texture. Luckily, Three.js comes with a nice function that will load and set up the texture for us. Add this line before the definition of our cube's material:

var cubeTexture = THREE.ImageUtils.loadTexture('./box.png');

It's really all you have to do in order to have your texture loaded.

In a real-world app you would have to preload the texture like any normal image and show the users some fancy loading bar to let them know that you are loading (Three.js will use the cached image then).

Step 2: Painting the Cube

Now we will apply the texture to our cube. This is also easy, you just need to replace the color definition in the cube's material to look like this:

This way you can have multiple different objects with the same texture if only the color changes.

Step 3: Multiple Materials

You can set different materials for every face of the cube. To achieve that, you have to change the whole material's definition. First, define the materials array. Each element in the array will correspond to the material of one face. They go in this order: right, left, top, bottom, front and back:

As you can see each face has it's own material, so you can set different textures, colors and other attributes for each one. Next, change the type of the cube's material to THREE.MeshFaceMaterial:

var cubeMaterial = new THREE.MeshFaceMaterial(materials);

You only need to pass the materials array as the parameter. In the browser you should see that each side of the cube has different color:

Step 4: Particles!

Let's say you want to create an effect of spinning snowflakes in your app. If you were to render each snowflake as a mesh you will get very low fps. That's where particles come into play. They are way less complicated, and drawing them as a whole particle system makes them really efficient.

Start with creating a geometry for our particles:

var particles = new THREE.Geometry;

THREE.Geometry is a base geometry object, without any shape. Now we have to define the position of each particle in the system. Let it be completely random:

Notice that we are using THREE.ParticleBasicMaterial, which is only for particles. In options we only define the color and the size of each particle. Finally, you can create the particle system and add it to the scene:

In material definition, there is a blending option. It tells the renderer how it should render one object on another. With THREE.AdditiveBlending overlapping color values will be added to each other which will result in a brighter smoke in the areas with higher particle density. We also set the color to almost black, so the smoke looks more natural.

Finally, create the particle system, move it a bit to the left and add it to the scene:

In the loop we are adding delta * 50 to the y position of the particle. Next we check if the particle is higher than 230, if so we randomly choose its new position somewhere in the bottom of the smoke pillar. Finally, the most important thing: setting the geometry's __dirtyVertices flag to true.

To improve the performance, Three.js is caching the objects to avoid building all of the WebGL calls again every frame, so if we change something in the geometry of the object we have to let the renderer know that it has changed. Basically, the __dirtyVertices flag will just reach the element.

If you open the browser now you should see a smoothly animated smoke next to the cube.

Conclusion

In this tutorial you've learned how to use textures and particles. As before, don't be afraid to experiment a bit with your app. If you have problems take a look at the documentation. In the next article I will teach you how to load models and animate them.

I am a programmer from Poland. I started programming when I was about eight years old, and I have learned many programming languages since then (including Assembler, Basic, C, C#, Delphi, Java, JavaScript and many more). I fell in love with JavaScript from the first sight, and this one became my passion — I am developing both front-end and back-end solutions with it, including desktop software. I also enjoy writing some Delphi application or game from time to time.