Breakdowns/Emerge 1

  • 08emergeNewFree
  • 08singularityNew
  • 05penumbraNew
  • 08nebulaNew
  • 21genuary26
  • 07bands
  • 05slate
  • 10gravity
  • 05warp
  • 05abiogenic
  • 10cascade
  • 08shift
  • 07formation
  • 02mesh
  • 08imaginary
  • 06arcs
  • 05dawnFree
  • 05eidolon
  • 09flareFree
  • 29genuary2025

Join waitlist ↵
164

Emerge 1

Conway's Life cellular automaton with simple rules and inexhaustible motion.

Loading...
←→

emerge7

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
Works171
Writing31

Fragments

Learn creative coding with shaders. For design engineers, creative coders and shader artists: techniques, tools, deep dives. Powered by ThreeJS and TSL.

Loading...

2025 Phobon

phobon.ioShadercraft

Pages

HomeTechniquesUtilitiesBreakdownsWorksWriting

Contact

X @thenoumenonhey@fragments.supplyOKAY DEV @phobon
All rights reserved.

Implementation

The Emerge pieces are a playground for cellular automata on WebGPU: one shared CellularAutomata component, many small rulesFn experiments. This first sketch is the warm-up—classic Conway on a torus, dressed for the wall with a gold-on-violet duotone and a generous mat so the grid reads like a print rather than a full-bleed texture.

Breakdown

Conway's rules are the lingua franca of CA—two or three neighbors to survive, exactly three to be born—so the interesting choices here are mostly presentation: grid size, seed density, and framing. There are 3 key components:

The rule in TSL

The update is expressed as nested If branches on the current state and Moore count. Live cells die above three neighbors or below two; dead cells wake only at three.

Conway rule (emerge1)
const emerge1 = Fn(([currentActive, neighborActiveCount]) => {
  const c = currentActive.toVar()
  If(currentActive.equal(1), () => {
    If(neighborActiveCount.greaterThan(3), () => c.assign(0))
      .ElseIf(neighborActiveCount.greaterThan(1), () => c.assign(1))
      .Else(() => c.assign(0))
  }).Else(() => {
    If(neighborActiveCount.equals(3), () => c.assign(1))
  })
  return c
})

Same logic you'd write on a CPU, but it runs in the compute pass so the whole field steps in parallel.

Torus and density

Defaults in the component give you a wrapping grid; here the sketch sets rows/columns to 200 and seedDensity: 0.28 so the initial soup is busy but not noise.

Color and framing

foreground and framing.background are fixed hex values (parsed with hexToRgbArray), and framing.margin insets the active region so the violet reads as a deliberate border around the simulation.

maxIterations={0} lets the CA run continuously until you leave the page—good for watching long-lived debris and occasional gliders settle in.

Emerge 2

Emerge 2

Free
Emerge 3

Emerge 3

Free
Emerge 4

Emerge 4

Free
Emerge 5

Emerge 5

Free
Emerge 6

Emerge 6

Free
Emerge 7

Emerge 7

Free
Emerge 8

Emerge 8

Free

Be the first to know what's next