Hair and Strands

A character turns their head and their hair swings, settles, and sways a beat behind — that lag is half of what sells them as alive. But hair is a nightmare to simulate honestly: a human head carries roughly 100,000 individual strands, each one a thin, floppy, nearly unstretchable fibre that bends easily, resists being curled away from its style, collides with its neighbours, and drapes over the shoulders. Do the obvious thing — one simulated element per real hair — and you are running a hundred thousand coupled physics problems every frame. Nobody does that.

This page builds hair up from a single humble object — a strand modelled as a chain of particles anchored at the scalp — names the three things a strand must resist (stretch, bend, twist), sketches the modern rigorous model (Discrete Elastic Rods), and then confronts the scale problem head-on: simulate a few thousand guide strands and interpolate the other 97,000. It builds on the particle-and-constraint machinery of position-based dynamics and is a cousin of mass-spring cloth.

A strand is a chain of particles

Take one hair and chop it into a handful of short segments — say a dozen. Put a particle (a point mass) at each joint between segments, and pin the first particle to the scalp. A hair is now a little chain: an ordered list of points p_0, p_1, \dots, p_n with p_0 welded to the head and each consecutive pair joined by a segment of some rest length L_i.

Everything else — gravity pulling each particle down, wind, the head yanking the root around — just moves the particles. The three resistances are what keep the moved particles arranged like a hair and not like a cloud of disconnected dots.

The three forces a strand resists

Hair (and fur, and grass, and rope) is an elastic rod, and a rod stores energy in exactly three ways when you deform it:

Stretch resists a change in length; bend resists a change in direction between neighbours; twist resists a change in roll. A limp, freshly-washed hair has low bend and twist stiffness and flops; a hair-sprayed, styled lock has high bend stiffness and holds its shape against gravity. Styling is stiffness.

Give me three points and I can tell you the angle they make — that's bend. But twist is rotation about the line joining points, and a point has no orientation: spin a dot about an axis through it and nothing changes. To measure twist you must attach a frame — say a pair of perpendicular vectors — to each segment and track how much they rotate from one segment to the next. This is precisely why the rigorous hair models are called rods, not chains: a rod carries a material frame, a chain of particles does not. Without a frame, your "hair" can never resist being wound up like a telephone cord.

The modern model: Discrete Elastic Rods

The state-of-the-art way to simulate a single strand rigorously is Discrete Elastic Rods (DER), introduced by Bergou and colleagues in 2008 and now standard in film hair. The idea, at a high level:

You do not need the full DER machinery to make believable hair — many real-time systems get away with a chain of particles, length constraints, and a simple bending term, ignoring twist entirely. But when you need a curl to spring back correctly, or a braid to behave, DER (or a position-based approximation of it) is the model that gets it right.

Watch the strands sway

Below are three guide strands, each a chain of particles (dots) joined by fixed-length segments and pinned at the top. Drag time and watch them whip: the root barely moves, but the error accumulates down the chain so the tips swing furthest and lag behind — the signature look of hair. Crucially, every segment keeps its length no matter how the strand bends; only the angles between segments change. That is inextensibility in action.

Notice how neighbouring strands move together but not identically — a small phase offset gives the clump its life. That coherence is exactly what makes interpolation between a few guides look like a full head of hair.

Worked example: a 5-segment guide strand under gravity

Take one guide strand of five segments — six particles p_0,\dots,p_5 — each segment of rest length L = 1. The root p_0 is pinned to the scalp. We integrate it with a position-based dynamics loop, and the magic is a constraint-projection pass that keeps every segment exactly one unit long.

Step 1 — predict. Ignore all the internal forces for a moment. Apply gravity to each free particle and let it drift: p_i \leftarrow p_i + v_i\,\Delta t + g\,\Delta t^2. After this step the particles have all fallen a little, so the segments have stretched|p_{i+1}-p_i| is no longer 1.

Step 2 — project the length constraints. Walk the chain and fix each segment back to length L. For a segment between p_i and p_{i+1}, the constraint is

C = |p_{i+1}-p_i| - L = 0.

If the current length is d = |p_{i+1}-p_i|, the segment is off by d - L. Move the two particles toward or away from each other along their connecting direction \hat{n} = (p_{i+1}-p_i)/d to erase that error. Because the root is pinned (infinite mass), the whole correction of the first segment lands on p_1:

p_1 \leftarrow p_1 - (d - L)\,\hat{n},

and for an interior segment where both endpoints are free, split the correction evenly:

p_i \leftarrow p_i + \tfrac12 (d-L)\,\hat{n}, \qquad p_{i+1} \leftarrow p_{i+1} - \tfrac12 (d-L)\,\hat{n}.

Step 3 — iterate. Fixing segment 1 slightly breaks segment 2, and so on, so you sweep the chain a handful of times (each sweep is one Gauss–Seidel pass). A few iterations and every segment is back to length 1 to a tolerance the eye can't see. The strand has swung under gravity, yet not stretched a millimetre.

Step 4 — recover velocity. Set each particle's new velocity from how far it actually ended up moving, v_i \leftarrow (p_i^{\text{new}} - p_i^{\text{old}})/\Delta t, and loop. The constraint projection has quietly injected exactly the stiff, inextensible behaviour we wanted — without a single stiff spring anywhere.

The tempting first idea is to connect the particles with stretch springs: a spring of rest length L and stiffness k, force F = -k(d-L). It seems reasonable — springs resist stretching, hair resists stretching. It is a trap.

Real hair is essentially inextensible: it does not stretch a perceptible amount. To fake inextensibility with a soft spring you must crank k enormously high — and a very stiff spring makes the equations numerically stiff. Explicit integration of a stiff spring needs a tiny time step or it explodes: the particle overshoots, the restoring force grows, it overshoots harder, and your hair detonates into a spiky mess. You end up either unstable or forced into microscopic time steps you can't afford across thousands of strands.

The fix is to stop modelling length as a force and model it as a hard constraint, projected geometrically each step (the position-based approach above). Constraint projection is unconditionally stable — you can't overshoot a position you're clamping — and it enforces near-exact inextensibility with a couple of cheap iterations. For length, constrain; don't spring. (Soft springs are fine for the gentle resistances like bend, where you genuinely want a little give.)

The scale problem: guides and interpolation

Even at a hundred particles per strand, simulating 100,000 strands is a hundred thousand chains and far too much. The universal trick: simulate only a few thousand guide strands, spread evenly over the scalp, and interpolate — "skin" — the remaining strands to them, just as a skinned mesh follows its skeleton.

This is the same divide-and-conquer as level-of-detail everywhere in graphics: put the expensive work on a sparse representative set, and cheaply reconstruct the dense detail. It works because adjacent hairs move coherently — a guide is a faithful stand-in for its neighbours.

Because interpolation is generous and variation is added on top. Between three guide strands you can spawn hundreds of render strands, each a smooth blend of the three, then nudge each one with procedural clumping (pulling nearby strands into wisps), frizz (small random kinks), and per-strand curl. The physics is low-resolution but the geometry is full-resolution, and the eye reads the millions of fine, slightly-varied hairs, not the sparse guides underneath. It's the same reason a crowd can be a handful of animated cycles instanced with variation and still look like a stadium.

Collisions: the expensive part

Two collision problems remain, and both are costly. Strand–body collision stops hair sinking into the head, neck and shoulders — usually approximated by wrapping the body in cheap collision primitives (spheres and capsules) and pushing any particle that penetrates back out to the surface. Strand–strand collision stops the hair volume collapsing into itself and gives it body, but every strand can in principle touch every other — quadratically many pairs — so it is almost always approximated: treat the hair as a continuum, or resolve collisions only between guides, or add a repulsion that preserves volume without tracking exact contacts.

The lesson repeated across hair simulation: be honest where the eye looks and cheat everywhere else. Exact per-strand contact is rarely worth its price; a plausible, volume-preserving approximation almost always wins.