Wrapping the input coordinate into a periodic cell tiles one SDF into infinite copies at near-zero cost
Domain repetition tiles a single SDF across space by wrapping its input coordinate into a repeating cell before evaluation, using fract(p) (repeat every unit), mod(p, period), or round. The domain folds onto itself so the marcher sees the same shape at every cell, and because the distance function is computed only once in the canonical cell, the cost is essentially independent of how many copies appear — GPU instancing without any instance array or draw call. The integer part removed during wrapping is the cell ID (e.g. floor(p/period)), which can drive per-instance variation such as colour or animation offset; Inigo Quilez used this to animate many flying creatures from one SDF in his Angels (2013) shader. High-level tools expose it directly — marching.js offers Repeat(shape, spacing). Two caveats: the field is infinite, so distance-limiting (fog or a bounded render distance) is used to cap computation; and objects near cell boundaries may not include their neighbours’ SDFs in the minimum, causing seam artifacts.
Examples
vec3 q = mod(p + 0.5*period, period) - 0.5*period; // wrap into [-period/2, period/2]
float d = sdSphere(q, 0.4); // one sphere, infinite copies
// marching.js high-level equivalent, with fog to bound the field
march( Repeat(Sphere(.1), .4) ).fog(.1, Vec3(0)).render(4, true)
Assessment
Explain why domain repetition’s cost is nearly independent of instance count, and describe how the cell ID is used to differentiate instances. For a forest tiled with mod(p.xz, 3.0), name two boundary artifacts and how to mitigate each. Contrast bounding the field with fog versus reducing the render distance.