Concentric Rings
Use fract on the distance from center to create repeating concentric rings:
Here's how it works.
Computing the distance first
vUv - 0.5 shifts the coordinate origin from the bottom-left to the center of the canvas.
length(p) gives the distance from each pixel to the center: 0 at the center, about 0.5–0.7 at the edges.
This creates a value field that grows uniformly outward from the center.
fract turns distance into rings
d * 12.0 stretches the 0–0.7 distance range to 0–8.4.
fract() folds that range into a repeating 0–1 sawtooth wave, where each cycle produces one ring.
The more times it folds (larger d, farther from center), the denser the rings near the edges.
step cuts hard ring edges
step(0.5, rings) splits each ring into an inner half (0–0.5, returns 0) and an outer half (0.5–1.0, returns 1), creating alternating dark and light concentric bands.
Try changing it
| Change | Effect |
|---|---|
Set 12.0 to 6.0 | Wider rings, fewer of them |
Set 12.0 to 24.0 | Thinner rings, more of them |
Change step(0.5, rings) to step(0.3, rings) | Narrower dark rings, wider light ones |
Change vUv - 0.5 to vUv - vec2(0.2, 0.7) | Center of rings moves to upper-left |
Exercise
Replace float rings = 0.0; with the correct expression to produce concentric rings centered on the canvas.
Answer Breakdown
d is each pixel's distance from the center. d * 12.0 amplifies that distance by 12. fract() folds it into a repeating 0–1 waveform — each fold creates one ring.
The starting code rings = 0.0 gives every pixel a rings value of 0. step(0.5, 0.0) always returns 0, so the canvas is solid dark. Changing to fract(d * 12.0) makes rings oscillate with distance, and step carves out dark/light pairs at each cycle.
Try replacing fract(d * 12.0) with fract(d * d * 50.0) — the ring spacing will vary with distance, producing a compression effect toward the edges.