SDF Transformations & Curves
2 min read•1 page
Unlike boundary meshes, SDFs are transformed by applying the inverse transform to the query point $p$ before evaluating the distance function. This lets us bend, twist, or duplicate geometry infinitely with zero memory overhead.
Deformation Operators:
1. Translation / Rotation: $f(T^-1(p))$. Query point is shifted/rotated opposite to the desired movement. 2. Infinite Repetition: Spatial domain folding using a modulo operator $mod(p, s) - 0.5s$. 3. Twist / Bend: Varying the rotation angle dynamically as a function of the query point's coordinate (e.g. height $y$).
python
1# Modifiers work by transforming the query point 'p' in reverse2def op_translate(p, offset):3 return p - offset45def op_repeat(p, size):6 # Map p to local repeated cell7 return Vector3(8 (p.x % size) - 0.5 * size,9 p.y,10 (p.z % size) - 0.5 * size11 )1213def op_twist(p, k):14 # Twist angle proportional to height (y)15 angle = p.y * k16 c, s = cos(angle), sin(angle)17 rx = p.x * c - p.z * s18 rz = p.x * s + p.z * c19 return Vector3(rx, p.y, rz)
Modifier (0=Translate/Rotate, 1=Repeat, 2=Twist)
0.002 min read•1 page
Calculating distances to curves is essential for outline rendering and wireframe effects. A line segment has a straightforward projection calculation. A quadratic Bezier curve is more complex, requiring us to solve a cubic equation to find the closest point.
Projection Mathematics:
1. Segment Projection: Project query point $p$ onto the infinite line of the segment, then clamp to the boundaries $[0, 1]$. 2. Bezier Closest Point: The vector from the closest point on the Bezier curve $B(t)$ to $p$ must be orthogonal to the tangent vector $B'(t)$, yielding $dot(B(t) - p, B'(t)) = 0$.
python
1def sd_segment(p, a, b):2 pa = p - a3 ba = b - a4 # Clamped projection factor5 t = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0)6 return length(pa - ba * t)78def sd_quadratic_bezier(p, a, b, c):9 # Find parameter t in [0, 1] minimizing:10 # dist(p, B(t)) where B(t) = (1-t)^2*a + 2(1-t)*t*b + t^2*c11 # Involves finding roots of a cubic equation: dot(B(t) - p, B'(t)) = 012 ...13 return min_distance
Curve Type (0=Line Segment, 1=Bezier Curve)
0.00Query Point X
0.50