Some WebGL experiments where the viewer seemingly travels through a textured tunnel. Powered by Three.js and inspired by the effect seen on fornasetti.com.

Since WebGL is getting more and more popular, we start to see a bunch of websites using it for amazing creative designs. The brand Fornasetti recently published their website using the power of WebGL for a very nice effect: an animation that let’s us seemingly travel through a tunnel with a changing pattern. The most interesting part of this experience is that the motion through the tunnel is controlled by the movement of the mouse. Today we’ll share some similar Three.js powered tunnel traveling experiments with you.

Attention: You will need a recent browser that supports WebGL (> IE10) in order to see the demos.

Screenshot of Fornasetti‘s website.



Getting Started

For this demo we are using Three.js which is a useful library to create WebGL without getting your hands dirty. Before generating the tube we first need to setup a scene with a renderer, a camera and an empty scene.

If you don’t feel comfortable using Three.js, I suggest you to first read a tutorial to get started with it. Rachel Smith wrote a good one in three parts over here.

Once we have our scene ready we will proceed with these steps:

The curve

Thanks to Three.js we have a useful function that allows us to create a curve based on a set of points. We first need to calculate the positions of those points. Once it’s done we can create our curve like this:

// Create an empty array to stores the points var points = []; // Define points along Z axis for (var i = 0; i < 5; i += 1) { points.push(new THREE.Vector3(0, 0, 2.5 * (i / 4))); } // Create a curve based on the points var curve = new THREE.CatmullRomCurve3(points)

This curve will be updated later to modify the shape of the tube in real time. As you can see, all the points have the same X and Y positions. At the moment, the curve is a single straight line.

The tube

Now that we have a curve (that is not curved at all) we can create a tube using Three.js. To do so we need three parts: a geometry (the shape of the tube), a material (how it looks) and finally a mesh (the combination of the geometry and the material):

// Create the geometry of the tube based on the curve // The other values are respectively : // 70 : the number of segments along the tube // 0.02 : its radius (yeah it's a tiny tube) // 50 : the number of segments that make up the cross-section // false : a value to set if the tube is closed or not var tubeGeometry = new THREE.TubeGeometry(this.curve, 70, 0.02, 50, false); // Define a material for the tube with a jpg as texture instead of plain color var tubeMaterial = new THREE.MeshStandardMaterial({ side: THREE.BackSide, // Since the camera will be inside the tube we need to reverse the faces map: rockPattern // rockPattern is a texture previously loaded }); // Repeat the pattern to prevent the texture being stretched tubeMaterial.map.wrapS = THREE.RepeatWrapping; tubeMaterial.map.wrapT = THREE.RepeatWrapping; tubeMaterial.map.repeat.set(30, 6); // Create a mesh based on tubeGeometry and tubeMaterial var tube = new THREE.Mesh(tubeGeometry, tubeMaterial); // Add the tube into the scene scene.add(this.tubeMesh);

Move the tube forward

This part is my favorite because to my surprise the animation did not work as I believed initially. I first thought that the tube was actually moving into the direction of the camera. Then, I suggested that the camera was moving inside the tube. But both ideas were wrong!

The actual solution is really clever: nothing is “physically” moving forward in the scene beside the texture that is translated along the tube.

To do so, we need to define an offset for the texture on every frame to create the illusion of motion.

function updateMaterialOffset() { // Update the offset of the material with the defined speed tubeMaterial.map.offset.x += speed; };

User interactions

The demo wouldn’t be that good if we didn’t implement some user interaction. When you move your mouse in the browser you can control the shape of the tube. The trick here is to update the points of the curve we created in the first step. Once the curve has been changed, we can update the tube accordingly with some transition.

// Update the third point of the curve in X and Y axis curve.points[2].x = -mouse.position.x * 0.1; curve.points[2].y = mouse.position.y * 0.1; // Update the X position of the last point curve.points[4].x = -mouse.position.x * 0.1;

That’s it?

Well, sadly no, the code is a bit more complex than what I’ve explained in this article. But if you understood the steps above, you should have a global idea of how the demo works. If you want to understand even more, check the source code of the first demo; I’ve included a lot of comments. If you still have questions, do not hesitate to poke me on Twitter 🙂

The demos

Once you have a basic tube, you can improve it with many different options. Check out all the demos to give you some ideas!

The demo with the brick pattern we’ve introduced above.



Press your mouse down (or touch your screen) to release a rainbow of new particles!



This demo is inspired by all the sci-fi movies with some time travel effect.



Dive inside your body and explore a blood vessel 🙂



Why should all tubes be round? This time we are traveling through a triangular one.



Try this demo on your phone or your tablet to control the tube with your device orientation!



Thank you for reading this article!

If you are excited by the demos in this article, please share your joy in the comments 🙂

References and Credits