Turing Bloom
Two chemicals share a square. One is fed in, the other eats it and makes more of itself. Nothing tells them to grow a reef.
About this piece
This is the Gray-Scott model, a two-chemical reaction run on a 180×180 grid. Chemical A is fed into every cell from outside; chemical B is drained out of every cell. The only thing that happens between them is one autocatalytic reaction — A + 2B → 3B — so B consumes A and turns it into more B. Written out, with lap() the local Laplacian:
dA/dt = DA lap(A) − A·B² + F (1 − A)
dB/dt = DB lap(B) + A·B² − (K + F) B
That is the entire program. There is no rule anywhere that says “branch”, no list of shapes, no randomness after the first frame. The reef is what those two lines do when you iterate them 360 times a second.
Why two diffusion speeds is the whole trick
Alan Turing wrote this idea down in 1952, in The Chemical Basis of Morphogenesis, his last published paper. His claim was counter-intuitive enough that it took decades to be taken seriously: a chemical mixture that is perfectly stable when you stir it can be made unstable by adding diffusion, and the instability has a preferred size. Spread it out and it does not smooth over — it separates into spots and stripes at a wavelength set by the rate constants.
The mechanism has a name now: local activation, long-range inhibition. B is the activator; it makes more of itself wherever it already is. A is what B needs, and A diffuses faster — here exactly twice as fast, DA = 1.0 against DB = 0.5. So a patch of B grows, and while it grows it drains A out of the ring around it faster than B can spread into that ring. The patch is fenced in by its own hunger. Set DA = DB and the whole picture dissolves into a flat wash within a few hundred steps; the ratio, not the reaction, is what makes a pattern.
The (F, K) plane, and why this corner
Two numbers select the behaviour: the feed rate F and the kill rate K. John Pearson mapped that plane in 1993 and found more than a dozen qualitatively different regimes packed into a region roughly 0.01 wide. Three of them are worth naming, because the code here is identical for all three and only the constants differ:
- Coral, F = 0.037 / K = 0.06 — what this plate runs. Fronts advance, tips split in two, and a branch stalls when it runs into the depleted zone around its neighbour. The result keeps rearranging for as long as you leave it open.
- Mitosis, F = 0.0367 / K = 0.0649 — a shift of about one part in a thousand. Blobs stay separate, grow to a fixed size, and divide.
- Maze, F = 0.029 / K = 0.057 — stripes of a single width that lock into a labyrinth and then stop moving.
Most of the plane is dead. Push K a little too high and B is drained faster than the reaction can replace it, so every seed fades and the field goes uniformly A = 1 — a blank plate, not a subtle one. That is a real cliff, not a gradient: at F = 0.037 the pattern survives to roughly K = 0.065 and is gone by 0.07.
How this plate is built
Two pairs of Float32Arrays of 32,400 cells each, swapped every step so no cell ever reads a half-updated neighbour. The Laplacian is the standard nine-point stencil — 0.2 on each edge neighbour, 0.05 on each corner, −1 at the centre. Those weights sum to zero, so a flat field never drifts, and they are symmetric, so the equations have no preferred direction on the grid. Integration is forward Euler at dt = 1, which for DA = 1.0 sits exactly at the stability limit of that stencil; a larger diffusion constant at this step size would blow up rather than draw.
Both axes wrap. A reflecting edge would pin an advancing front against the wall and grow a visible frame around the picture; on a torus the reef runs off one side and back in on the other.
Seeding is the part that took the most care. Gray-Scott from a single central drop shows an almost-empty plate for several seconds — a blank first paint, a blank screenshot, a blank share card. So the field is seeded with 36 small blobs on a jittered 6×6 lattice covering the whole square, each 2 to 4 cells in radius, about 4% of the field in total; and then it is advanced 360 steps before the first frame is ever drawn. By then the fronts have met and the picture is a picture. The jitter comes from an integer hash rather than Math.random(), so the bloom you see on load is the same one everybody else sees. Click the canvas and it grows a different one, deterministically — run 3 is the same reef on your machine as on mine.
Colour is not painted, it is read. Each frame writes the concentration of B into a 180×180 ImageData through a four-stop ramp taken live from this site’s palette: page background where nothing grew, then the deep cobalt, the body cobalt, and the coral accent only on the brightest crests. B settles into about [0, 0.34] for this (F, K), so the ramp is stretched over that window instead of over [0, 1] — otherwise the whole reef would sit in the bottom third of the gradient and read as one flat wash. Switch this page between light and dark and the same field repaints as ink on paper.
What to look for
Watch a single tip. It advances, thins, and splits into two — that is the Turing wavelength asserting itself: a front wider than the preferred spacing cannot stay a single front. Then watch what happens when two branches approach each other. They do not merge and they do not cross; they stop, a cell or two apart, held off by the trough of used-up A between them. Every gap in this picture is that trough.
Give it a minute and look again. Unlike a maze or a mitosis field, the coral setting never fully settles — branches are still being pushed around by their neighbours long after the frame looks finished.
Honest limits. This is a simulation of an idealised chemistry, not of any real organism; the resemblance to coral or to a leopard’s coat is a family resemblance between mechanisms, not a model of either. The grid is genuinely 180 cells across whatever your screen is, so on a wide stage each cell is about 7 pixels and the smoothness you see is the browser’s bilinear upscale, not extra detail — zoom in and you will find the lattice. The square field is scaled to cover a rectangular stage rather than stretched, which keeps the shapes round at the cost of cropping the top and bottom of the reef on a wide window. And it is arithmetic, not chemistry: forward Euler at dt = 1 is a coarse integrator, so the exact pixel values drift from a finer solve even though the pattern does not. Reduced-motion visitors get a settled still frame — the field warmed 1,260 steps and drawn once — because a frozen young field would be an honest picture of nothing much.
Curious how the loop and canvas fit together? Read how it works →
More from the gallery
- Plate 18 Penrose Tiling Two rhombs tiling the plane in a pattern that never repeats.
- Plate 19 Sandpile Avalanche Grains piling up until sites topple and an avalanche runs.
- Plate 20 Moiré Interference Two line grids turning against each other into slow bands.
- Plate 21 Kuramoto Sync Scattered blinking lights pulling one another into step.
- Plate 22 Slime Mould Network Wandering specks laying trails that grow into a branching web.
- Plate 01 Quantum Fibonacci Golden-angle phyllotaxis blooming from the seed outward.