Back
Inkwash: a watercolor simulator that lives in one HTML file
SiTech AI Team3 წთ. საკითხავი

Inkwash: a watercolor simulator that lives in one HTML file

Johno Whitaker's Inkwash simulates ink and water on paper with a fluid solver and a Beer–Lambert rendering pass. The whole app is a single HTML file with no dependencies and no build step.

Johno Whitaker has published Inkwash, a watercolor sketching app that runs in the browser, together with a long technical explainer of how it works. The app is a single HTML file of under a thousand lines with no dependencies and no build step; it requires WebGL2 and renderable half-float textures, which he dates to hardware from roughly 2021 onward.

From a waterbrush to a fluid solver

The project began as a test of Anthropic's Claude Fable 5 and grew into an attempt to recreate the author's nature-journaling routine in a browser. That routine pairs a Pilot G2 pen with a waterbrush — a nylon brush with a squeezable water reservoir in the handle. Whitaker writes that he has not touched the code himself: he can read the file, but the implementation came from the model, as did much of the explainer's prose, which he discloses.

Under the canvas the painting is not pixels but a stack of floating-point textures — mobile pigment, settled pigment, water, velocity and pressure — ping-ponged through about a dozen WebGL2 shaders every frame. The fluid motion uses Jos Stam's Stable Fluids algorithm from 1999, whose semi-Lagrangian advection traces each cell backwards along the velocity field so that a large timestep cannot blow the simulation up. Pressure projection with roughly 22 Jacobi iterations makes the water incompressible.

Wetness as a permission system

What makes the result read as paper is that a wetness field gates the whole simulation. Velocity is multiplied by a smoothstep of wetness, so flow cannot exist on dry ground and a wash stops at its own boundary. Pigment mobility is scaled the same way, so damp paper lets ink creep while soaked paper lets it run. Water itself advects at 0.6 times the flow speed and dries exponentially, with a slider setting the time constant between roughly 2 and 18 seconds. Fresh pen ink lays down a faint wetness of its own, which is why a brush pass right after a pen stroke feathers the line while an older stroke holds firm.

Beer–Lambert and the blue halo

Pigment is stored as per-channel optical density rather than colour, and the display shader converts it with the Beer–Lambert law, multiplying the paper colour by an exponential of density. Overlapping strokes therefore deepen instead of flattening toward gray, the way real glazes behave. The same storage choice produces the app's signature effect: the bleed step runs at a different rate per channel, so a wet edge sorts itself into a dark core with a cool blue-violet halo — an imitation of how black inks chromatograph on wet paper.

A second, settled pigment layer provides layering: pressing "fix" runs a 1.2-second pass that transfers mobile pigment to the fixed sheet and flash-dries the paper, while white gouache is baked opaquely into it. The full pipeline — twelve shader passes including the Jacobi iterations — runs at 60 frames per second on a phone, the author writes, because the expensive solve happens on a coarse grid.

SSiTech

SiTech — AI-powered web development

We build fast, modern websites and bring AI into real business workflows. Have a project or a question? We'd love to help.