Study 04 / Morphogenesis Garden

The solver makes structure. The palette makes emphasis.

Nine authored concentration patches—fixed in the default field and deterministically varied by seed—enter a two-field reaction–diffusion update. The layout, finite-difference stencil, fixed boundary, 32,768-cell ceiling, staged warm-up, and copper transfer determine what appears.

Which choices remain authored when no frame is drawn by hand?

Open the live system
Morphogenesis Garden reaction plateAn actual forty-eight by thirty-two reaction-diffusion field after three hundred iterations, quantized into five copper bands and marked with the nine seed-zero initial inoculation positions.REACTION PLATE / RP‑04300 ITERATIONS / 5 BANDS
Diffusion
1.0 / 0.5
Feed
0.055
Kill
0.062
Inoculations
9
An actual 48 × 32 helper snapshot after 300 deterministic steps, compressed into five color bands. The numbered marks preserve the exact initial patch coordinates.
Published
Jul 12, 2026
Updated
Jul 12, 2026
Reading
11 min
On this page
  1. Concentrations, not flowers
  2. Nine inoculations
  3. The reaction ledger
  4. Stencil and reservoir
  5. Resolution has a cost
  6. Palette and stillness
  7. Where generation belongs

01 / Morphogenesis Garden / Concentrations, not flowers

The solver draws no flowers.

Morphogenesis Garden contains no plant model or branch grammar. It stores two numbers—A and B—for every cell, then repeats the same local reaction and diffusion update. A seeded generator may choose the nine initial patches, but no randomness enters the solver after initialization. “Garden” names the resemblance of the final contours, not the thing being simulated.

That distinction makes the work more interesting, not less. No path describes the rust rings in the hero specimen. They appear because nearby concentrations repeatedly alter one another. But the system does not choose its own conditions: the initial patches, coefficients, boundary, resolution, iteration schedule, and color transfer are all authored.

Emergence here has a narrow meaning. The visible geometry is absent from the source, yet it remains a consequence of explicit code. It is not agency, intelligence, or a claim about biological growth.

02 / Nine authored inoculations

Reproducibility begins with where B enters the field.

Initialization fills every cell with A=1 and B=0. Nine default normalized coordinates then receive circular B patches: A becomes zero, B becomes one, and radii range from 2.2 to 3 grid cells. Controller seed zero reproduces those exact coordinates. Other uint32 seeds deterministically jitter each center by at most 0.035 of the normalized field and scale its radius within 80–120%.

Nine default Garden inoculationsNine numbered patches are plotted in normalized field coordinates. Their radii range from two point two to three grid cells.123456789
These seed-zero positions are authored data, not decoration. A viewport resize rebuilds the current deterministic seed against the new grid.

Because the coordinates are normalized, they keep their broad composition across grid sizes. Their exact sampled cells still depend on resolution and rounding. A new viewport size therefore rebuilds a related field rather than stretching a pixel-identical asset.

The deterministic field starts from explicit patches.
const field = createGardenField(columns, rows, settings.seed);
// seed 0 returns GARDEN_INITIAL_PATCHES; other seeds vary them safely:
for (const [x, y, radius] of gardenInitialPatches(settings.seed)) {
  seedGardenField(field, columns * x, rows * y, radius);
}

At baseline, pressing the open Canvas queues a 3.5-cell patch at the down position, so even a short tap survives until the next solver step. While held, the field reinjects at 60 times per second—every 10 warm-up iterations or every 3 baseline live iterations. A fractional accumulator keeps that cadence near 60 per second when intensity changes solver pace. A stationary hold therefore does not change chemistry merely because the display refreshes faster. Pressure, speed, and direction are not inputs, and reduced motion disables the injection.

03 / The reaction ledger

Each iteration is an explicit balance sheet.

A diffuses at 1.0; B diffuses at half that rate. The reaction term AB²consumes A and produces B. Feed replenishes missing A at 0.055, while B is removed by the combined feed-and-kill rate of 0.117. Every new value is clamped between zero and one.

One iteration, recorded as two concentration accounts

Field A

A′ = A + DₐL(A) − AB² + f(1 − A)
Diffuse
+ 1.0 × L(A)
React
− AB²
Feed
+ 0.055(1 − A)

Field B

B′ = B + DᵇL(B) + AB² − (k + f)B
Diffuse
+ 0.5 × L(B)
React
+ AB²
Remove
− 0.117B

The engine writes the next A and B values into separate typed arrays, then swaps the old and new buffers. No cell can see a neighbor that has already advanced to the next generation during the same pass. The result does not depend on whether the loop scans left-to-right or right-to-left.

The current helper expresses a Gray–Scott update directly.
const reaction = a * b * b;
nextA = clamp(a + (1.0 * laplacian(A) - reaction
  + 0.055 * (1 - a)), 0, 1);
nextB = clamp(b + (0.5 * laplacian(B) + reaction
  - (0.062 + 0.055) * b), 0, 1);

These coefficients occupy one productive region of the model; they do not describe a universal recipe for “organic” form. Changing them can collapse the field, fill it, or move it into a different pattern regime. The controller therefore leaves chemistry untouched: intensity only bounds live solver pace from 90 to 270 iterations per second and pointer radius from 2.5 to 4.5 cells.

04 / Stencil and reservoir

Local means nine samples and a fixed edge.

Diffusion uses a nine-point finite-difference stencil. Cardinal neighbors carry 0.20, diagonals carry 0.05, and the center contributes −1. The weights sum to zero, so a perfectly uniform field produces no diffusion term.

Nine samples define the local neighborhood

Boundary cut

The outer ring stays at A=1 / B=0. New patches keep a symmetric two-cell margin from every edge.

Only interior cells are updated. The outer ring remains at its initialized A=1 / B=0, acting as a reservoir rather than wrapping to the opposite edge. Initial and pointer patches observe a symmetric two-cell seed margin, so direct input cannot overwrite that boundary or its adjacent ring.

Boundary behavior is part of the composition. A periodic field, mirrored edge, or no-flux boundary would produce different contours. Treating the frame as neutral would hide one of the system's authored inputs.

05 / Resolution and warm-up

Warm-up is part of the entrance.

Garden state is created lazily when the chapter first needs to draw. Desktop fields use 192 columns and mobile fields use 128. Rows follow the viewport aspect ratio, with a minimum of 72 and a hard ceiling of 32,768 total cells. The ordinary 1440 × 944 stage stays at 24,192 cells; the 390 × 788 stage reaches the cap at 32,768.

Two verified viewport cuts and their bounded schedules
StageGridCellsSchedule
1440 × 944192 × 12624,192ordinary desktop cut
390 × 788128 × 25632,768cell ceiling reached
Warm-up300 total600 / second20 maximum per frame
Livecontinuous180 / second6 maximum per frame

The 300-iteration preview is scheduled at 600 iterations per second, so a normal 60Hz entrance spreads warm-up over roughly half a second. Once warm, the field advances at 180 iterations per second at the intensity-50 baseline (90–270 across its valid range). A local delta cap of 33ms limits one delayed frame to 20 preview iterations or 6 live iterations. Fractional work carries forward instead of changing speed at 60Hz, 120Hz, or 165Hz. The same solver clock also times held input, so it is not reapplied once per rendered frame.

Warm-up and live growth use separate fixed-rate schedules.
const preview = gardenWarmupSchedule(
  delta, pendingPreview, remainingOf300
); // 600 iterations / second, maximum 20 per frame

const live = gardenLiveSchedule(delta, pendingLive);
// 180 iterations / second, maximum 6 per frame

Resize notifications that report the same width, height, and DPR return without rebuilding the engine. A materially different size still creates a new grid and returns to the nine patches derived from the current seed. The implementation chooses coherent dimensions over resampling a modified field while the product settings remain intact.

06 / Palette and stillness

The brightest color is a selected boundary.

Rendering first reduces the two fields to q = clamp((1 − A + B) × 1.45). A dark core follows q¹·⁴⁵, while a Gaussian band peaks at q=0.48 with a width of 0.14. That band adds most of the copper highlight. The highest concentration is dark red, not the brightest pixel.

The palette is deliberately non-monotonic
  1. q=0.00

    3, 7, 19

  2. q=0.25

    22, 15, 22

  3. q=0.48

    194, 87, 41

  4. q=0.75

    43, 23, 27

  5. q=1.00

    57, 29, 30

The brightest copper band sits near q=0.48, not at the highest concentration.

The low-resolution field is written to an offscreen ImageData buffer, then scaled to the viewport with image smoothing, a 0.35px blur, and 1.15 saturation. Morphology and color remain separate decisions: the solver produces concentrations; the transfer function decides which boundary deserves attention.

Under prefers-reduced-motion: reduce, Garden computes a separate 300-step preview, caches it by geometry and seed, renders that completed plate, and schedules no animation frames. Repeated scroll redraws reuse the cached field. The Canvas is aria-hidden; equations, input contract, limits, and related destinations remain ordinary HTML. The visible Pause / Resume transport cancels RAF without advancing or substituting the live solver arrays.

07 / Where generation belongs

Use generated form where variation can remain nonessential.

This method suits an editorial specimen, a bounded brand texture, or a decorative empty surface when exact geometry is not part of the task. It earns its place when resolution, coefficients, initialization, processing time, contrast, and a still fallback can all be versioned with the design.

Generation is useful when…

  • variation supports atmosphere rather than carrying content;
  • the initial condition and parameter range are reproducible;
  • the field has a measured cell and iteration budget;
  • a deliberate still frame communicates the same visual role.

Author the asset directly when…

  • a logo, scientific diagram, or status display must be exact;
  • visitors could mistake color for measured data;
  • resize or input history must never alter the outcome;
  • the visual competes with reading instead of framing it.

The catalog offers three useful counterpoints. Typed Halftone Background Drift keeps a procedural surface inside explicit CSS parameters. Gooey Blob Construction produces an organic-looking union through blur and thresholding rather than a reaction solver. Irregular Handwritten Mask Reveal shows the opposite strategy: irregularity authored directly as a path.

The Garden is not an infinite image generator, and this release does not yet promise a reproducible share card. It is one bounded field whose local rules become legible because the surrounding authorship is made explicit.

Method

References and implementation sources

This article documents the live implementation running on this site. These primary standards and publication records were used to verify API behavior and technical terminology.

  • Complex patterns in a simple systemGray & Scott, Science (OSTI record)

    Primary publication record for the autocatalytic reaction–diffusion system used as terminology context.

  • HTML Canvas 2D ContextWHATWG HTML Living Standard

    Image-data and drawing behavior used to transfer the scalar field into visible pixels.