Introduction

Pick any shape — a circle, a rounded box, a letter "A". Now assign every point in the plane a single number: the distance to the nearest point on the shape's boundary. Points outside get a positive number; points inside get the same distance but negative; points exactly on the surface get zero.

That function is a Signed Distance Field (SDF).

The sign is the whole trick. Positive means "outside," negative means "inside," and the zero level set is the shape itself. You never need to store the boundary explicitly — the shape is implicit in the function's level sets. Want to shrink or grow the shape? Add a constant to the function. Want a rounded corner? Clamp the distance. Want to blend two shapes into one smooth blob? Take the minimum of their SDFs (or a smooth approximation of it). All of these operations are a line of math, not a mesh edit.

SDFs were popularized in computational geometry and computer graphics alike. Valve used them in 2007 to render crisp vector-quality text on GPU hardware at a fraction of the cost of traditional methods. Ray marchers — algorithms that step along a ray until f(p)0f(\mathbf{p}) \leq 0 — turn an SDF into a raytracer with a loop of a dozen lines. And because the function is analytic, the surface normal at any point is simply the gradient f\nabla f — no triangle soup required.

This article unpacks how SDFs are defined, why blending works, and where you will find them quietly running the graphics on your screen right now.

Try It

Below, two circular blobs are rendered by evaluating their SDFs on a canvas pixel by pixel. Drag each blob with your mouse and watch them smoothly melt into one another when they get close — that is the smooth-union operator at work.

<!-- {{c_demo_title}} -->
<canvas id="sdf-canvas" width="480" height="300" aria-label="{{canvas_aria}}"></canvas>
<div class="controls">
  <label>{{label_smooth}} <input id="k-slider" type="range" min="0" max="120" value="60" /></label>
  <span id="k-val">k = 60</span>
</div>
<div class="info" id="info">{{hint_drag}}</div>
<div class="btns">
  <button id="reset-btn" type="button">{{btn_reset}}</button>
</div>
/* {{c_layout}} */
* { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; margin: 0; background: #f5f7fa; color: #222; }
canvas { display: block; border-radius: 10px; cursor: grab; width: 100%; max-width: 480px; touch-action: none; }
canvas:active { cursor: grabbing; }
.controls { display: flex; align-items: center; gap: 1rem; margin: .6rem 0 .3rem; flex-wrap: wrap; }
label { font-size: .9rem; display: flex; align-items: center; gap: .4rem; }
input[type=range] { width: 120px; }
#k-val { font-size: .85rem; color: #555; }
.info { font-size: .88rem; color: #444; min-height: 1.3em; margin-bottom: .4rem; }
.btns { display: flex; gap: .5rem; }
button { font: 600 14px system-ui; padding: .4rem .85rem; border: 1px solid #1d3557;
         background: #1d3557; color: #fff; border-radius: 8px; cursor: pointer; }
// Code not found

The solid colour shows the inside (where f<0f < 0). The thin boundary is the zero level set — the actual shape. The gradient shading outside reveals the distance field itself, lighter farther from the surface. Drag one blob onto the other and notice how the junction softens: no sharp corner, just a continuous blend. No mesh was edited; the merge is pure arithmetic on two distance functions.

How Blending Works

The core operations

Let ff and gg be two SDFs. Three basic set operations become arithmetic:

union(f,g)=min(f,g)\text{union}(f,g) = \min(f, g)

intersection(f,g)=max(f,g)\text{intersection}(f,g) = \max(f, g)

subtraction(f,g)=max(f,g)\text{subtraction}(f,g) = \max(f, -g)

The smooth union replaces the hard min\min with a polynomial blend introduced by Inigo Quilez. With smoothness parameter k>0k > 0:

h=max ⁣(kfg,  0)/kh = \max\!\bigl(k - |f - g|,\; 0\bigr) / k

smin(f,g,k)=min(f,g)h2k/4\text{smin}(f, g, k) = \min(f, g) - h^{2} \cdot k / 4

When ff and gg are far apart this is just min\min; near the boundary where fg<k|f - g| < k, it smoothly interpolates, creating the organic "blobby" junction you see in the demo.

Finding the surface: sphere tracing

An SDF tells you the radius of the largest empty sphere centred at your current point. A ray marcher exploits this:

  1. Start at position p\mathbf{p} along the ray.
  2. Evaluate r=f(p)r = f(\mathbf{p}).
  3. Step forward by rr — you are guaranteed not to skip over the surface.
  4. Repeat until rεr \leq \varepsilon (hit) or the total distance exceeds a budget (miss).

Each step doubles your proximity in the ideal case, so convergence is O(log(1/ε))O(\log(1/\varepsilon)) — effectively constant for any scene at reasonable precision. This is why GPU shaders can ray-march an entire world of blended SDFs in real time: no acceleration structure, just the distance function itself.

Normals for free

Because SDFs satisfy f=1|\nabla f| = 1 almost everywhere (the eikonal equation), the unit surface normal at any point p\mathbf{p} with f(p)0f(\mathbf{p}) \approx 0 is simply:

n^=f(p)\hat{n} = \nabla f(\mathbf{p})

Approximate this with finite differences and you get analytically correct lighting with no vertex normals, no tangent frames — just the field itself.

Where It Matters

SDFs appear wherever a program needs to reason about distance to a surface:

  • Font rendering on GPUs: Valve's Chris Green (2007) showed that a single low-resolution SDF texture can render a glyph at any size with crisp edges — the shader just checks the sign. This is still how many game engines render text.
  • Procedural 3D graphics: demoscene and shader artists (Shadertoy, GLSL sandbox) build entire sculpted worlds by composing SDF primitives. Engines like Unity and Unreal expose SDF-based field rendering for particle collisions and ambient occlusion.
  • Collision detection: robotics and physics engines store the environment as an SDF; querying distance and gradient gives both penetration depth and push-out direction in a single lookup.
  • Neural implicit surfaces (NeRF variants, DeepSDF, 2019): deep networks learn to output the SDF of an object from point-cloud or multi-view data. The surface is never stored as a mesh; it is the zero set of the learned function.
  • Medical imaging: signed distance maps let surgeons measure how close a tumour is to a vessel boundary by reading a single voxel value.

Understanding SDFs is a natural companion to ray tracing and connects to the broader theme of implicit representations in geometry and computational geometry.

Conclusion

A signed distance field collapses the complexity of a shape into the simplest possible representation: a number at every point in space. That number is positive outside, negative inside, and exactly zero on the surface. From that one idea flow smooth blending, sphere-traced rendering, analytic normals, font rasterisation, and neural 3D reconstruction — all without storing a single triangle.

The next time a game engine renders a rounded button, a shader blobs two spheres together, or an MRI viewer shows tissue margins, there is a good chance a signed distance field is doing the heavy lifting. Shapes are functions. Functions are flexible. That is the whole secret.

Share this article

Pick a channel — or use your device's native share sheet.

Comments

Loading comments...

https://www.kipuhub.com/en/article/signed-distance-fields/Content licensed under CC BY-NC 4.0.