Level 1 · ●○○
The Distance Picture
Prerequisites: Coordinates — nothing more.
Pick any point on this page. Now ask one question about it: how far is the nearest surface? That single number — measured for every point at once — is the whole subject of this site. It will carry us from a circle to shadows, cameras, fractals, and worlds that fit in four kilobytes. This level is about learning to see it.
And here is a comforting secret before we start: if you have ever written code like if (distance < radius) to check whether a click landed inside a circle, you have already used a signed distance function — unwittingly. You compared a distance to a boundary and branched on the sign. Everything below is that same instinct, given a name and taken seriously.
One number per point
Take the plane you know from school, with coordinates , and put a circle of radius at the origin. Now define a function: for every point of the plane, is the distance from to the nearest point of the circle — with one twist. If is inside the circle, we flip the sign and call the distance negative. Zero means you are standing exactly on the boundary.
That function is a signed distance function (SDF), and the picture of all its values at once is a distance field. Don't take it on faith — probe it:
Three things to notice while dragging. First, the number is honest: the yellow ruler always reaches the nearest point of the circle, and its length is exactly the field value. Second, the sign is doing real work — it splits the world into inside (negative, glowing cold) and outside (positive, warm). Third, the faint ring through the probe: every point on it has the same field value. Such a ring is called a level set, and the boundary itself is the zero level set — the set where .
How to read a field
A field is a number at every point, and numbers want to be seen. Here is the same idea painted three ways — and a first taste of more shapes than circles:
The contour stripes view is the one to internalize. Each band marks a ring of equal distance, like elevation lines on a hiking map; tight, even banding everywhere tells you the field is healthy. You will meet this exact visualization on every level of this site — including insidethe 3D renderers, where the bands are how we'll debug what the eye can't see.
The first formula
So far the field has been a picture. Here is the punchline of Level 1: for the circle, the entire field is one line of arithmetic. The distance from to the origin is (written length(p) in shader code), so the signed distance to a circle of radius is
Outside, and is positive; inside it is negative; on the boundary it is exactly zero. One subtraction, all three behaviors. In the shared library that draws this site, this formula is sdCircle exact:
Stop and let the framing land, because everything else on this site is a consequence of it: a shape is its distance function. The circle is not a list of points or a picture — it is length(p) - r, an object you can compute with. Geometry has become arithmetic. Next level we'll add and subtract shapes like numbers; two levels on, this same arithmetic will guide rays through 3D space.
How an SDF is written — now break it
Open view / edit the codeon the figure above and read the whole program. It is shorter than this paragraph: the renderer hands the shader your pixel's position (gl_FragCoord), two lines turn it into field coordinates p, one line computes the distance d, and fieldColor paints it. That one line — float d = ... — is the entire shape. Which makes it the most rewarding line on this page to vandalize. Switch to the ✎ edit & run tab and try, one at a time:
float d = abs(p.x) + abs(p.y) - r;— a diamond. But look closely at the stripes: they crowd tighter than before. This formula changes faster than 1 per unit traveled — it breaks the Lipschitz promise below, and Level 3 shows what that costs a renderer.float d = length(p) - r + 0.12 * sin(6.0 * atan(p.y, p.x));— a flower: the radius now depends on the angle. Welcome to procedural shape design.float d = min(length(p - vec2(0.6, 0.0)), length(p + vec2(0.6, 0.0))) - r;— two circles from onemin. You have just discovered Level 2 early.- Or sabotage honestly: misspell something and press run. The compiler complains, the last working shape keeps rendering, and nothing is lost.
Every centerpiece figure on this site carries the same ✎ edit & run tab — the melting blend of Level 2, the first 3D render of Level 3, the full renderer of Level 4, the studio of Level 5. The code panels are not documentation; they are the running program, handed to you mid-flight.
Go deeper: exact vs bound — what the badges mean★★☆
A distance function is exact exactwhen it returns the true Euclidean distance to the shape's boundary, everywhere. Every formula in this level is exact, and the verification script in this site's source (scripts/verify-sdfs.ts) checks each one numerically against brute-force sampling of the boundary.
Some useful formulas settle for less: a bound bound never overestimatesthe true distance (and gets the sign right), but may report a smaller number than the truth. The library's octahedron, for instance, uses the cheap formula (|x|+|y|+|z| − s) · 0.57735027 — the constant is — which underestimates by up to ~29% near edges. Why tolerate that? Because the algorithm that turns fields into images (Level 3) only ever asks: “how far can I safely travel?”An underestimate is a cautious answer — slower, never wrong. An overestimate would let rays tunnel through walls. The badges on this site track exactly this distinction, and when an operation breaks exactness (Level 2's smooth blend, for one), the prose will say so.
Go deeper: why the box formula works★★☆
The library's box is four lines:
float sdBox2(vec2 p, vec2 b) {
vec2 d = abs(p) - b;
return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);
}abs(p)first folds the plane into the positive quadrant — a box is symmetric, so one corner's worth of math covers all four. Then d = abs(p) − b measures how far you stick out past the half-extents on each axis, and the two terms split the world cleanly:
- Outside past a corner: both components of are positive, and
length(max(d, 0.0))is the straight-line distance to that corner — Pythagoras, exactly. - Outside past an edge: only one component is positive;
maxzeroes the other, and the length collapses to that one coordinate — perpendicular distance to the edge. - Inside: both components are negative, the first term is zero, and
min(max(d.x, d.y), 0.0)picks the least negative overshoot — the distance to the nearest wall, with the inside-is-negative sign built in.
No case analysis in the code; the cases fall out of max and min. This pattern — fold with abs, split with max — builds half the library.
Go deeper: Lipschitz continuity, in plain words★★★
Walk through a distance field at one meter per second. How fast can the field value change? At most one unit per second — because moving a meter changes your distance to anything by at most a meter. Formally, a signed distance function satisfies
for all points — it is Lipschitz continuous with constant 1. Where the field is smooth, its gradient has length exactly 1 (a fact Level 4 turns into surface normals, for free).
This innocuous-looking property is the load-bearing wall of the whole edifice. Read it backwards: if the field says 0.4, there is no surface within 0.4 units in any direction. That guarantee — distance as a certificate of empty space — is what lets Level 3's renderer leap through space in safe strides instead of inching along. A “bound” field keeps the guarantee by underestimating; a broken field that overestimates (you'll be able to build one in Level 2 and watch the artifacts) violates it, and the renderer pays in holes and ghosts.
What you now know
- A distance field assigns every point one number: distance to the nearest surface, negative inside, zero on the boundary.
- Level sets are rings of equal distance; contour stripes make them visible, and the zero level set is the shape.
- The circle's entire field is
length(p) − r— a shape is its distance function; geometry becomes arithmetic. - Formulas are labeled exact or bound; a field never changes faster than 1 per unit traveled (Lipschitz), which is a promise of empty space.
You can measure one shape. But arithmetic doesn't stop at one number: what is the minimum of two distance fields? Level 2 answers — and the answer melts.