Building a figure out of a field
Built on the polynomial smooth minimum by Inigo Quilez. Sources for this reference
Built on the exact 2D rounded cone, which is the tapered limb primitive by Inigo Quilez. Sources for this reference
A character made of distance fields is not a modeling problem, it is a rigging problem. Compute the joints first, in world space, exactly as a skeleton would. Hang primitives off them. Everything that makes it move happens before the field is ever evaluated.
Pick a proportion system before you pick a shape
The figure above is four heads tall. That is a choice, and the important part is that it is a system: the head is a quarter of the height, the legs are 45 percent of it, the limbs are about half a head wide, and there is deliberately almost no waist. Every number comes out of one table.
A realistic adult is a different system, around seven and a half to eight heads, with legs at half the height and a waist clearly narrower than both chest and hips. Either is fine. What does not work is a figure belonging to no system at all, which is what you get by picking each measurement to look right on its own: the result reads as wrong and nobody can say why. If your figure is going in front of people, write the table down first, then check the geometry against it rather than against your eye.
Two primitives carry the whole thing
A capsule is a segment with thickness, which is a bone. A tapered capsule is a bone that gets thinner along its length, and it is the one that matters: constant radius reads as plumbing, and a taper reads as an arm.
float sdCone(vec2 p, vec2 a, vec2 b, float ra, float rb){
vec2 pa = p-a, ba = b-a;
float h = clamp(dot(pa,ba)/dot(ba,ba), 0.0, 1.0);
return length(pa - ba*h) - mix(ra, rb, h);
}
The skeleton is ordinary code
Nothing about the animation touches the field. An elbow is the shoulder plus a rotated offset; a hand is the elbow plus another. That is forward kinematics, and it is a few lines of vector math. The field function receives finished joint positions and does not know a pose exists.
Which is why this scales. Adding a walk cycle, a lean or a reach means changing joint math, not shape math.
A joint has limits, and a hinge has a direction
"A joint's transform is its parent's followed by its own rotation" is true and it is not the whole story. A knee and an elbow are hinges: one axis, and one direction of travel. Nothing in the maths knows that, so it has to be said out loud:
float hinge(float flex, float maxFlex){
return clamp(flex, 0.0, maxFlex);
}
Skip it and the usual thing happens. A walk cycle gets driven off a single signed sine, which is the obvious way to write one, and for half of every stride the knee folds forwards. The result is not obviously broken frame by frame. It just reads as rubbery, and the word people reach for is noodle.
The same clamp is why the figure above has two flexion events per leg per stride rather than one: a small one just after the foot lands, as the leg takes the weight, and a large one in mid swing to clear the ground. One sine cannot produce both, which is a good way to notice that a walk is not a sine wave in the first place.
Every blend radius is relative
Each joint blends with k at about 0.55 of the local limb radius rather
than a constant. Use one number everywhere and the wrists and ankles drown, because
the same k that is a gentle fillet at the shoulder is most of the limb at
the hand. This is the same failure the
blend radius note shows directly.
Light it from the distance, not the gradient
The obvious move is to use the field gradient as a normal. Do not. Inside a shape the
gradient points away from the nearest edge, so it holds one constant direction across
whole regions and the interior renders as flat facets meeting along the medial axis.
Treat the distance as a height instead: near the edge the surface turns over, deep
inside it faces the viewer. That is a dome, and it costs one sqrt.
Rules of thumb
- Joints first, in world space. The field function should take positions, never angles.
- Tapered capsules for limbs. Constant-radius capsules read as pipes.
- Blend radius proportional to the local limb radius, never global.
- Bevel the normal off the distance. The raw gradient facets.
- Clamp hinge joints. A knee that can bend both ways is the difference between a walk and a noodle.
- Scroll the ground at the stride rate, or a perfect gait still moonwalks.
- A rim light just inside the silhouette is what keeps the figure readable when it overlaps anything.
One email when something new goes up. No newsletter, no schedule, nothing else.
Double opt-in, so watch for a confirmation email. Unsubscribe any time.