The Operators
midi-sink never solves a fluid on a grid. Grid advection diffuses, and diffusion turns crisp suminagashi rings into mud within seconds. Instead the ink is an area-preserving, continuous deformation of the sheet, evaluated by inverse lookup: for every output pixel the engine asks where that water came from, , and reads the ink there. Two half-float textures hold the accumulated pre-image coordinates plus the ink phase and a per-drop hue selector; each gesture is one more pass that reads one texture and writes the other. This is Aubrey Jaffer’s mathematical marbling (Lu, Jaffer, Jin, Zhao & Mao, 2012), extended with two of his own later closed-form fields and a few of ours — see the citations.
Every operator page follows the same shape:
- The formula, exactly as the shader evaluates it, in aspect-corrected normalized coordinates (non-square canvases are corrected before the mathematics, or rings become ellipses; distances are in canvas heights).
- Invariants — why it preserves area, its class — exact at any
magnitude, or sub-stepped to stay away from a fold — and what composes
with what. Every operator declares its class and passes the same
four-part conservation gate (the desktop bench’s
--soak: area, mass, the pre-image’s wander, fabrication as a rate); the composite is gated per backend. - Ownership — which MIDI dimension or gesture drives it, and the
one-consumer rule: a MIDI dimension has exactly one consumer at a time
(
bend_mode,press_mode,slide_modechoose it) so two operators never fight over one stream. - A live demo — the release wasm, the same engine bytes every platform ships, embedded through the scene API. The sliders are the formula’s symbols. There is no second implementation anywhere on this site.
Two conventions run through every demo. The scenes are paced — the ⏱
slider is the number of frames between steps, and the operators that compose
exactly are applied as a run of small passes, so you watch the transformation
happen rather than see only its result (set it to 0 for the result alone). And
every scene works on two ring clusters, top-left and bottom-right, so one
operator can show two orientations or two signs at once: a horizontal and a
vertical tine, two counter-rotating vortices, perpendicular fold axes, a drop
beside a pressure feed. A third: every scene carries the medium toggle
(M) — flip it to 1 and the same script runs from its first strike as the
Anod discharge: every strike in a scene is the medium’s, so under
Anod the ring clusters are struck as sparks on their charge, as a
tap is in the app, and the deformation is read as strain instead of bands.
The toggle is permanent for the run, never a switch at the end.
The nine of 1.0
Section titled “The nine of 1.0”| Operator | Kind | Class | Driven by |
|---|---|---|---|
| Drop — and the pressure feed | expansion | exact | strike, pressure feed, breath |
| Tine | shear | exact (Jacobian 1) | per-note bend (glide), master bend |
| Vortex — exponential, Rankine, torsion | rotation | exact at any angle | mod wheel / Airwave CC (exponential), two-finger twist (Rankine) |
| Wake — inviscid doublet, viscous Stokeslet | potential-flow doublet · 2-D Stokes impulse | sub-stepped ≤ a/4 | every stylus stroke; a wind legato (the sounding drop dragged to the next note) |
| Pinch — saddle, crossed tines | Hamiltonian saddle | exact (det = 1) | CC 74 with Slide → Pinch, pen azimuth, two-finger pinch |
| Ripple | sine shear | exact (Jacobian 1) | per-note bend with Per-note bend → Ripple, CC 102/103 |
| Swirl — Lamb–Oseen | viscous rotation | exact at any angle | poly pressure 0xA0, channel pressure with Channel pressure → Swirl |
| Scroll | translation with ingress | exact | the piano-roll layouts’ tempo |
The five of the electric medium
Section titled “The five of the electric medium”The second medium, Anod, reads the same field as a discharge and brought five operators with it — every one of them a shear or a rotation composed from the first nine’s lemmas, and every one of them playable under suminagashi too:
| Operator | Kind | Class | Driven by |
|---|---|---|---|
| Wave torsion | oscillating rotation by θ(r) | exact at any amplitude | the vortex routes with the Torsion profile; the note-on sweep; Anod’s press |
| Chladni — an eddy in every key | exact disc rotations on the layout’s cells · the inverse Chladni’s summed flow | exact (discs) · first-order (inverse) | the stir and balance CCs 106/107; Anod’s per-note bend |
| Burst — the viscous multipole, m ≥ 2 | time-integrated impulsive multipole | sub-stepped (first-order, under the wake’s criterion) | the gesture; the middle piece of the Anod strike |
| Spark — the composed strike | drop + burst + jagged shears | exact shears; sub-stepped by inheritance | the Anod strike on its charge; the slide (CC 74) its frequency |
| Chirikov — the standard map | sinusoidal kick + linear drift | exact; capped at K = 1.25 per step | the throw: CC 109, Anod’s mod wheel |
The two media and their look — the washi and the glass, the three palettes of each and the palette model behind them — are the medium guide’s.
Two rules that hold everywhere
Section titled “Two rules that hold everywhere”Continuous feeds are deltas. Pressure, breath, swirl and pinch arrive as absolute controller values, but the operators consume rates: a pass per frame whose magnitude is the smoothed value × Δt. Feeding an absolute value integrates into runaway strain; a delta relaxes when the hand relaxes.
Paper is screen-locked. The washi fibre and grain are sampled in screen space, never through the deformed field. Ink moves; the paper it sits on does not. If fibres ever drift with a tine, that invariant has been broken.
midi-sink 2.0.0-rc.5 · AGPL-3.0 · source
