Research
What makes mixing feel natural
Question: which technology makes two digital paints combine the way two real ones do?
The short answer
Natural mixing has two halves, and almost every app only does the first:
- The colour model — what colour two paints make. This needs subtractive, pigment-based mixing (Kubelka–Munk). RGB averaging turns blue + yellow into grey.
- The transport model — where, how much, and how incompletely they mix. Real paint marbles, streaks, dirties the brush and contaminates the next stroke. A perfect mixer that blends evenly and instantly feels fake, even with correct colour.
The first half is a solved problem you can choose off the shelf. The second is where "natural" actually lives, and it's ours to build.
Half 1 — the colour model
| Option | How it works | Licence | Verdict |
|---|---|---|---|
| RGB / alpha lerp | Average the numbers | — | Wrong. Blue + yellow → grey. The biggest single tell of fake paint |
| Mixbox (Sochorová & Jamriška, SIGGRAPH Asia 2021; Secret Weapons) | RGB → 7-D latent space (KM pigment concentrations + residual) via LUT, mix linearly there, map back | CC BY-NC 4.0 — non-commercial only. A commercial licence has to be negotiated by email | Excellent quality, has a GLSL shader, ships in Rebelle and Blender Flip Fluids. Only worth licensing if it clearly beats our own in spike 3 |
| Spectral.js (van Wijnen) | RGB → reflectance curve as a weighted sum of 7 primary curves → KM mix → back to RGB | MIT | A licence-clean route for "any colour the user picks." Small, easy to port to a shader |
| Kubelka–Munk on a named, fixed palette | Store each texel as concentrations of real pigments, not RGB. Each pigment has absorption K(λ) and scattering S(λ); mix K and S by concentration; convert to reflectance, then to colour, at display time | Ours | Recommended core. The most faithful option, and the one that gives painters the behaviour they know for free (below) |
Why the named-palette KM model wins: tinting strength and hiding power fall out of the physics instead of being faked. Phthalo blue dominates any mix because its absorption is huge; titanium white covers because its scattering is huge; ochre is weak and earthy. A painter will test exactly these behaviours in their first thirty seconds.
Where the pigment data comes from: fit K and S per pigment to our own photographed mixing chart (Track B1 in the brief). Optimise to minimise ΔE2000 between the model's swatches and the photographed ones under a known illuminant. The digital palette is then calibrated against real paint we physically made. For the lab, a smooth-spectrum upsampling of each pigment's colour is a good-enough stand-in until the chart exists.
Cost: 4–8 pigments × 10–16 wavelength bands per texel, evaluated only when compositing dirty tiles. Trivial on any A-series GPU.
Half 2 — the transport model (where "natural" lives)
- Incomplete mixing — marbling. Move paint mostly by advection (carried along with the brush) with very little diffusion. On a knife, real paint marbles for many passes before it goes homogeneous, and the marbling is beautiful. Blending should be something you work at.
- Every bristle carries its own load. Model 16–48 bristles, each with its own pigment vector. A dirty brush then lays down streaks of both colours automatically, and the colour shifts along the stroke as bristles run out at different rates.
- Bidirectional transfer. The brush deposits its load and also picks up wet paint from the canvas, in proportion to wetness and contact. So the tail of a stroke carries the colour it passed through: the dirty-brush streak. Nothing has to be authored.
- Wiping the brush is a deliberate act. A rag wipe that cleans most of the load. Dirtiness becomes a choice, and a painterly one.
- The palette is a real surface. Mix piles with a knife on a palette that uses the same simulation as the canvas. Piles persist between sessions.
- Optical mixing is also mixing. Impressionist broken colour sets strokes side by side and lets the eye mix them. The engine's job here is not to over-blend, and to keep enough canvas resolution per screen point that separate strokes stay separate.
- Glazing is mixing through layers — KM layer-over-substrate (see Depth and light).
Mud, without lying
An honest mixer makes brown sludge easy. Real oils do too, and beginners will blame the app. Fixes that don't cheat the physics:
- Default to the Zorn palette — yellow ochre, cadmium red (vermilion originally), ivory black, titanium white. It's attested back to Apelles in Pliny, it's the standard teaching palette in portrait ateliers today, it's very hard to make mud with, and it's superb for flesh. It's also four channels instead of eight: half the memory and compute, especially on iPhone.
- Show the brush's actual load (a small swatch of what's on the bristles right now).
- Make the rag one gesture away.
What to test (spike 3)
| Test | Pass if |
|---|---|
| Blue + yellow, red + white, black + yellow (the classic Zorn "green") | Hue matches the physical chart within ΔE2000 ≈ 3–5 |
| Phthalo into white at 1:10 | Still a strong blue (tinting strength) |
| Blind swatch test with painters: real photo vs digital | Can't reliably pick the digital one |
| Three strokes of red through wet yellow | Visible marbling persists; not a uniform orange |