Mass-Spring Cloth
A cape billowing behind a hero, a flag snapping in the wind, a tablecloth settling over a table's
edge — animated cloth looks alive because it is simulated, not keyframed. The workhorse
model, introduced by Xavier Provot in 1995, is beautifully simple: pretend the fabric is a
grid of tiny point masses stitched together by springs. Each mass
feels gravity, wind, and the tug of its springy neighbours; you add up those forces, take a small step
forward in time, and repeat. Do that thirty times a second and the grid drapes, folds
and flutters like real fabric.
This page builds that model from its three kinds of spring, shows the per-step update loop, and then
confronts the one thing that makes cloth genuinely hard: real fabric barely stretches, and forcing a
mass-spring grid to barely stretch makes the equations stiff — stiff enough to blow
an explicit simulation to infinity in a handful of frames. We meet the classic cures, and drape a
little pinned patch under gravity you can play with.
The model: masses joined by three kinds of spring
Lay a regular grid of point masses, one at each fabric vertex — say an n \times m
lattice. Every mass i has a position \mathbf{x}_i,
a velocity \mathbf{v}_i, and a mass m_i. Now
connect them with springs. Provot's insight was that one kind of spring is not enough —
a grid of only horizontal-and-vertical springs shears and folds like a floppy trellis. You need three
distinct connection patterns, each resisting a different way the cloth can deform.
- Structural springs join each mass to its immediate horizontal and vertical
neighbours. They resist stretching and compression — the in-plane pull of the
weave.
- Shear springs join each mass to its diagonal neighbours. They resist
shearing — the grid skewing from squares into rhombi.
- Bend (flexion) springs join each mass to the neighbour two cells away
(skip-one), along rows and columns. They resist folding — sharp out-of-plane creases —
and give cloth its characteristic stiffness against buckling.
Each spring stores a rest length L_0 (its length in the
flat, undeformed cloth) and a stiffness k. When the spring's
current length differs from L_0, it pulls its two ends back toward rest with a
Hooke's-law
force.
The spring force
Take a single spring between masses i and j. Let
\mathbf{d} = \mathbf{x}_j - \mathbf{x}_i be the vector from one to the other,
with current length \lVert \mathbf{d} \rVert. Hooke's law says the force on
mass i points along the spring, proportional to how far it is stretched past
its rest length:
\mathbf{F}_{i} \;=\; k\,\bigl(\lVert \mathbf{d} \rVert - L_0\bigr)\,\frac{\mathbf{d}}{\lVert \mathbf{d} \rVert}.
The bracket (\lVert \mathbf{d} \rVert - L_0) is the strain
(positive = stretched, negative = compressed); the unit vector
\mathbf{d}/\lVert \mathbf{d} \rVert gives the direction. Mass
j feels the equal-and-opposite -\mathbf{F}_i. Real
implementations add a damping term proportional to the relative velocity along the
spring, so oscillations bleed away instead of ringing forever:
\mathbf{F}^{\text{damp}}_{i} \;=\; c\,\bigl[(\mathbf{v}_j - \mathbf{v}_i)\cdot \hat{\mathbf{d}}\bigr]\,\hat{\mathbf{d}}, \qquad \hat{\mathbf{d}} = \frac{\mathbf{d}}{\lVert \mathbf{d} \rVert}.
The per-step update loop
Simulating the cloth is a loop over small time steps \Delta t. Each step
does the same four things:
- Zero and accumulate forces. For every mass start from
\mathbf{F}_i = \mathbf{0}, add gravity
m_i\,\mathbf{g}, add each connected spring's Hooke + damping force, add
external wind and air drag.
- Solve for acceleration: \mathbf{a}_i = \mathbf{F}_i / m_i
(Newton's second law).
- Integrate velocity then position forward by \Delta t
(an explicit scheme, e.g. semi-implicit Euler:
\mathbf{v}_i \mathrel{+}= \mathbf{a}_i\,\Delta t, then
\mathbf{x}_i \mathrel{+}= \mathbf{v}_i\,\Delta t).
- Apply constraints: hold pinned masses fixed, resolve collisions, and clamp any
over-stretched springs (strain limiting).
A cloth of a few thousand masses with three spring types is tens of thousands of springs — but each is
a handful of multiplies, so the whole update is cheap. The choice of integrator in step three
is where cloth simulation lives or dies, as we are about to see. For the full menu of schemes see
numerical integration for animation.
The stretching problem: cloth is stiff
Here is the crux. Take a shirt in both hands and pull: it hardly lengthens at all — maybe a percent or
two before it resists hard. To reproduce that "barely stretches" behaviour, the structural
springs must be very stiff — a huge k. But a stiff spring produces
enormous restoring forces for tiny displacements, and those forces swing back and forth extremely fast.
The differential equation becomes what numerical analysts call stiff: it contains
oscillations far faster than the motion you care about.
An explicit integrator (plain forward Euler, or even RK4) is only stable if the step
\Delta t is small enough to resolve the fastest oscillation. For a
spring of stiffness k and mass m, that oscillation
has angular frequency \omega = \sqrt{k/m}, and stability roughly demands:
\Delta t \;\lesssim\; \frac{2}{\omega} \;=\; 2\sqrt{\frac{m}{k}}.
Crank k up by 100× to stiffen the cloth and the allowable step shrinks by
\sqrt{100} = 10×. Push k high enough for realistic
cloth and \Delta t must be so tiny you would need hundreds of substeps per
frame; overshoot it by a hair and each step amplifies the error, the springs fling their masses further
every step, and the whole sheet explodes to infinity within a few frames. That is the
central tension of cloth: realistically inextensible fabric makes the naive method unstable.
Three classic cures
The field solved this three ways, and production systems mix them:
- Strain limiting (Provot, 1995). Keep the springs moderately soft — cheap and
stable — then, after integrating, walk the springs and any that stretched beyond a threshold (Provot
used 10% past rest) get their endpoints moved directly back until the
length is within bounds. This clamps the geometry rather than fighting it with force.
- Implicit integration (Baraff & Witkin, 1998). Instead of extrapolating from
the current forces, solve for the velocities that will be consistent at the end of the step
— a large linear system each frame. Implicit (backward) Euler is unconditionally stable:
you can take big steps with very stiff springs and it never explodes (it just adds numerical
damping). This is the "Large Steps in Cloth Simulation" paper that made feature-film cloth
practical.
- Position-based dynamics (PBD). Skip forces for the inextensibility part
altogether: treat "this edge must stay near its rest length" as a hard constraint and
project the positions to satisfy it directly, iterating over the constraint set. Fast, stable, and
controllable — the standard in real-time games and DCC tools. See
position-based dynamics.
The common thread: don't try to make an explicit spring solver represent near-inextensible cloth by
brute force. Either limit the strain, integrate implicitly, or constrain the positions.
Pinning, collision and self-collision
A free grid under gravity just falls. To hang a flag you pin its
attached edge: mark those masses as fixed — infinite mass, or simply skip their integration so
their positions never change. Everything downstream drapes from the pinned anchors. Pinning two corners
of a banner, or the shoulders of a cape, is exactly this.
Cloth must also not pass through the character wearing it. Collision against the body
detects masses that have penetrated a collision proxy (spheres, capsules, the mesh) and pushes them back
out along the surface normal, killing the inward velocity component. Self-collision —
stopping the cloth from passing through itself so folds stack instead of interpenetrating — is
far costlier: it needs spatial acceleration structures to test many mass/triangle pairs each frame, and
is a classic source of cloth-sim slowness and instability.
Watch it drape
Below is a small mass-spring grid pinned at its two top corners. Drive the
gravity / sag slider from 0 (flat, undeformed) up toward 1 (full droop): the interior
masses fall, the structural springs along the top row stretch to carry the load, and the sheet settles
into the gentle catenary-like curve real hanging fabric takes. The two pinned corners never
move — everything hangs from them.
Watch the top row as you increase the sag: those springs stretch the most, because they carry
the weight of everything below. That is precisely where strain limiting bites first.
Worked example: a patch pinned at two corners
Take a 3 \times 3 patch, rest spacing L_0 = 1,
each mass m = 0.1\,\text{kg}, pinned at the two top corners
P_1 and P_2. Release it under gravity.
Which springs stretch? The whole sheet hangs from the two pins, so the top-row
structural springs — the ones directly connecting the interior top mass to the pinned corners —
carry the entire weight below them and stretch the most. The diagonal shear springs
lengthen too as the middle sags into a shallow V, while the bottom-row springs barely change (little
hangs beneath them). If the structural springs are soft, the top edge visibly lengthens — the sheet
droops far lower than a real cloth of that size would.
How strain limiting caps the sag. Suppose after a step the top-row springs have
stretched to length 1.25 — a 25\% strain, well
past Provot's 10\% cap. Strain limiting shortens each offending spring back
to at most 1.10 by moving its movable end (the pinned end can't
move) toward the anchor:
\text{allowed length} = (1 + 0.10)\,L_0 = 1.10, \qquad \text{so the free end is pulled inward until } \lVert \mathbf{d} \rVert \le 1.10.
Applied every step across the sheet, this caps the cumulative stretch: no chain of springs can
elongate past roughly 10% of its rest length, so the patch settles at a realistic droop instead of
drifting ever lower like taffy — and all with soft, cheap, stable springs.
When a character teleports, or the frame rate hitches so \Delta t suddenly
balloons, the stability bound \Delta t \lesssim 2\sqrt{m/k} is momentarily
violated. For that one big step the explicit solver over-corrects, springs overshoot, and the cloth
wobbles like jelly or shudders before the constraint solver reels it back in. It is the same explosion
that would run away forever with stiff springs — just caught and damped after a frame. Engines guard
against it by clamping the step size, taking multiple substeps per
frame, and leaning on PBD's position projection, which stays stable no matter how large the step.
The tempting fix for a floppy simulation is to reach for the stiffness dial: soft structural springs
let the cloth stretch like rubber — a cape that lengthens like chewing gum as the hero
runs — so surely just crank k up until it stops? No. With an
explicit integrator, a bigger k shrinks the stable step as
1/\sqrt{k}, and past a modest value the simulation explodes — masses
fly off to infinity within a few frames. You cannot buy inextensibility by cranking
k in an explicit solver. The right tools are strain limiting
(clamp the geometry after the step), implicit integration (unconditionally stable, so
big k is safe), or position-based constraints (enforce the
rest length directly). Keep the springs soft, and make the fabric inextensible some other way.
Xavier Provot's 1995 Graphics Interface paper, "Deformation Constraints in a Mass-Spring Model to
Describe Rigid Cloth Behavior," gave us the three-spring grid and the strain-limiting trick in
one shot. Three years later Baraff and Witkin's SIGGRAPH 1998 paper "Large Steps in Cloth Simulation"
showed that implicit integration let you take frame-sized steps with stiff cloth — the breakthrough that
put believable cloth in films. Position-based dynamics (Müller and colleagues, mid-2000s) then made
stable cloth fast enough for real-time games. Thirty years on, every one of these ideas is still in the
pipeline you see in modern DCC tools.