From our sponsor: Ready to show your plugin skills? Enter the Penpot Plugins Contest (Nov 15-Dec 15) to win cash prizes!
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.
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:
- Create a curve to determine the shape of the tube
- Generate the tube based on the curve
- Move everything forward
- Add some user interactions
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;
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
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!
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
- Official Three.js website
- Brick texture from maxTextures
- Perlin noise algorithm was written by Seph Gentle
- Last vector pattern from Freepik.com
- Blood cell model from Turbosquid
Pretty good ! Thank for the tutorial. The demo with particles is closest to the Intergalactic Mission website (https://thefwa.com/cases/valerian-intergalactic-mission). It’s very impressive.
wow! Thanks for sharing!
Awesome!!!!!
Thank you!
Loved the Star Wars theme! Can I make a suggestion? If you could integrate the Gyroscope API to this, you’d make a killer VR demo.
https://whatwebcando.today/accelerometer.html
Did you try the last demo ? You can control it with your gyroscope 🙂
The VR demo would be awesome ! Maybe a future demo…
Wow amazing. The power of WebGL and creativity.
Boy, you sure do like tunnels Louis! 😀 Love these and your CodePen posts too. Great work all around.
I think I just got high watching the demos… WTF
It is fucking awesome!
amazing!!!
Hey, I saw that you mentioned a VR mode would be awesome and I was really interested to see how trippy it was. I modified some of the code to duplicate the canvas across the screen. Works nicely on a mobile VR headset although look navigation is a bit buggy, check it out! https://umpox.github.io/tubeVR/index6.html
Just awesome…Especially Particles & Bloodcells. Thank for sharing. What a visual stuff. Great job.
Hello guys, I just found out. If you let the ” triangle ” tube for like 5 mins running it crashes.
Anyone knows why?
Nice writeup! Fornasetti site is by http://www.cartelle.nl btw 🙂
Woooooooooooow +200 respect. First thought which came up in my mind… Use the StarWars Wormhole Tube to navigate from page to page with VR Glasses glued onto your head would be just sooo freakin’ awesome xD!!
Absolutely Beautiful.
awesome
amazing work ….
can u please tell me how can i change Triangle color theme ?