Two imaginary chemicals, feeding and starving each other into Turing patterns.
Nothing here is drawn. Two imaginary chemicals — call them A and B — sit on a grid, one number each per pixel. Every frame they follow a three-line rule, and out of that rule alone come spots, stripes, and branching coral. These are
The whole simulation lives in one
Three things happen to every cell, every frame: the chemicals diffuse (smear into their neighbours), they react (B eats A to make more B), and the world is topped up — A is fed in, B is killed off. Two dials decide which world you live in: the
Diffusion needs to know how a cell compares to those around it. The −1, its edge neighbours +0.2 each, the diagonals +0.05. Where a cell sits in a dip the total is positive (chemical flows in); on a bump it’s negative (flows out).
if (i==0||j==0) factor = 0.2; // edge neighbours
if (i==0&&j==0) factor = -1.; // the cell itself
sum += texture(iChannel0, xy+offset).ab * factor;A spreads fast (
The reaction itself is the term a*b*b — wherever A and B meet, a little A is converted into B. A is then 1, and B
a + dA*lapAB.x - a*b*b + feed*(1.0 - a), // A
b + dB*lapAB.y + a*b*b - (k + feed)*b // BBefore reading itself back, the buffer mat2 multiply.
The buffer’s chemical A is a soft 0 → 1 gradient. The display pass does one thing: a single
vec3 col = vec3(smoothstep(0.4, 0.6, texture(iChannel0, uv).a));Everything below 0.4 goes black, everything above 0.6 white, with a thin antialiased seam between. Try wiring the .b channel here instead and you’d see B’s mirror image.