Washes

An interactive watercolor simulation for the browser — a three-layer fluid, pigment, and paper model with Kubelka–Munk compositing, after Curtis et al. 1997.

demo v1.0.22 · engine 2.3.0

Demos

Showcase

Pages — product & story pieces
GRAIN Surfacing VANTAGE
Studio — brand studies
BURN CURRENT FIELDS HANDMADE Meridian prerender
Personality — ten temperament studies
three studies live studies interfering field five studies continuous organism words dissolving temperament you touch light from dark five-channel recording
Labs — physics & experiments
Lab I — physics Lab II — experimental demo gallery two-layer v1.1 features 2.x features

The engine

washes is a dependency-free npm-shaped package (README · changelog 0.98 → 2.3.0) living in engine/. The stage above is the engine painting for itself — inks mixed for the local hour, strokes choreographed by the timeline sidecar, an opaque canvas ({ opaque: true }, new in 2.3.0) in a width-capped frame that fixes the grid cost on any monitor, resolution handed to you as the quality() presets in the corner strip, and it reads its own coverage() before deciding what to paint next. The corner controls re-ink, pause (it still accepts pigment while frozen — deposits bloom on resume), reset, or save the sheet as a PNG. View source — the whole painter is a couple hundred lines.

// ESM / bundlers
import { Washes } from './engine/src/index.js';
const wc = Washes.create(host, { pigments: [{ color: '#2f6fb0' }] });
wc.paint(0.5, 0.5, 0.06, 'blue', 0.8);

<!-- classic script tag -->
<script src="engine/dist/washes.standalone.js"></script>
<script> const wc = Washes.create(host); </script>

Optional entry points: washes/gpu-sim (WebGL2 backend) and washes/timeline (declarative stroke choreography). Saved brushes live in presets/.

Paper references

Interactive explainers of the literature the simulation is built on:

Curtis et al. 1997 — Computer-Generated Watercolor Kubelka–Munk glazing Mixbox pigment mixing Stam — Stable Fluids Foster–Metaxas MAC grid Bridson — advection The CFL condition

History

The project's full lineage — watercolor v0.1 → v1.0 and washes v0.61 → v0.98 — is preserved as runnable snapshots in archive/versions/, alongside the original bundles and build-session transcripts in archive/.