Interactive ThreeJS Cloth Breakdown

A breakdown of all the steps to make a ThreeJS Cloth interative effect with cannonjs. Learn the main techniques of this demo.

This week's demo was meant to be a ballon (see at the end), one cloth per each face of a cube. But that was too expensive. Too many meshes, too many points, and too many constraints.

Physic simulations in the CPU get slow fast, at least with CanonJS. There are other libraries like Rapier, which would probably perform better. And some techniques also help, like animating the bones of a mesh instead of all of its vertices. But for the sake of the demo, I pivoted to the fullscreen cloth interaction.


As mentioned before, my idea was to make a balloon similar to the one shown in this blender tutorial. But that was too expensive to run and went with something more like the left cloth simulation.



Connecting the cloth mesh

Starting with a plane mesh, each vertex is connected to its neighbors by distance. Loop through each point, create the physic's body, and connect it to its 4 neighbors by a distance of 1 / nSegements

The points are only connected with their vertical and horizontal nieghtbors.

Originally I made the mistake of connecting them diagonally. This doesn't work because the diagonal distance is greater than the vertical/horizontal distance.

Cloth connections
Cloth connections

Relaxing the cloth

If you create the simulation in the exact position of the plane and the exact distance constraints, then nothing is likely to happen. All the constraints are already met, and the points don't have leeway to relax and move.

To give some relaxation to the points I made the edges static and also scaled them down closer to the center. The closer to the center the edges were (closer to each other), the more distance the other points can use to expand and relax.

Multiple versions of the cloth with the edges closer to the center
Multiple versions of the cloth with the edges closer to the center

Wind and mouse interaction

Usually wind in cloth simulations is done by sampling noise. I went with a simpler approach, just pushing everything from the center.

points.forEach((body, i) => {

v0.mult(-0.01, v0)

body.applyImpulse(v0, vZero)

Because the edges are static, the mesh is not going to move around to much and just relax and stretch in the middle.

And the interaction is a hidden sphere that moves around with the mouse. The physics simulation does the rest from here!

sphere interacting with cloth
sphere interacting with cloth

Cloth Balloon

The initial idea was a cloth balloon. Bounce it around the screen. Throw some objects at it. Something fun.

However, fun is expensive. And my CPU wasn't too keen on the type of fun that runs at 3fps. So I pivoted to the final demo.

I've been recommended RapierJS which seems to run with better performance, but for a future demo, I want to explore cloth simulation in the GPU similar to David Li's Elastic Man

cloth ballon
cloth ballon