Morphing between two shapes

Built on the polynomial smooth minimum by Inigo Quilez. Sources for this reference

Two fields, one parameter, and you have a morph. It is one of the genuinely magic properties of representing shapes as functions, and the obvious implementation has a failure mode worth knowing before you ship it in a transition.

Star to square. Left: a straight lerp of the two fields. Middle: a smin crossfade. Right: the two shapes alone.

The lerp is not wrong, it is unprincipled

d = mix(sdStar(p), sdBox(p), t);

This does produce a continuous transition, and for shapes that are close it looks fine. What it actually computes is the average of two distances, and the zero set of an average is not the average of two zero sets. So the intermediate surface is a shape that belongs to neither, and the way it gets there is not something you controlled.

Watch the star's points on the left. They do not retract, they dissolve, thinning uniformly until they vanish. Sometimes that is the effect you want. It is rarely the effect you asked for.

The crossfade keeps every frame a real shape

Push the outgoing shape away by growing its distance, pull the incoming one in, and blend the two with smin:

float K = 0.40;   // keep this SMALL relative to the shapes
d = smin(a + t*K, b + (1.0-t)*K, k);

Adding a constant to a field moves its surface outward by that amount, so a + t*K is the star shrinking away and b + (1-t)*K is the square arriving. At every value of t the result is a genuine smooth union of two genuine shapes, which is why the intermediate frames read as one object changing rather than two images cross-dissolving.

Neither one preserves anything

Worth saying plainly: neither approach preserves area, volume, or feature correspondence. A star point does not become a square corner, because nothing told it to. If you need specific features to map to specific features, that is a different and much harder problem, and a field morph is not the tool.

What a field morph is very good at: transitions where the audience should read "it changed" rather than "point A became point B". Dissolves, reveals, a UI element becoming another UI element, a creature shifting form mid-cutscene.

Rules of thumb

  1. Prefer the smin crossfade. Every intermediate is then a real shape.
  2. Adding a constant to a field offsets the surface. That is the whole mechanism.
  3. Keep the push SMALL relative to the shapes. Both terms are offset at once, so at the midpoint each is pushed by half of it, and too large a value shrinks the morph to nothing exactly halfway through.
  4. Ease t. A linear morph reads mechanical no matter which method you use.
  5. Neither method maps features to features. If you need that, this is the wrong technique.

All 61 notes How to use them Credits