◆ Signed Distance

Level 3 · ●●

The March Into 3D

Prerequisites: Levels 1–2. Vectors introduced in-page.

Here is a deal almost too good to be honest: everything you built in two dimensions comes to 3D unchanged. length(p) - r never asked how many coordinates pp carries. Give it two and it draws a circle; give it three and it describes a sphere. The min/max algebra, the smooth minimum, the domain tricks — all of them survive verbatim. What does notsurvive is the screen. A monitor is stubbornly flat, so for the first time we must ask: how do you turn a 3D field into a 2D image? The answer is this site's golden key.

Go deeper: vectors as arrows — all the 3D math you need☆☆

A vector is an arrow: it has a length and a direction. In coordinates we write it by its components, v=(x,y,z)v = (x, y, z) — go xx across, yy up, zz toward you. Two kinds of arrows matter here:

  • Positions: an arrow from the origin to a point. “The camera stands at (1.6,0.2,0)(-1.6,\, 0.2,\, 0).”
  • Directions: an arrow that only says which way. We keep these at length 1 (“normalized”) so that position + t · direction walks exactly tt units along the arrow.

Length is Pythagoras with one more term: v=x2+y2+z2\|v\| = \sqrt{x^2 + y^2 + z^2}length(v) in shader code, and the reason length(p) - r works in any dimension. normalize(v) is v/vv / \|v\|: same direction, length 1. One more tool arrives in Level 4 — the dot product, which measures how much two arrows agree — but you can march perfectly well without it today.

Same formulas, three components

A 3D distance field assigns a number to every point of space: distance to the nearest surface, negative inside. You cannot display all of it at once, but you can cut it. Below, the sphere's field length(p) - 0.7 is sliced by a movable plane — and every slice is an ordinary Level-1 picture:

Slicing a 3D field
length(p) − 0.7 with p = (x, y, z). Each slice of the sphere's field is an ordinary Level-1 circle field — smaller as the plane leaves the center, empty past the poles.

The problem: a camera asks where rays hit

Every camera, real or rendered, answers one question per pixel: looking along this direction, what do I see first? Rendering by shooting a ray through each pixel and finding its first intersection is called raycasting, and for a handful of shapes it can be done with pure algebra — a ray hits a sphere where a quadratic equation says so, and that's how classical raytracing renders its glass balls, beautifully and exactly.

But look at what Level 2 left in our hands: shapes that have been melted together, repeated to infinity by a mod, bent by domain tricks. There is no quadratic formula for “two circles at k=0.3k = 0.3, mirrored and tiled.” Algebraic intersection needs a formula per shape; our shapes no longer have names. What they have — all they have — is the one thing every field provides: at any point, a number promising how far the nearest surface is. We need a way to find ray hits that asks only that.

The golden key: leap exactly as far as the field allows

Stand at the ray's origin and ask the field: d=f(p)d = f(p). By Level 1's Lipschitz promise, no surface exists within dd of you — in any direction, and in particular along the ray. So step forward exactly dd. Ask again. Step again:

t0=0,ti+1=ti+f(ro+tird)t_0 = 0, \qquad t_{i+1} = t_i + f(\,\mathit{ro} + t_i\,\mathit{rd}\,)

When ff falls below a hair's width, you are standing on the surface; if tt runs past the horizon, the ray hit sky. That is the entire algorithm — sphere tracing, named for the spheres of guaranteed-empty space it leaps through. Watch it work, one honest step at a time:

Showpiece A — the sphere-trace stepper
steps0marching…
Each yellow circle is the field's promise: no surface within this radius. The ray leaps exactly that far. Aim the ray so it grazes the blob's edge and watch the step count climb — the march never cheats, so near-misses cost real work.
Showpiece B — first light
Same formulas as the stepper — promoted to three components — and a camera standing where the ray began. One march per pixel and the field becomes an image. The step-cost view shows grazing rays glowing along every edge: the stepper's lesson, drawn by the renderer itself.

Two behaviors deserve your attention in the stepper. Far from everything, the field is large and the ray crosses the scene in two or three giant leaps — empty space is cheap. Aimed near an edge, the safety circles shrink and the march tiptoes — grazing rays are expensive, which the step-cost view above renders as a glowing halo around every silhouette. And notice what showpiece B really is: the moment we run the same march for every pixel, the diagram becomes a renderer. White where rays land, black where they escape. It is unlit, flat, and a little anticlimactic — deliberately. Level 4 is one long crescendo from this silhouette to the landing page's hero, and every step of it is just more questions asked of the same field.

In the library, the march ships as raymarch— the loop you can read in either showpiece's code panel, with MAX_STEPS, a surface epsilon, and a far limit as its only knobs.

Go deeper: convergence, Lipschitz, and over-relaxation★★★

Why does the march terminate at all? For an exact field, each step covers the full distance to the nearest surface. If the ray actually hits, the remaining distance shrinks at worst geometrically near the surface (head-on rays converge in a handful of steps; the pathological case is a ray parallel to a nearby wall, where each step is bounded by the wall clearance — that is precisely the grazing halo). The Lipschitz bound is what makes the leap safe: a field with Lipschitz constant L1L \le 1 can never hide a surface inside the sphere of radius f(p)f(p). If L>1L > 1 somewhere — a displacement cranked too high, a scale missing its * s — the promise breaks and rays tunnel through geometry.

Because cautious steps waste work in open space, production marchers often over-relax: step ωf(p)\omega \cdot f(p) with ω(1,2)\omega \in (1, 2), and fall back to the safe step if the next sample reveals the gamble overshot (the spheres of two consecutive steps must overlap; if they don't, retreat). Typical speedups are 20–40% on open scenes. The marcher in this site's library stays at ω=1\omega = 1 — pedagogy prefers honesty to a free lunch with fine print.

Go deeper: when the field is only a bound — failure cases★★

Everything above assumed the field tells the truth. A bound field (smin welds, interiors of booleans, the octahedron shortcut) tells a cautious truth: never too large, possibly too small. Sphere tracing survives — smaller leaps, same guarantee — it just slows down in proportion to how timid the bound is.

What actually goes wrong in practice:

  • Overestimating fields (broken scaling, aggressive displacement): rays leap past thin features and surfaces develop holes that flicker with the camera.
  • Severely timid bounds: step counts explode and the renderer hits MAX_STEPS before the surface — visible as a dark or missing silhouette edge, often misread as a shading bug.
  • Epsilon tuning: the “close enough” threshold trades a slightly inflated surface (large ε) against banding and step noise (small ε). Most artifacts you will ever see in raymarched work are one of these three.
Go deeper: raymarching vs raytracing vs rasterization★★

Three ways to put a scene on a screen, honestly compared. They are answers to different questions, not competitors for one crown:

Sphere-traced raymarchingAnalytic raytracingRasterization
Scene descriptionone distance function (or bound)intersection formula per shapetriangle lists
Finds a hit byiterating safe leapssolving equations exactlyprojecting triangles, z-buffer
Lovesblends, repetition, fractals, fieldsspheres, planes, quadrics; physical opticshuge meshes at 60 fps; hardware
Cost driversteps per ray (grazing rays!)rays × objects (until trees help)triangles × overdraw
Weak spotthin features, timid boundsshapes without formulasglobal effects need add-ons

The deepest difference: rasterization starts from the geometry and asks which pixels it covers; both ray methods start from the pixel and ask what it sees. And within ray methods — if your shape has an intersection formula, analytic raytracing is exact and fast; the moment you melt, repeat, or displace, the formula evaporates and the march is what remains. Level 5 returns to raytracing for reflections, where the two approaches happily cooperate.

What you now know

  • 2D formulas are 3D formulas — length(p) − r with a third component is a sphere, and slices of 3D fields are Level-1 pictures.
  • Rendering = one ray per pixel asking what do I see first? Analytic intersection answers it for textbook shapes; melted, repeated shapes have no formula.
  • Sphere tracing: leap exactly f(p)f(p), the distance the field guarantees empty — iterate to the surface. Empty space is cheap; grazing rays are expensive.
  • Run the march for every pixel and the field is already a renderer — flat and unlit, for now.

A white silhouette knows where the surface is, but nothing about which way it faces, what color it wears, or what stands between it and the light. Level 4 asks the field five more questions — and the silhouette becomes a photograph.

Level 4Light, Shadow, and a Camera