The Bind Pose and Skinning
A character mesh is just a bag of vertices — a few hundred thousand points floating in space. A
skeleton is a tree of joints, each carrying a transform that says where its bone
sits and how it is oriented right now. On their own these two things know nothing about each other.
Skinning is the glue: it makes the skin follow the bones, so that when the elbow
joint rotates, the vertices of the forearm swing with it and the arm bends. This page pins down the
single most important idea that makes that glue work — the bind pose and the
inverse bind matrix — and shows the exact transform a rigidly-attached vertex obeys.
The bind pose: where skin and skeleton were introduced
When a rigger first attaches a mesh to a skeleton, the character is standing in one specific
pose — arms out, legs slightly apart, the classic T-pose or A-pose. This is the
bind pose (also called the rest pose or reference pose): the pose
in which the mesh was modelled and in which it was bound to the skeleton. It is the one
moment where we know, for certain, exactly where every vertex sits relative to every joint. Every
later pose is measured as a departure from this one.
- The bind pose is the pose the mesh was modelled and bound in — the reference
against which all deformation is measured.
- Each joint j has a bind matrix
B_j: its world transform at bind time (it takes a point from
joint j's local space out into world/mesh space).
- Its inverse, the inverse bind matrix B_j^{-1}, does
the opposite — it takes a mesh-space vertex into joint j's
local space, as that vertex sat at bind time.
The skinning transform: undo the bind, then re-apply the pose
Take a vertex v that is rigidly attached to a single joint
j — imagine a freckle painted on the forearm, glued to the elbow. In the
bind pose it sits at some position in mesh space. Now the animator poses the skeleton, and joint
j's current world transform is M_j.
Where does the freckle go? Two steps:
First we ask: where did this vertex sit relative to the joint, back at bind time? That is
exactly what B_j^{-1} computes — it carries v
into the joint's local frame. That local position is frozen; it never changes,
because the freckle is glued to the bone. Then we re-plant that local position using the joint's
current world transform M_j. Composing the two:
v' \;=\; M_j \, B_j^{-1} \, v.
- A vertex bound to one joint j deforms as
v' = M_j \, B_j^{-1} \, v.
- B_j^{-1} undoes the bind — it stores the vertex in
the joint's local frame, where it is constant.
- M_j re-applies the current pose — it moves that
frozen local point to wherever the joint is now.
The pairing M_j \, B_j^{-1} is often precomputed once per joint per frame
and called the joint's skinning matrix; every vertex bound to that joint is then a
single matrix-times-vector away.
The bind pose is the identity — that is the whole point
Here is the check that makes the formula click. In the bind pose, nothing has moved yet, so every
joint's current transform equals its bind transform: M_j = B_j.
Substitute:
v' \;=\; M_j \, B_j^{-1} \, v \;=\; B_j \, B_j^{-1} \, v \;=\; I \, v \;=\; v.
The vertex is left exactly where it was. This is precisely what we want: in the bind
pose the mesh should be undeformed, sitting where the modeller put it. The B_j^{-1}
is the piece that makes the bind pose collapse to the identity — it cancels the bind transform so that
deformation only ever measures the difference between the current pose and the bind pose.
Seeing it move
Below, a bone runs from the elbow joint outward, with a handful of vertices
bound to it (their frozen local positions relative to the bone). Press play — or step the
timeline — to rotate the joint. Each vertex keeps its local relationship to the bone exactly
(the freckle stays a freckle) while its world position swings around: that is
v' = M_j \, B_j^{-1} \, v in action, with only M_j
changing between the two panels.
Worked example: a freckle on the forearm
Work in 2-D for clarity. Suppose the elbow joint, at bind time, sits at the origin with no rotation,
so its bind matrix is the identity's cousin — a pure placement. Say
B_{\text{elbow}} places the joint at (2,0) with
no rotation, so
B_{\text{elbow}} = \begin{bmatrix} 1 & 0 & 2 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix}, \qquad B_{\text{elbow}}^{-1} = \begin{bmatrix} 1 & 0 & -2 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix}.
A freckle sits on the forearm at mesh position v = (5, 0) — that is,
3 units out along the bone from the joint. First undo the bind:
B_{\text{elbow}}^{-1} \, v = (5 - 2,\; 0) = (3, 0),
which is the freckle's local position: three units down the bone, as expected. Now the
animator rotates the elbow by 90^\circ (keeping the joint at
(2,0)), so the current transform
M_{\text{elbow}} rotates about that pivot. Applying it to the local point
(3,0) swings it up:
v' = M_{\text{elbow}} \, B_{\text{elbow}}^{-1} \, v = (2,\, 0) + \big(3\cos 90^\circ,\; 3\sin 90^\circ\big) = (2, \, 3).
The freckle has swung from (5,0) to (2,3) —
straight up above the joint, exactly as a forearm point should when the elbow bends a quarter turn.
And in the bind pose (M_{\text{elbow}} = B_{\text{elbow}}) the same formula
returns (2,0) + (3,0) = (5,0) = v: unmoved.
Weights: one vertex, several bones
A vertex glued to a single joint is fine deep inside a limb, but a vertex near a
joint — at the elbow crease, or where the shoulder meets the torso — needs to be
pulled by more than one bone at once, or it creases like folded cardboard. So each vertex
carries a small list of skin weights: a set of joints
j with weights w_j \ge 0 saying how much each
one influences it, and the weights sum to one:
\sum_j w_j = 1.
The natural thing to do is blend the single-joint answers, weighted:
v' = \sum_j w_j \, M_j \, B_j^{-1} \, v. That weighted average of skinning
matrices is linear-blend skinning — the workhorse of real-time character deformation,
and the subject of the
next lesson.
For now, the key idea is just that the rigid formula M_j \, B_j^{-1} \, v is
the atom, and weights are how we mix several atoms together.
Setting those weights is a craft called painting weights: the rigger literally paints
influence onto the mesh with a brush, one joint at a time, watching a heat-map of "how much this bone
owns this patch of skin". Auto-binding gives a first guess; the hand-painting cleans up the elbows,
armpits, and other creases where a smooth blend matters most. A well-painted arm bends without
collapsing; a badly-painted one pinches or balloons.
You could, in principle, bake each vertex's local position into the joint's frame once and store
that. But meshes are authored, exported, and edited in mesh/world space — that is the space
the modeller and every tool speaks in. The inverse bind matrix lets the engine keep the mesh in its
natural coordinates and convert on demand: B_j^{-1} is computed
once, at bind time, from the skeleton the artist set up, and shipped alongside the mesh. It is the
clean bridge between "the space the artist modelled in" and "the space the joint animates in", and it
means the same mesh can be re-bound to a different skeleton just by recomputing the
B_j^{-1}s. One matrix per joint, computed once — a small price for keeping
everything else in friendly coordinates.
The single most common skinning bug is applying the joint's current transform straight to the vertex —
v' = M_j \, v — and dropping the B_j^{-1}. It
looks harmless, but it double-applies the bind transform: the vertex already sits at
its bind-pose world position, and M_j shoves it through the joint's full
placement again. In the bind pose you would get
v' = B_j \, v \ne v — the mesh is offset and warped before a single frame
of animation plays; rotate the joints and it flies apart into the notorious exploding-character mess.
The fix is the whole lesson: B_j^{-1} is exactly the piece that cancels the
bind, forcing the bind pose to be the identity M_j B_j^{-1} = I so that
deformation measures only the departure from bind. If your rig blows up on load, the missing inverse
bind matrix is the first suspect.