Level 2 · ●○○
An Algebra of Shapes
Prerequisites: Level 1.
Level 1 ended with a heresy: a shape is its distance function. Here is why that matters. Functions return numbers, and numbers have arithmetic — so if shapes are functions, shapes have arithmetic too. This level builds that algebra: three boolean operations that cost one comparison each, a blend that melts geometry like wax, and a family of tricks that conjure infinite copies for free.
min, max, and the algebra of solids
Suppose shape A has field and shape B has field , both signed the usual way: negative inside. What is the field of A-or-B— the union? Stand at any point: you are as close to the union as you are to whichever shape is nearer. And if either field says “inside” (negative), you are inside the union. Both facts at once:
Intersection is the mirror image: you must be inside both, so the larger (least inside) value rules. Subtraction is intersection with the complementof A — and negating a signed distance field flips inside and outside, so A's complement is simply . Three set operations from two comparisons and a minus sign:
One honest footnote, because this site promised honesty: min gives the true distance everywhere outside the union exact, but inside an overlap it can report a distance to a boundary that no longer exists (it got swallowed by the other shape). Intersection and subtraction inherit the same caveat bound. The values are never too large in magnitude — they remain safe bounds — which, as Level 3 will show, is the only property the renderer actually needs.
The smooth minimum — where it starts to feel alive
min has a personality flaw: it is decisive. At every point one shape wins outright, so where the winners change, the combined surface keeps a hard crease. But nothing forces us to be decisive. Near the crossover — wherever and are within of each other — we can let the two fields negotiate:
That is the library's opSmoothUnion bound, written exactly as it ships (mix(b, a, h) is the linear blend ). Far from the crossover, clamps to 0 or 1 and you get plain min back. Near it, the blend term bulges the field outward, and the crease becomes a fillet. Drag the slider slowly:
This one slider is the gateway to generative art, character modeling, and every “blobby” aesthetic you have seen in demoscene work. Two formulas plus equals an organism. It is also our first deliberate trade: smoothness for exactness — the Go deeper below has the fine print.
Domain tricks: transform space, not the shape
Every operation so far acted on the fields' outputs. The other half of the algebra acts on the input — the point itself — before the field ever sees it. Want the shape somewhere else? Don't move the shape; ask about a moved point. Each trick below is one line applied to :
- Repetition:
q = mod(p + 0.5*c, c) - 0.5*cfolds all of space into one cell of size — the motif repeats forever, for the price of onemod. exact while the shape fits in its cell. - Symmetry:
q = vec2(abs(q.x), q.y)folds the left half-plane onto the right — instant mirror image. - Rotation:
q = rot2(angle) * qrotates space backwards, so the shape appears rotated forwards. Distances survive untouched — rotation is rigid. - Scaling:
d = f(p / s) * s. Shrinking space makes the shape bigger, but it also shrinks the field's values — the trailing* srestores honest distances. Forget it and you break the Lipschitz promise from Level 1.
Internalize the inversion, because it is the deepest habit of field-thinking: the shape never moves; space is folded, mirrored, and tiled around it. An infinite forest costs the same as one tree.
The mini-studio: your first payoff
You now hold every tool a 2D generative artist needs: a library of exact shapes, a melt knob, and infinite repetition. The studio below composes five random library shapes with opSmoothUnion, optionally tiles them, and lets you export the result — at double resolution, straight from the shader that drew it.
The field as an oracle
One more gift before the deep dive panels — and it costs nothing you don't already own. Ask the field its value at any point inside a shape. That number is not just a distance: it is the radius of the largest circle that fits there, guaranteed by Level 1's no-surface-within-this-distance promise. Which means the classic generative-art problem of packing shapes snugly — usually solved with collision tests and rejection loops — collapses into a three-step chant: ask the field, place the circle, min it in.
Two things worth savoring here. First, the algorithm above runs in plain JavaScript on the CPU — no shader computes it, only draws it. Distance fields are mathematics, not GPU technology; plotter artists drive pen-and-paper robots with these same formulas. (This framing — and the packing trick itself — is a staple of the creative-coding world; Piter Pasma's Genuary tutorial is a lovely shader-free introduction.) Second, file away the shape of the move — the field tells you how big a step is safe, you take exactly that step, then ask again. Next level, that exact move, aimed along a ray instead of around a circle, becomes a 3D renderer.
Go deeper: why smin breaks exactness★★☆
The blend term pushes the field down near crossovers — the combined value becomes smaller than the true distance to the new, smoothed surface. The result is still a valid lower bound (the verifier checks numerically), but it is no longer exact anywhere near the weld, even outside the shape.
There is a second, subtler casualty: the smoothed field's level sets are no longer parallel to the surface at uniform spacing — look closely at the stripes near a weld in the morpher and you can see them stretch. Tools that assume exactness (uniform-step contouring, some text-rendering tricks) misbehave on smin fields; the sphere tracer of Level 3 merely slows down.
Go deeper: polynomial vs exponential smin★★★
The quadratic formula above is the workhorse: cheap, branchless, and exactly minoutside the blend band. It has siblings (described here for comparison; this site's library ships only the polynomial form). The exponential smooth minimum
blends globally — every shape influences every point, however slightly — and is associative: melting A with B then C gives the same field as any other order, which the polynomial version cannot promise. The price is two exp calls and a field that never quite returns to plain min. For interactive blends of a handful of shapes, the polynomial wins; for N-way organic merges (metaballs), the exponential family is the principled choice.
Go deeper: bound fields — what “still works” actually means★★☆
After this level most of our fields are bounds, not exact distances. It is worth being precise about the contract a bound field keeps:
- the zero level set is still exactly the surface — smin, min and max only deform values away from zero, they never move where zero sits relative to the blended shape they define;
- the value's magnitude never exceedsthe true distance to that surface — the “promise of empty space” from Level 1 survives, just more timidly;
- the sign still says inside/outside, truthfully.
What is lost is only efficiency and uniformity: an algorithm consuming the field must treat the value as a cautious promise, not a measurement. Every renderer in the rest of this site is built to need nothing more.
What you now know
- Booleans are comparisons:
min= union,max= intersection,max(−a, b)= subtraction — exact outside, safe bounds inside overlaps. - The smooth minimum trades exactness for a fillet of width — the single most seductive idea in field-based art.
- Space, not shapes, gets transformed:
modrepeats,absmirrors, rotation rigidly turns, and scaling must pay back its* s. - Composition + melt + repetition = a generative art studio in a dozen lines of shader.
Everything so far lives in a flat plane — but length(p) − r never asked how many coordinates has. Give it three and it answers with a sphere. The only real question is how to see it… and the field itself will tell us how far we can safely march.