A three-petalled knot drawn from nothing but circles.
There is no shape stored anywhere in this program. Instead it stamps a single small dot
It begins by framing the canvas — centering the coordinates and
The raw input is fragCoord — the pixel’s position, counted in pixels. Dividing it by iResolution (the canvas size) rescales everything to a tidy 0 → 1 across the screen. These are the uv coordinates almost every shader starts from.
The next two lines correct for aspect ratio so circles stay round on a non-square canvas. Then we shift the origin to the centre, apply zoom, and nudge by shift — leaving (0,0) in the middle and equal distances in x and y. A comfortable sheet of paper to draw on.
Each step places its dot at the sum of two turning motions: an 1 : −2 folds the path into three petals. Try nudging the hand to a positive number.
Every step starts from the same seed point vec2(0.0, 0.2) and an angle a that creeps forward with time, plus a fraction of a full turn for each step: a = iTime + (i / 1000)·2π.
a, then scale it by a · handSpin and added on top. A smaller wheel, turning at its own pace.Add the two together and you have the exact spot where this step lays its dot.
center = rotate(center, a) * armSpin;
center += rotate(vec2(0.0,0.2), a * handSpin);v by a 2×2 rotation matrix built from the sine and cosine of the angle — the textbook way to spin a 2-D vector about the origin.
mat2 m = mat2(c, -s, s, c);
return m * v;The dot itself is one
bw *= smoothstep(0.03, 0.031, distance(uv, center));For any pixel, distance(uv, center) measures how far it sits from this step’s centre. Inside radius 0.03 the result is 0; past 0.031 it is 1. Because we multiply the running brightness every step, a pixel only stays bright if it dodged every single dot.
Since the angle steps by i / 1000 of a turn, the full loop traces exactly one revolution. Lower the count with