Displacing an SDF's input coordinate before evaluation deforms the shape by any function
An SDF can be deformed without touching its formula by perturbing the input coordinate p before passing it to the distance function — bending the space the shape lives in rather than the shape itself. In domain warping you offset p first: adding a parabolic offset to the y-coordinate before computing a mouth ellipsoid curves it into a smile while the shape stays an ellipsoid. In the related opDisplace operation you compute any function of p — sine waves, noise, custom expressions — and add that amount back to the returned distance, pushing the boundary outward or inward to produce organic, wavy, or spiky outlines. Because the perturbation is applied in UV space, the result is resolution-independent, and a single displacement function yields complex organic deformations. A key limitation: adding an arbitrary function to the distance may break the Lipschitz condition so the result is no longer a true SDF, and very large displacements can cause rendering artifacts like missed surfaces.
Examples
// domain warp: bend the coordinate → smile
float mouthY = p.y - 0.3*p.x*p.x;
// opDisplace: perturb distance by a function of p
float opDisplace(vec2 p) {
float d1 = sdCircle(p, 0.3);
float d2 = sin(20.0*p.x)*sin(20.0*p.y)*0.05; // displacement
return d1 + d2;
}
Assessment
Apply a sine-wave displacement to a circle SDF, then increase the amplitude and identify when rendering artifacts appear and why (Lipschitz violation). Explain why warping p before the SDF call (domain warp) produces a smile while adding a term to the SDF output produces a different artifact.