A set of five demos with animated WebGL lines created with the THREE.MeshLine library. Find out how to animate and build these lines to create your own animations.

Two years ago, I started playing with lines in WebGL using THREE.MeshLine, a library made by Jaume Sanchez Elias for Three.js.

This library tackles the problem that **you cannot handle the width of your lines** with classic lines in Three.js. A MeshLine builds a strip of triangles billboarded to **create a custom geometry** instead of using the native WebGL GL_LINE method that does not support the width parameter.

These lines shaped as ribbons have a really interesting graphic style. They also have less vertices than a **TubeGeometry** usually used to create thick lines.

## Animate a MeshLine

The only thing missing is the ability to **animate lines without having to rebuild the geometry** for each frame.

Based on what had already been started and how SVG Line animation works, I added **three new parameters to MeshLineMaterial** to visualize animated dashed line directly through the shader.

**DashRatio:**The ratio between what is visible or not (`~0`

: more visible,`~1`

: less visible)**DashArray:**The length of a dash and its space (0 == no dash)**DashOffset:**The location where the first dash begins

Like with an SVG path, these parameters **allow you to animate the entire traced line** if they are correctly handled.

Here is a complete example of how to create and animate a MeshLine:

```
// Build an array of points
const segmentLength = 1;
const nbrOfPoints = 10;
const points = [];
for (let i = 0; i < nbrOfPoints; i++) {
points.push(i * segmentLength, 0, 0);
}
// Build the geometry
const line = new MeshLine();
line.setGeometry(points);
const geometry = line.geometry;
// Build the material with good parameters to animate it.
const material = new MeshLineMaterial({
lineWidth: 0.1,
color: new Color('#ff0000'),
dashArray: 2, // always has to be the double of the line
dashOffset: 0, // start the dash at zero
dashRatio: 0.75, // visible length range min: 0.99, max: 0.5
});
// Build the Mesh
const lineMesh = new Mesh(geometry, material);
lineMesh.position.x = -4.5;
// ! Assuming you have your own webgl engine to add meshes on scene and update them.
webgl.add(lineMesh);
// ! Call each frame
function update() {
// Check if the dash is out to stop animate it.
if (lineMesh.material.uniforms.dashOffset.value < -2) return;
// Decrement the dashOffset value to animate the path with the dash.
lineMesh.material.uniforms.dashOffset.value -= 0.01;
}
```

## Create your own line style

Now that you know how to animate lines, I will show you some tips on how to customize the shape of your lines.

### Use SplineCurve or CatmullRomCurve3

These classes **smooth an array of points** that is roughly positioned. They are perfect to build curved and fluid lines and keep control of them (length, orientation, turbulences…).

For instance, **let’s add some turbulences** to our previous array of points:

```
const segmentLength = 1;
const nbrOfPoints = 10;
const points = [];
const turbulence = 0.5;
for (let i = 0; i < nbrOfPoints; i++) {
// ! We have to wrapped points into a THREE.Vector3 this time
points.push(new Vector3(
i * segmentLength,
(Math.random() * (turbulence * 2)) - turbulence,
(Math.random() * (turbulence * 2)) - turbulence,
));
}
```

Then, use one of these classes to smooth your array of lines before you create the geometry:

```
// 2D spline
// const linePoints = new Geometry().setFromPoints(new SplineCurve(points).getPoints(50));
// 3D spline
const linePoints = new Geometry().setFromPoints(new CatmullRomCurve3(points).getPoints(50));
const line = new MeshLine();
line.setGeometry(linePoints);
const geometry = line.geometry;
```

And like that you create **your smooth curved line**!

Note that **SplineCurve** only smoothes in 2D (x and y axis) compared to **CatmullRomCurve3** that takes into account three axes.

I recommend to use the **SplineCurve**, anyway. It is **more performant to calculate lines** and is often enough to create the desired curved effect.

For instance, my demos Confetti and Energy are only made with the **SplineCurve** method:

### Use Raycasting

Another technique taken from a THREE.MeshLine example is using a **Raycaster to scan a Mesh** already present in the scene.

Thus, you can create your lines that follow the shape of an object:

```
const radius = 4;
const yMax = -4;
const points = [];
const origin = new Vector3();
const direction = new Vector3();
const raycaster = new Raycaster();
let y = 0;
let angle = 0;
// Start the scan
while (y < yMax) {
// Update the orientation and the position of the raycaster
y -= 0.1;
angle += 0.2;
origin.set(radius * Math.cos(angle), y, radius * Math.sin(angle));
direction.set(-origin.x, 0, -origin.z);
direction.normalize();
raycaster.set(origin, direction);
// Save the coordinates raycsted.
// !Assuming the raycaster cross the object in the scene each time
const intersect = raycaster.intersectObject(objectToRaycast, true);
if (intersect.length) {
points.push(
intersect[0].point.x,
intersect[0].point.y,
intersect[0].point.z,
);
}
}
```

This method is employed in the Boreal Sky demo. Here I used a sphere part as geometry to create the mesh `objectToRaycast`

:

Now, you have enough tools **to play and animate MeshLines**. Many of these methods are inspired by the library’s examples. Feel free to explore these and share your own experiments and methods to create your own lines!

## References and Credits

Source link https://tympanus.net/codrops/2019/01/08/animated-mesh-lines/