Linear Blend Skinning
A rigged character is really two things glued together: a skeleton of joints that an
animator poses, and a skin — a single smooth mesh of thousands of vertices — that has
to follow the bones without tearing at the seams. The question every real-time engine must answer,
sixty times a second for every vertex, is deceptively simple: when the elbow bends, where does this
particular skin vertex go?
The industry's default answer, running in nearly every game and phone on Earth, is
Linear Blend Skinning (LBS) — also called skeletal subspace deformation or
just smooth skinning. It is beautifully cheap, it fits a GPU vertex shader perfectly, and it
has one famous, ugly flaw that has a nickname: the candy-wrapper collapse. This page
builds the method, works its collapse out on paper, and shows you exactly why a linear blend
of rigid motions refuses to stay rigid.
One vertex, several bones, a weighted average
In the bind
pose the skin sits in its neutral rest shape and each vertex is painted with a
few skin weights — numbers w_j saying how much joint
j owns this vertex. A vertex deep in the forearm is owned entirely by the
forearm bone (w = 1); a vertex right over the elbow crease has its ownership
split between the upper-arm and forearm bones (say w = 0.5
each). The weights on any vertex always sum to one.
LBS then does the obvious thing. It transforms the rest vertex by each owning bone as if that
bone owned it completely, and takes the weighted average of the results:
- The skinned vertex is
\mathbf{v}' \;=\; \left(\sum_{j} w_j\, M_j\, B_j^{-1}\right)\mathbf{v},
\qquad \sum_j w_j = 1,
where \mathbf{v} is the rest-pose vertex and the sum runs over the joints
that influence it.
- B_j is joint j's bind
(rest) world transform; B_j^{-1} pulls the vertex out of world space into
that joint's local frame — where it sat relative to the bone at rest.
- M_j is the joint's current posed world transform;
it plants that local offset back into the world at the new pose.
- Because the weights sum to one, a vertex owned by a single bone
(w_j = 1) moves exactly rigidly with it — only the shared
vertices get blended, and that blend is what makes the surface bend smoothly across a joint instead
of cracking.
The product M_j B_j^{-1} is a single skinning matrix per
joint that the engine computes once per frame and stores in a small matrix palette. Per
vertex the whole cost is then: fetch two-to-four matrices, scale each by its weight, add them,
multiply the vertex once. No trig, no branches — a straight weighted sum of matrices, which is why it
flies on hardware.
Cost, and nothing but cost. A modern character mesh has tens of thousands of vertices and the skinning
must finish inside a couple of milliseconds. LBS needs only a handful of multiply-adds per vertex,
maps directly onto a GPU vertex shader, and the expensive part — building each
M_j B_j^{-1} — happens just once per bone per frame, not once per vertex.
Cap the influences at four bones per vertex and you can pack the weights into a single vertex
attribute. Decades of "good enough" motion have been shipped on exactly this arithmetic; the fancier
methods on this course all exist to fix the specific places where this weighted average goes wrong.
Watch the collapse happen
Below is a two-bone arm: a fixed upper arm and a forearm you can bend with the slider. The skin is
drawn as an outline of vertices. The highlighted vertices near the elbow are the
shared ones, split half-and-half between the two bones; the rest are owned rigidly by a single
bone. Drag the bend toward a sharp angle and watch the inner elbow: the shared vertices do not
sweep cleanly around the corner — they migrate inward, pinching the surface and losing volume.
Push it toward a full fold and the crease nearly vanishes.
The rigidly-owned vertices (unhighlighted) travel perfectly with their bone — no distortion at all.
Every bit of the trouble lives in the blended band, and it gets worse the more the two bones disagree
about where the vertex should go.
Worked example: the 90° elbow that shrinks
Take a vertex sitting right on the elbow, a distance r = 0.6 straight out
from the joint, shared equally (w = 0.5) between the upper-arm bone (which
does not move here — its transform is the identity I) and the forearm bone,
which rotates by 90^\circ about the joint. Because both bones share the same
pivot, the only thing that differs between them is the rotation, so the blended transform acting on the
vertex's offset from the joint is
M \;=\; 0.5\,I \;+\; 0.5\,R(90^\circ) \;=\; 0.5\begin{pmatrix}1&0\\0&1\end{pmatrix} + 0.5\begin{pmatrix}0&-1\\1&0\end{pmatrix} = \begin{pmatrix}0.5&-0.5\\0.5&0.5\end{pmatrix}.
Is M a rotation? A rotation has determinant 1.
Here \det M = (0.5)(0.5) - (-0.5)(0.5) = 0.5 — not one. In
fact M factors cleanly:
M \;=\; \tfrac{1}{\sqrt2}\,R(45^\circ) \;=\; 0.707\times(\text{rotation by }45^\circ).
So the blended transform is a rotation by 45^\circ (half of ninety — sensible)
but with a uniform shrink to 0.707 baked in. The vertex
that lived 0.6 from the joint now lands only
0.6 \times 0.707 \approx 0.424 from it: the surface has been sucked
29% inward. That inward suck, all around the joint, is the elbow pinch. The
general rule falls straight out — the equal-weight blend
0.5\,(I + R(\theta)) equals
\cos(\theta/2)\,R(\theta/2), a half-angle rotation scaled by
\cos(\theta/2). The scale is 1 only at
\theta = 0; it falls the more the bones disagree.
The candy-wrapper twist
The pinch turns catastrophic at a twist. Imagine the wrist rotating about the length
of the forearm while the forearm itself stays put — the two bones sharing the wrist vertices are then
two rotations almost 180^\circ apart. Plug \theta = 180^\circ
into the blend:
0.5\,(I + R(180^\circ)) \;=\; 0.5\,(I - I) \;=\; \mathbf{0}, \qquad \cos(90^\circ) = 0.
The blended matrix is the zero matrix: it maps the entire shared band onto the single
joint point. The skin collapses to a thin pinched neck — exactly the twisted-shut look of a
sweet wrapper, which is where the nickname comes from. Anywhere between
0^\circ and 180^\circ you get partial shrink; at
the full half-turn you get total collapse, because averaging a rotation with its opposite gives
nothing at all.
Here is the misconception that causes every one of these bugs. LBS looks like it is averaging two
motions, so it feels like the answer should be "half-way between the two poses" — and a half-way
pose ought to be a perfectly good rigid pose. But that is not what the formula does.
It averages the two matrices, entry by entry, and the set of rotation matrices is
curved — it is not closed under straight-line averaging. Take two rotations, blend their
matrices linearly, and the result leaves the rotation group entirely: its determinant drops below one,
so it necessarily shrinks. That single fact — a linear blend of rigid transforms is
not itself rigid — is the whole story behind the elbow pinch and the candy-wrapper. So:
- Do not expect volume preservation from LBS. It never promised it; near bent or
twisted joints it actively destroys volume.
- The remedies all attack this exact point: add helper / twist joints so no single
blend ever spans a large angle; layer corrective blend shapes that sculpt the lost
volume back in at problem poses; or switch to
dual-quaternion
skinning, which blends in a space that stays rigid (next lesson) and so cannot
candy-wrapper.