This post presents a tunnel effect. This is a classic in 3D demo. They are visually efficient and easy to code. In fact, tunnels are so trendy that even doctor who and stargate have fun in them :)

Try the demo. It has been built using the boilerplate for three.js seen in a previous post. The code is simple and small. Less than 20lines has been added on top of the boilerplate. We will create a THREE.Geometry to get the shape of tunnel. Then we will use a texture trick to create the visual illusion of moving.

Let’s build the walls

The first step is to build the walls of the tunnel. It is easier that one would expect. A tunnel may be seen as a cylinder with the camera inside. Once you realized that, most of the work is done. Luckily for us, three.js got an easy way to build cylinders, called CylinderGeometry. Nevertheless our tunnel / cylinder got 2 special points.

First, it is open-ended. So we must not build its top and bottom. We need this to see thru its extremities. This is handled by a parameter in CylinderGeometry. We just set openended parameter to true and the rest is done for us :)

Second, the camera is usually located outside of objects. But our tunnel/cylinder has the camera inside it. To make our object visible from the inside, we need to turn it inside out. For that, just use mesh.flipSided = true

Let’s go forward

Now we need to go forward in this tunnel For that we will use an old trick. We won’t move the tunnel walls themselves, only their appearance. It gives the visual illusion that we are moving. Remember what they say in matrix ? “there is no spoon”. It is all the same, we are moving while staying still :)

A Texture isn’t a spoon

First we want to move the appearance of the cylinder, thus the player got the illusion to go forward. We will use THREE.Texture for that. We wont move the actual pixels of the textures, only its coordinates. Additionnaly we want the texture to repeat on the cylinder, thus it appears as continuous. WebGL texture is a powerfull and flexible tool. You can tweak so many features.

First let’s make this texture move. Suppose we want the texture to loop once every 10 seconds. So the coordinate .offset.y needs to go from 0 to 1 in 10 seconds. This line is enougth to make the tunnel move forward. You can change your speed within the tunnel by changing this number.

1 texture . offset . y += 0.1 * seconds ;

Now the texture repetition. For that we will use a texture parameter called wrap. It indicates how the gpu repeat the texture on a face. Here is a good tutorial on opengl wrap. By default, wrapS / wrapT are set to THREE.ClampToEdgeWrapping . So the texture is scaled to match exactly the size of the face. In our case, we want to repeat the texture and not scale it. So we use THREE.RepeatWrapping .

1 texture . wrapT = THREE . RepeatWrapping ;

Conclusion

We have seen how to do a tunnel with three.js. This is very simple to code and awesome on the screen. It is less than 20 lines added to the boilerplate. The cylinder geometry was already provided. We used THREE.Texture offsets to provide the optical illusion of moving.

Later, we may add a blue phonebooth and play doctor who :) The code is available on github under MIT license. Feel free to fork and modify. That’s all folks, have fun.