← All projects

Cloth simulation.

A grid of point masses joined by springs, stepped with Verlet integration in 3D and shaded on the GPU. The springs stay drawn on top, so you can watch the math hold the fabric together. Grab it, fling it, slice it, or orbit around it.

0 points 0 springs 0 max fps 0 ms/frame
Drag a point to pull and throw Drag empty space to orbit Right-drag or Shift+drag to cut Double-click a point to pin or unpin it Keys: G grab · C cut · W wind · T tearing · R reset
01 · Integrate

Verlet integration

Each point stores only its current and previous position. Velocity is implied by the difference, so a step is x' = x + (x − x₀)·damping + g·dt². No velocities to drift out of sync, and constraints can move points directly.

02 · Constrain

Three kinds of spring

Structural springs join neighbours and stop stretching. Shear springs cross each cell diagonally so squares can't skew into diamonds. Bend springs skip a point, resisting sharp folds; they're what makes the cloth feel sturdy. Turn on Shear & bend to see them.

03 · Shade

Lighting the surface

Every frame, each point's normal is the cross product of the vectors to its neighbours. A WebGL shader lights the fabric from that normal, with a soft wrap-around key light, a fill light and a sheen at grazing angles. The front is white and the back slate so you can see it turn over, and both blend toward orange wherever the springs are stretched, on the same scale as the lines.

Original

I first wrote this in Luau for Roblox: the cloth is an EditableMesh whose vertices are driven by the solver, with sphere and cylinder colliders, a custom vector type to cut allocation, and a benchmarking mode. Rendering the mesh, not the physics, turned out to be the bottleneck. This port keeps the cloth in flat typed arrays, uses a square-root-free spring correction, interpolates between physics steps for high-refresh displays, puts the solver to sleep once the cloth settles, and hands all the shading to the GPU.