Crayon brush — reference vs. current renderer

Each acceptance scene side by side: the real-crayon reference next to the shipping ADR-0065 brush driven through the same mark on a production build, with the visual gap named per scene.

5 paired scenes2 macros/dev/engine harness

Single stroke

Real crayon reference: Single stroke
Real crayon (reference)
Current renderer: Single stroke
Current brush (ADR-0065 renderer)

Real wax carries continuous tone inside one hue — thick patches read darker, thin drag-outs go translucent and tint the paper. The renderer lays one flat rgb with binary pits: every opaque pixel is the identical color, so the stroke reads stamped rather than dragged, and the grain is isotropic confetti instead of clumps streaked along the stroke direction.

Same-color buildup (light → heavy)

Real crayon reference: Same-color buildup (light → heavy)
Real crayon (reference)
Current renderer: Same-color buildup (light → heavy)
Current brush (ADR-0065 renderer)

The reference deepens: repeated passes fill the tooth AND drop in value / rise in saturation, and the sparse end is a translucent dusting. The renderer builds coverage only — the right half gets more solid but every covered pixel stays the exact same blue. That was a hard constraint of the replay era (constant-hue idempotence); snapshot undo (ADR-0066) lifted it, but the brush still behaves as if it hadn’t.

Blue over yellow

Real crayon reference: Blue over yellow
Real crayon (reference)
Current renderer: Blue over yellow
Current brush (ADR-0065 renderer)

The darken-min stamp genuinely turns the crossing green — the strongest part of the current design, worth keeping. The gap is texture, not color: the real crossing is streaky and partial (blue skips riding over yellow wax), while the render mixes uniformly inside a crisp rectangle.

One-gesture back-and-forth scribble

Real crayon reference: One-gesture back-and-forth scribble
Real crayon (reference)
Current renderer: One-gesture back-and-forth scribble
Current brush (ADR-0065 renderer)

Real scribbles keep each sweep legible — darker where lines cross, feathered at the turnarounds. The renderer’s mid-stroke pass splitting works (rows do densify), but same-hue exactness means crossings never darken, so sweeps fuse into one texture field with faint horizontal seams at the pass boundaries.

Dense fill swatch

Real crayon reference: Dense fill swatch
Real crayon (reference)
Current renderer: Dense fill swatch
Current brush (ADR-0065 renderer)

The real fill shows pressure blotches and long drag streaks; bare paper survives in organic clumps. The rendered fill is even micro-speckle everywhere — the 256 px tooth tile has no low-frequency structure (deliberately, to hide the tile repeat), so nothing modulates at blotch scale.

Macro: deposit on tooth

Macro: deposit on tooth
Real crayon macro (reference)

What the tile model can’t express: wax thickness. Pigment sits in 3-D clumps on the tooth bumps with drag streaks where the crayon slid — thickness varies continuously, and value follows thickness.

Macro: thin dusting → heavy wax

Macro: thin dusting → heavy wax
Real crayon macro (reference)

The full deposit range of one crayon: translucent speckle at grazing pressure to glossy near-solid wax after repeated passes. A faithful brush needs a deposit quantity per pixel, not a binary covered/bare bit.

The five visual gaps, ranked

  1. No deposit depth. Buildup only fills more tooth; covered pixels never get deeper or more saturated. Real wax deepens with every pass, mid-stroke and across strokes.
  2. Flat tone. One rgb per color (±8% mottle) vs. continuous value modulation driven by wax thickness; thin wax should go translucent, not vanish into binary pits.
  3. Isotropic grain. The tooth field ignores stroke direction; real grain streaks along the drag.
  4. No blotch-scale structure. Fine speckle only — fills lack pressure blotches and clumped bare-paper islands.
  5. Binary edges. Stippled 0/1 rims read as confetti next to the references’ feathered, crumbly edges.

The darken-min color mixing and mid-stroke pass splitting are explicitly worth carrying forward; every gap above traces back to the replay-determinism contract ADR-0066 deleted.