Carrying material through a blend

Once two shapes blend smoothly, their materials have to blend too, and the usual answers are either a hard seam or a second hand-rolled ramp that almost lines up. Neither is necessary: smin already computed the right weight and then discarded it.

Two blending circles with different materials. Left: nearest wins. Middle: a separate hand-tuned ramp. Right: smin's own blend weight.

The number is already there

The polynomial smooth minimum works by computing h, a clamped ramp of how close the two fields are relative to k, and interpolating with it. That h is not an implementation detail. It is the blend, and it is correct for anything else the two shapes carry:

float sminW(float a, float b, float k, out float h){
    h = clamp(0.5 + 0.5*(b - a)/k, 0.0, 1.0);
    return mix(b, a, h) - k*h*(1.0 - h);
}

float d      = sminW(a, b, k, h);
vec3  color = mix(colorB, colorA, h);   // free, and exactly co-located
float rough  = mix(roughB,  roughA,  h);
float emit   = mix(emitB,   emitA,   h);

Why the middle panel is the subtle failure

Panel one is obviously wrong: a hard color seam cutting across a soft geometric join. Nobody ships that twice. The seam is even on the right line, since a < b is exactly where h crosses one half. It is the hardness that is wrong.

Panel two is the trap. A separate ramp on b - a with its own width looks correct in isolation and is almost right. Its midpoint is even in the same place, because it is centered on the same a = b line. What does not match is the width. Here it is three times the fillet, so the color bleeds across both bodies instead of turning inside the join, and how much of each body it tints changes as the shapes move. It is the kind of wrongness that survives review because each frame looks fine.

Panel three cannot drift, because there is only one number.

Chaining, and the thing to watch

For a tree of blends, carry the material alongside the distance and blend it at every node with that node's own h. The material arrives at the top already correct.

The caveat is the same one the blend radius note ends on: chained smin is order dependent, so the material inherits that. Blending A with B then C gives a different color distribution from A with C then B, in exactly the places where it gives a different shape. That is consistent rather than buggy, but it does mean the build order of a creature is a material decision as well as a geometric one.

Rules of thumb

  1. Return h from your smin. It is free and it is the only correct weight.
  2. Never hand-roll a second ramp for color. It will not line up and the drift is animated.
  3. Blend everything the shapes carry with the same h: color, roughness, emissive, material id.
  4. For a hard material id, h > 0.5 and a < b are the same line, so either works. h earns its keep once the transition is soft.
  5. Chained blends are order dependent for material exactly as they are for shape.

All 61 notes How to use them Credits

If you find anything wrong, let me know at hello@andrewdetwiler.com and I'll get it updated.