Initializing 3D Canvas...

SDF Basics

2 min read•1 page

Signed Distance Field:

1. For each spatial sample, compute distance to the closest surface point. 2. Apply sign convention: negative inside, positive outside. 3. The zero-level isosurface defines the shape boundary.
python
1# Signed Distance Field concept
2# For any point P in space, SDF(P) returns:
3# negative -> P is inside the shape
4# zero -> P is on the surface
5# positive -> P is outside the shape
6
7def sdf_example(point, center, radius):
8 """Signed distance from point to sphere surface."""
9 import math
10 dx = point[0] - center[0]
11 dy = point[1] - center[1]
12 dz = point[2] - center[2]
13 dist = math.sqrt(dx*dx + dy*dy + dz*dz)
14 return dist - radius # negative inside, positive outside

A Signed Distance Field maps every point in space to its shortest signed distance to the nearest surface. Negative values indicate interior, positive values indicate exterior, and zero marks the boundary.

1 min read•1 page

Sphere SDF:

1. Compute Euclidean distance from query point to sphere center. 2. Subtract the radius to get signed distance. 3. Result is negative inside, zero on surface, positive outside.
python
1# Sphere SDF
2def sdf_sphere(point, center, radius):
3 """Returns signed distance from point to sphere surface."""
4 import math
5 dx = point[0] - center[0]
6 dy = point[1] - center[1]
7 dz = point[2] - center[2]
8 return math.sqrt(dx*dx + dy*dy + dz*dz) - radius

The sphere SDF is the simplest primitive: distance from the center minus the radius. The isosurface at distance zero forms a perfect sphere.

Radius
3.00
2 min read•1 page

Box SDF:

1. Fold point into positive octant using absolute values. 2. Subtract half-extents to get per-axis offsets. 3. Combine positive offsets (outside distance) with max negative offset (inside distance).
python
1# Box SDF (axis-aligned)
2def sdf_box(point, center, half_extents):
3 """Signed distance from point to axis-aligned box."""
4 import math
5 # Compute distance per axis from center, subtract half-extents
6 dx = abs(point[0] - center[0]) - half_extents[0]
7 dy = abs(point[1] - center[1]) - half_extents[1]
8 dz = abs(point[2] - center[2]) - half_extents[2]
9
10 # Outside distance: length of positive components
11 outside = math.sqrt(max(dx, 0)**2 + max(dy, 0)**2 + max(dz, 0)**2)
12 # Inside distance: largest negative component
13 inside = min(max(dx, max(dy, dz)), 0.0)
14
15 return outside + inside

The box SDF uses absolute-value symmetry and component-wise clamping to compute exact signed distance to an axis-aligned box.

Box Width
3.00
1 min read•1 page

Torus SDF:

1. Project query point onto XZ plane, compute distance to major ring. 2. Form 2D vector from ring distance and Y height. 3. Subtract minor radius to get signed distance.
python
1# Torus SDF
2def sdf_torus(point, major_radius, minor_radius):
3 """Signed distance to a torus centered at origin, axis along Y."""
4 import math
5 # Project point onto XZ plane
6 qx = math.sqrt(point[0]**2 + point[2]**2) - major_radius
7 qy = point[1]
8 return math.sqrt(qx*qx + qy*qy) - minor_radius

The torus SDF reduces a 3D problem to 2D by projecting onto the plane of revolution, then computing distance from the ring centerline.

Major Radius
3.00
Minor Radius
1.00
2 min read•1 page

SDF Transform:

1. Build inverse transform matrix from translation and rotation. 2. Apply inverse to query point before SDF evaluation. 3. Distance value is preserved under rigid transforms (no scaling).
python
1# Rigid transform for SDF evaluation
2import numpy as np
3
4def sdf_transformed(point, sdf_fn, translation, rotation_matrix):
5 """Evaluate SDF by inverse-transforming the query point."""
6 # Inverse transform: undo translation, then undo rotation
7 p_local = rotation_matrix.T @ (np.array(point) - np.array(translation))
8 return sdf_fn(p_local)
9
10# Key insight: instead of transforming the shape,
11# inverse-transform the query point into local space.

To evaluate an SDF on a transformed shape, we inverse-transform the query point back into the primitive's local coordinate frame.

Translate X
2.00
Rotation (deg)
45.00
2 min read•1 page

SDF Scale:

1. Divide query point by scale factors to map to unit space. 2. Evaluate SDF in unit space. 3. Multiply result by minimum scale factor for conservative bound.
python
1# Non-uniform scale for SDF
2def sdf_scaled(point, sdf_fn, scale_factors):
3 """Evaluate SDF on non-uniformly scaled shape.
4
5 Warning: Non-uniform scale breaks exact distance.
6 Compensate by dividing result by max scale factor.
7 """
8 import numpy as np
9 s = np.array(scale_factors)
10 p_local = np.array(point) / s
11 # Approximate correction for non-uniform scale
12 return sdf_fn(p_local) * min(s)

Uniform scaling preserves SDF accuracy by dividing the query point and multiplying the result. Non-uniform scale breaks exactness and requires conservative approximation.

Scale X
1.00
Scale Y
1.50
2 min read•1 page

SDF Gradient:

1. Sample the SDF at 6 offset positions (two per axis). 2. Compute partial derivatives via central differences. 3. Normalize the resulting gradient vector.
python
1# Normal estimation via central differences (gradient of SDF)
2def sdf_normal(sdf_fn, point, eps=1e-4):
3 """Compute surface normal using finite differences."""
4 nx = sdf_fn([point[0]+eps, point[1], point[2]]) - \
5 sdf_fn([point[0]-eps, point[1], point[2]])
6 ny = sdf_fn([point[0], point[1]+eps, point[2]]) - \
7 sdf_fn([point[0], point[1]-eps, point[2]])
8 nz = sdf_fn([point[0], point[1], point[2]+eps]) - \
9 sdf_fn([point[0], point[1], point[2]-eps])
10
11 import math
12 length = math.sqrt(nx*nx + ny*ny + nz*nz)
13 return [nx/length, ny/length, nz/length]

The gradient of an SDF at a surface point gives the outward surface normal. We approximate it numerically using central finite differences.

Sample Count
8.00
2 min read•1 page

SDF Projection:

1. Evaluate SDF distance at current position. 2. Compute gradient (normal direction) via central differences. 3. Step along negative gradient by the distance value. Repeat until converged.
python
1# Surface projection using SDF gradient descent
2def project_to_surface(sdf_fn, start_point, max_iter=20, eps=1e-4):
3 """Project a point onto the zero isosurface via gradient descent."""
4 p = list(start_point)
5 for _ in range(max_iter):
6 d = sdf_fn(p)
7 if abs(d) < eps:
8 break
9 n = sdf_normal(sdf_fn, p, eps)
10 # Step along negative gradient by distance value
11 p = [p[i] - d * n[i] for i in range(3)]
12 return p

To find the closest surface point, iteratively step along the negative gradient by the SDF value until convergence to the zero isosurface.

Start Point X
5.00

Related Concepts