---
title: "How colours mix"
description: "How Professor Oops stores colour as the light it soaks up, so paint stirs like paint, washes darken, marker dots split into rings and bleach turns black orange."
source_name: "Game Tailors"
source_url: "https://professoroops.com/en/inside/colour/"
site_home: "https://professoroops.com/"
source_description: "The drawing app where the paper is real. No ads. No accounts. No personal data: only anonymous counts, which you can switch off."
locale: "en"
legal:
  - "Game Tailors · Schieweg 15Y-40, 2627 AN Delft (NL)"
  - "KvK 92437702 · VAT NL866044474B01"
  - "info@gametailors.com · +31 6 4227 5919"
copyright: "© 2026 Game Tailors"
published_at: "2026-11-10T12:02:57.150Z"
modified_at: "2026-11-10T12:02:57.150Z"
---

# How colours mix

## Colours mix like real paint because the game stores the light each one soaks up

Stir blue paint into yellow and you get green. Lay one wash over another and it goes darker. Touch a black marker dot with water and it splits into a blue ring, a pink band and a yellow middle. No code draws those rings or mixes those colours. They follow from how the game writes colour down: three numbers for every spot of paper, saying how much red, green and blue light the colour there soaks up.

[For engineers](<#hood-engineers>)

![A black marker dot on paper, wetted with a drop of water, separating into a blue outer ring, a pink band and a yellow centre, computed with the game's dye rule](<https://professoroops.com/_assets/entity_29PuXTtL7z1RCoVdOVFu.png>)

## Stirred paint lands between its two colours; washes laid over each other go darker

A screen makes colour by adding light. Red light plus green light looks yellow. Paint works the other way round. Each pigment soaks up part of the light, and what's left bounces back to your eye. Yellow paint soaks up blue light, blue paint soaks up red, and a mix of the two lets mostly green through.

Professor Oops keeps colour the paint way round. Every spot of paper holds three numbers: how strongly the colour there absorbs red, green and blue light. Those numbers are turned back into a colour only when the page is drawn.

That one choice gives two kinds of mixing for free, depending on where the colour lives. Colour soaked into the paper **stacks**. A wash over a dry wash adds its absorbance to the first, so the light has to get through both and comes back darker than either, like a glaze. Paint, ketchup and other thick stuff lying on top is **stirred**. Each spot of it stores its colour multiplied by how much of it there is, so when two blobs run together their colours average by volume. Nobody has to tell them to mix.

Colours mix like real paint because the game stores the light each one soaks up

For engineers

### Colours mix like real paint because the game stores the light each one soaks up

Colour is stored per cell as optical density in three channels, after the Beer-Lambert law, and turned back into light only when the page is drawn. Paper adds absorbance, so layers multiply; goop keeps its colour premultiplied by its amount, so stirring gives a volume-weighted geometric mean with no mixing step. Dissolved dye is its own share of each channel, and each dye rides the water at its own speed, so a black marker dot splits into rings that nothing draws.

[Under the hood](<#hood-mixing>)

Stirred paint lands between its two colours; washes laid over each other go darker

Under the hood

### Stirred paint lands between its two colours; washes laid over each other go darker

Every colour in the game is a hand-picked reflectance from 0 to 1 per channel. It is stored as absorbance \(optical density\), the negative logarithm of that reflectance, and drawn as its exponential. That is what the Beer-Lambert law describes, applied to three channels <sup>[Swinehart 1962](<https://professoroops.com/en/inside/research-simulation/#swinehart-1962>)</sup>.

- **Paper**: three absorbance values a cell over the whole grid \(up to 512 × 384 cells, about half a millimetre a cell; 288 × 216 on a small phone\). New colour adds to them.
- **Goop**: its colour is kept multiplied by how much goop there is, and divided out only when drawn. Colour flows premultiplied with the volume, so mixing and conservation come with the flow, the way premultiplied alpha works for transparency.

layered: e<sup>−\(A₁\+A₂\)</sup> = c₁ · c₂    stirred: e<sup>−\(\(1−t\)A₁ \+ tA₂\)</sup> = c₁<sup>1−t</sup> · c₂<sup>t</sup>

So paper multiplies reflectances, and goop takes their volume-weighted geometric mean. The paint board's stir only speeds up what the flow already does.

Try it: mix two colours four ways The game's own rulePick two colours from the game's palette and slide how much of the second goes into the stir. **What to look for:** blue and yellow stirred come out green, where a screen's usual average comes out a dull grey-green. Laid over each other they go darker than either. \(Layered lays one full unit of each colour's absorbance; built up takes two washes to the wash rule's ceiling.\) Then try black and white: stirred, it stays dark, because this model has no scattering white \(see [where we simplify](<#simplify>)\).

![Two chosen colours shown mixed four ways: a screen-style RGB average, stirred as paint, layered as washes, and layered washes built up to the game's cap](<https://professoroops.com/_assets/entity_eO7HIKGgTOBOsItEx105.png>)

- Colour A
- Colour B
- RGB average
- a screen's mix
- Stirred
- paint, goop
- Layered
- one on another
- Built up
- with the wash cap

Colour ARedYellowBlueGreenPinkBlackWhiteColour BRedYellowBlueGreenPinkBlackWhite

Share of B in the stir50 %

lightness Y: average—

stirred—

layered—

stirred A: red—

green—

blue—

layered A: red—

green—

blue—

![In the game, a heap of yellow tube paint and a heap of blue, stirred into green with a palette knife where they meet, beside a yellow and a blue watercolour wash crossing into a darker, duller green](<https://professoroops.com/_assets/entity_GRUZbXdJOReEVKWXg4UM.webp>)

**Two laws on one page.** Tube paint stirred with the knife lands between its colours. Two watercolour washes crossing go darker than both.

Washes laid over each other go darker than both; stirred paint lands in between

Watercolour washes laid over each other read 0.183, darker than yellow \(0.670\) or blue \(0.245\) alone; stirred tube paint reads 0.479, between its 0.814 and 0.355.

- watercolour, one wash over the other
- tube paint, stirred with the knife
- paint brush, strokes crossed

Data table

Washes laid over each other go darker than both; stirred paint lands in between

|  | watercolour, one wash over the other | tube paint, stirred with the knife | paint brush, strokes crossed |
| --- | --- | --- | --- |
| yellow alone | 0.67 | 0.81 | 0.81 |
| blue alone | 0.25 | 0.36 | 0.35 |
| both together | 0.18 | 0.48 | 0.58 |

Source: Measured on the released engine. Automated tests check that stirred blue and yellow come out green, not grey.

### Each tool lays colour its own way, so a scribbled patch never turns to mud

Dab real watercolour on the same spot again and again and it gets deeper, but it never turns black. In the game each drawing tool has its own rule for laying colour, and every rule levels off. A wash creeps up to a ceiling set by its own colour. A marker saturates instead of getting darker forever. Pencil levels off at a strength set by its colour and how hard it's pressed, and crayon stops adding once the spot is as dark as its own colour. So a patch a child goes over twenty times gets deeper but stays recognisably the colour the child chose.

The price is small and honest. Two thin glazes multiply almost exactly. Two washes built all the way up don't: each channel ends at the darker of the two ceilings.

[Under the hood](<#hood-tools>)

Each tool lays colour its own way, so a scribbled patch never turns to mud

Under the hood

### Each tool lays colour its own way, so a scribbled patch never turns to mud

Each stamp of a tool adds its colour, as absorbance, to the cell's. Every rule is a saturating curve, so the more colour a spot already holds, the less the next stamp adds:

- **Watercolour** creeps toward a ceiling set by its own colour, and wax or soap in the paper keeps most of it off.
- **Marker** pulls the spot toward its own colour instead of stacking on top.
- **Pencil** levels off at a strength set by its colour and how hard it's pressed, and the paper's tooth decides how much it grips.
- **Crayon** adds until the spot is as dark as the crayon itself, and lays wax as it goes.
- **Brush and tube** lay goop; wet on wet, they tint what's there.

These rules are per tool. They share the storage, not the formula. Over thick goop a stroke tints the goop as well, and the tip picks up a little of what it touches, so a dirty brush is real state.

A wash levels off at its own ceiling; plain adding would run on toward blackOne stroke lays several stamps on a spot. The blue channel levels off at yellow's ceiling and the red at blue's; the plain sums run off the top of the chart.

After 60 stamps of yellow the blue channel levels off near 3.15; after 60 more of blue the red channel ends near 2.92, while the plain sums run past 6.

- red channel
- green channel
- blue channel
- red, plain sum
- green, plain sum
- blue, plain sum

Data table

A wash levels off at its own ceiling; plain adding would run on toward black

| stamps on one spot \(60 of yellow, then 60 of blue\) | red channel | green channel | blue channel | red, plain sum | green, plain sum | blue, plain sum |
| --- | --- | --- | --- | --- | --- | --- |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 0.002 | 0.014 | 0.184 | 0.002 | 0.014 | 0.184 |
| 2 | 0.003 | 0.027 | 0.358 | 0.003 | 0.028 | 0.368 |
| 3 | 0.005 | 0.041 | 0.522 | 0.005 | 0.042 | 0.553 |
| 4 | 0.006 | 0.053 | 0.676 | 0.006 | 0.056 | 0.737 |
| 5 | 0.008 | 0.066 | 0.822 | 0.008 | 0.07 | 0.921 |
| 6 | 0.01 | 0.078 | 0.96 | 0.01 | 0.084 | 1.105 |
| 7 | 0.011 | 0.089 | 1.089 | 0.011 | 0.098 | 1.289 |
| 8 | 0.013 | 0.101 | 1.212 | 0.013 | 0.112 | 1.474 |
| 9 | 0.014 | 0.112 | 1.327 | 0.015 | 0.126 | 1.658 |
| 10 | 0.016 | 0.122 | 1.436 | 0.016 | 0.139 | 1.842 |
| 11 | 0.017 | 0.133 | 1.539 | 0.018 | 0.153 | 2.026 |
| 12 | 0.019 | 0.143 | 1.635 | 0.019 | 0.167 | 2.21 |
| 13 | 0.02 | 0.153 | 1.727 | 0.021 | 0.181 | 2.395 |
| 14 | 0.022 | 0.162 | 1.813 | 0.023 | 0.195 | 2.579 |
| 15 | 0.023 | 0.171 | 1.894 | 0.024 | 0.209 | 2.763 |
| 16 | 0.025 | 0.18 | 1.971 | 0.026 | 0.223 | 2.947 |
| 17 | 0.026 | 0.189 | 2.043 | 0.027 | 0.237 | 3.132 |
| 18 | 0.028 | 0.197 | 2.111 | 0.029 | 0.251 | 3.316 |
| 19 | 0.029 | 0.206 | 2.176 | 0.031 | 0.265 | 3.5 |
| 20 | 0.031 | 0.213 | 2.236 | 0.032 | 0.279 | 3.684 |
| 21 | 0.032 | 0.221 | 2.293 | 0.034 | 0.293 | 3.868 |
| 22 | 0.033 | 0.229 | 2.347 | 0.036 | 0.307 | 4.053 |
| 23 | 0.035 | 0.236 | 2.398 | 0.037 | 0.321 | 4.237 |
| 24 | 0.036 | 0.243 | 2.446 | 0.039 | 0.335 | 4.421 |
| 25 | 0.038 | 0.25 | 2.491 | 0.04 | 0.349 | 4.605 |
| 26 | 0.039 | 0.256 | 2.534 | 0.042 | 0.363 | 4.789 |
| 27 | 0.04 | 0.263 | 2.574 | 0.044 | 0.377 | 4.974 |
| 28 | 0.042 | 0.269 | 2.612 | 0.045 | 0.391 | 5.158 |
| 29 | 0.043 | 0.275 | 2.648 | 0.047 | 0.404 | 5.342 |
| 30 | 0.045 | 0.281 | 2.682 | 0.048 | 0.418 | 5.526 |
| 31 | 0.046 | 0.287 | 2.714 | 0.05 | 0.432 | 5.71 |
| 32 | 0.047 | 0.292 | 2.744 | 0.052 | 0.446 | 5.895 |
| 32.57 | — | — | — | — | — | 6 |
| 33 | 0.049 | 0.298 | 2.772 | 0.053 | 0.46 | — |
| 34 | 0.05 | 0.303 | 2.799 | 0.055 | 0.474 | — |
| 35 | 0.051 | 0.308 | 2.824 | 0.057 | 0.488 | — |
| 36 | 0.053 | 0.313 | 2.848 | 0.058 | 0.502 | — |
| 37 | 0.054 | 0.318 | 2.871 | 0.06 | 0.516 | — |
| 38 | 0.055 | 0.322 | 2.892 | 0.061 | 0.53 | — |
| 39 | 0.057 | 0.327 | 2.912 | 0.063 | 0.544 | — |
| 40 | 0.058 | 0.331 | 2.931 | 0.065 | 0.558 | — |
| 41 | 0.059 | 0.336 | 2.948 | 0.066 | 0.572 | — |
| 42 | 0.06 | 0.34 | 2.965 | 0.068 | 0.586 | — |
| 43 | 0.062 | 0.344 | 2.981 | 0.069 | 0.6 | — |
| 44 | 0.063 | 0.348 | 2.996 | 0.071 | 0.614 | — |
| 45 | 0.064 | 0.351 | 3.01 | 0.073 | 0.628 | — |
| 46 | 0.065 | 0.355 | 3.023 | 0.074 | 0.642 | — |
| 47 | 0.067 | 0.359 | 3.036 | 0.076 | 0.656 | — |
| 48 | 0.068 | 0.362 | 3.047 | 0.078 | 0.67 | — |
| 49 | 0.069 | 0.365 | 3.059 | 0.079 | 0.683 | — |
| 50 | 0.07 | 0.369 | 3.069 | 0.081 | 0.697 | — |
| 51 | 0.071 | 0.372 | 3.079 | 0.082 | 0.711 | — |
| 52 | 0.073 | 0.375 | 3.088 | 0.084 | 0.725 | — |
| 53 | 0.074 | 0.378 | 3.097 | 0.086 | 0.739 | — |
| 54 | 0.075 | 0.381 | 3.105 | 0.087 | 0.753 | — |
| 55 | 0.076 | 0.384 | 3.113 | 0.089 | 0.767 | — |
| 56 | 0.077 | 0.386 | 3.121 | 0.091 | 0.781 | — |
| 57 | 0.079 | 0.389 | 3.128 | 0.092 | 0.795 | — |
| 58 | 0.08 | 0.392 | 3.134 | 0.094 | 0.809 | — |
| 59 | 0.081 | 0.394 | 3.14 | 0.095 | 0.823 | — |
| 60 | 0.082 | 0.396 | 3.146 | 0.097 | 0.837 | — |
| 61 | 0.247 | 0.453 | 3.146 | 0.267 | 0.914 | — |
| 62 | 0.403 | 0.508 | 3.146 | 0.436 | 0.992 | — |
| 63 | 0.55 | 0.559 | 3.146 | 0.606 | 1.069 | — |
| 64 | 0.688 | 0.608 | 3.146 | 0.775 | 1.147 | — |
| 65 | 0.819 | 0.654 | 3.146 | 0.945 | 1.224 | — |
| 66 | 0.942 | 0.698 | 3.146 | 1.115 | 1.301 | — |
| 67 | 1.059 | 0.739 | 3.146 | 1.284 | 1.379 | — |
| 68 | 1.169 | 0.779 | 3.146 | 1.454 | 1.456 | — |
| 69 | 1.272 | 0.816 | 3.146 | 1.624 | 1.534 | — |
| 70 | 1.37 | 0.852 | 3.146 | 1.793 | 1.611 | — |
| 71 | 1.463 | 0.885 | 3.146 | 1.963 | 1.688 | — |
| 72 | 1.55 | 0.917 | 3.146 | 2.132 | 1.766 | — |
| 73 | 1.632 | 0.948 | 3.146 | 2.302 | 1.843 | — |
| 74 | 1.709 | 0.976 | 3.146 | 2.472 | 1.921 | — |
| 75 | 1.783 | 1.004 | 3.146 | 2.641 | 1.998 | — |
| 76 | 1.852 | 1.03 | 3.146 | 2.811 | 2.075 | — |
| 77 | 1.917 | 1.054 | 3.146 | 2.981 | 2.153 | — |
| 78 | 1.978 | 1.077 | 3.146 | 3.15 | 2.23 | — |
| 79 | 2.036 | 1.1 | 3.146 | 3.32 | 2.308 | — |
| 80 | 2.091 | 1.12 | 3.146 | 3.489 | 2.385 | — |
| 81 | 2.143 | 1.14 | 3.146 | 3.659 | 2.462 | — |
| 82 | 2.191 | 1.159 | 3.146 | 3.829 | 2.54 | — |
| 83 | 2.237 | 1.177 | 3.146 | 3.998 | 2.617 | — |
| 84 | 2.281 | 1.194 | 3.146 | 4.168 | 2.695 | — |
| 85 | 2.322 | 1.21 | 3.146 | 4.338 | 2.772 | — |
| 86 | 2.36 | 1.225 | 3.146 | 4.507 | 2.849 | — |
| 87 | 2.397 | 1.24 | 3.146 | 4.677 | 2.927 | — |
| 88 | 2.431 | 1.254 | 3.146 | 4.846 | 3.004 | — |
| 89 | 2.464 | 1.267 | 3.146 | 5.016 | 3.082 | — |
| 90 | 2.494 | 1.279 | 3.146 | 5.186 | 3.159 | — |
| 91 | 2.523 | 1.291 | 3.146 | 5.355 | 3.237 | — |
| 92 | 2.55 | 1.302 | 3.146 | 5.525 | 3.314 | — |
| 93 | 2.576 | 1.313 | 3.146 | 5.694 | 3.391 | — |
| 94 | 2.6 | 1.323 | 3.146 | 5.864 | 3.469 | — |
| 94.8 | — | — | — | 6 | — | — |
| 95 | 2.623 | 1.332 | 3.146 | — | 3.546 | — |
| 96 | 2.645 | 1.341 | 3.146 | — | 3.624 | — |
| 97 | 2.665 | 1.35 | 3.146 | — | 3.701 | — |
| 98 | 2.685 | 1.358 | 3.146 | — | 3.778 | — |
| 99 | 2.703 | 1.366 | 3.146 | — | 3.856 | — |
| 100 | 2.72 | 1.373 | 3.146 | — | 3.933 | — |
| 101 | 2.736 | 1.38 | 3.146 | — | 4.011 | — |
| 102 | 2.751 | 1.386 | 3.146 | — | 4.088 | — |
| 103 | 2.766 | 1.393 | 3.146 | — | 4.165 | — |
| 104 | 2.779 | 1.399 | 3.146 | — | 4.243 | — |
| 105 | 2.792 | 1.404 | 3.146 | — | 4.32 | — |
| 106 | 2.804 | 1.409 | 3.146 | — | 4.398 | — |
| 107 | 2.816 | 1.414 | 3.146 | — | 4.475 | — |
| 108 | 2.826 | 1.419 | 3.146 | — | 4.552 | — |
| 109 | 2.836 | 1.424 | 3.146 | — | 4.63 | — |
| 110 | 2.846 | 1.428 | 3.146 | — | 4.707 | — |
| 111 | 2.855 | 1.432 | 3.146 | — | 4.785 | — |
| 112 | 2.864 | 1.436 | 3.146 | — | 4.862 | — |
| 113 | 2.872 | 1.44 | 3.146 | — | 4.939 | — |
| 114 | 2.879 | 1.443 | 3.146 | — | 5.017 | — |
| 115 | 2.886 | 1.447 | 3.146 | — | 5.094 | — |
| 116 | 2.893 | 1.45 | 3.146 | — | 5.172 | — |
| 117 | 2.9 | 1.453 | 3.146 | — | 5.249 | — |
| 118 | 2.906 | 1.456 | 3.146 | — | 5.326 | — |
| 119 | 2.911 | 1.458 | 3.146 | — | 5.404 | — |
| 120 | 2.917 | 1.461 | 3.146 | — | 5.481 | — |

Source: Arithmetic from the game's watercolour rule at full brush, with the palette's yellow and blue.

## Water makes marker run but leaves pencil and crayon where they are

Pour water over a real drawing and the marker runs while the pencil and crayon stay put. Marker ink is dye, and dye dissolves. Pencil and crayon are solid pigment pressed into the paper.

The game keeps the same difference. Beside its three colour numbers, every spot records how much of that colour is dissolved dye and how much is held in the fibres. Water may move only what isn't held, and dye is never held. Each tool says what it lays. Marker ink is all dye. Watercolour is part dye and part pigment grains. Coloured pencil, grey pencil and crayon are almost entirely held.

So a wash brushed over a pencil drawing blooms right through, and the line is still there when it dries. Pour water on pencil or crayon and over 95 % of the line stays, which an automated test checks. Rub the same pencil line and it smudges, because graphite sits loose on the fibres. Crayon hardly smudges.

### One spot of paper cut open, from the top layer down

#### Floating film

Oil, marbling ink.

*Moves on the water's surface.*

#### Goop

Paint, ketchup, mud. Its colour is kept together with how much of it there is.

*Flows on its own, stains the paper below.*

#### Water

Standing water and wetness in the fibres.

*Carries whatever is free.*

#### The paper itself

All the colour soaked in, split into:

- **Dye**: moves with water, each dye at its own speed.
- **Free pigment**: the rest of the colour. Moves, more slowly.
- **Held**: water can't move it.
- **Loose**: a rubbing finger can.
- **Wax, soap**: keep washes and bleach off.

[Under the hood](<#hood-held>)

Water makes marker run but leaves pencil and crayon where they are

Under the hood

### Water makes marker run but leaves pencil and crayon where they are

In every cell and every colour channel, water may move whatever colour isn't held, and the held part can never eat into the dye. Held colour is kept per channel, so a wash laid over a pencil line is as free to run as on blank paper.

Each dry medium says two things about what it lays: how much of it the fibres hold, and how much sits loose for a finger to smudge. All of them are almost fully held. Grey pencil is the loosest, coloured pencil smudges a little, crayon hardly at all, and melted wax not at all.

Crayon resist works through the wash rule, not by keeping water out. Wetness under crayon matches bare paper, but the colour stays off the wax, and a test checks that a wash over crayon stays clearly lighter than the wash beside it.

Marker is all dye; pencil and crayon are almost all held

Marker is 100 % dissolved dye and watercolour half dye, half free pigment; coloured pencil holds 98 %, grey pencil 97 % and crayon 99 % in the fibres.

- dissolved dye \(runs\)
- free pigment \(moves slower\)
- held in the fibres \(stays\)

Data table

Marker is all dye; pencil and crayon are almost all held

|  | dissolved dye \(runs\) | free pigment \(moves slower\) | held in the fibres \(stays\) |
| --- | --- | --- | --- |
| Marker | 100 | 0 | 0 |
| Watercolour | 50 | 50 | 0 |
| Coloured pencil | 0 | 2 | 98 |
| Grey pencil | 0 | 3 | 97 |
| Crayon | 0 | 1 | 99 |

Source: The shares each drawing tool lays in the game.

## A marker dot splits into rings because its dyes travel at different speeds

Draw a black dot, drop water on it and wait. A blue ring spreads out, a pink band follows, and a yellow patch stays in the middle. Science teachers call this chromatography. Black ink is a mix of dyes, and each one clings to the paper fibres by a different amount.

In the game a dye is one of the three colour channels. The dye that soaks up red light is the cyan one, green's is the magenta, blue's is the yellow. Whenever water moves between two spots of paper, each dye goes along at its own share of the water's speed. In a black marker the cyan dye nearly keeps up with the water, the magenta lags well behind and the yellow hardly moves. The water code has no idea what a marker is, and nothing draws a ring. The rings come out of three speeds.

The speeds were chosen so the rings show clearly, so they are tuned, not measured. In the released game every marker splits with black's three speeds. next update Each ink gets its own: green splits into yellow outside blue, purple into pink outside blue, brown into yellow, pink and a little blue.

[Under the hood](<#hood-rings>)

A marker dot splits into rings because its dyes travel at different speeds

Under the hood

### A marker dot splits into rings because its dyes travel at different speeds

The water pass runs about 30 times a second over the wet parts of the page. Between every pair of neighbouring cells, each dye goes along with the water that moved, scaled by that dye's own speed. A dye's speed comes from how strongly it clings to the fibres, the same idea as the retention factor in a chemistry lab's paper chromatography, except that ours are typed in rather than measured.

- Dye moves freely only once the paper is properly damp; on barely damp paper it creeps.
- A gentle evening-out between wet neighbours softens the rings.
- Near a drying edge, water and dye are pulled toward the drier side, which is what leaves the blue ring at the edge.

Colour and dye are kept in step, so the dye's colour is moved exactly once and nothing is made or lost. Parts of the page with no dye in them skip this work altogether. An automated test wets a black dot and finds the cyan ring well outside it, with the dot's total colour kept.

next update Every marker colour gets its own three speeds, so green, purple, brown and red each split their own way.

Try it: a marker dot in a drop of water The game's own ruleA drop has just landed on a black marker dot. Tap the paper to add another drop, or press Add a drop. **What to look for:** the cyan dye rides out with the water's edge and dries there as a blue ring, the magenta stops halfway, the yellow hardly leaves the dot. The readout gives how far out each dye sits on average and checks none is lost. The water's spread, the dye rule and every rate are the game's; the drop soaking in and the drying are simplified. Green, purple, brown and red show each ink's own split next update.

![A marker dot on paper, with water spreading from it and each colour of dye travelling at its own speed](<https://professoroops.com/_assets/entity_29PuXTtL7z1RCoVdOVFu.png>)

MarkerBlackGreenPurpleBrownRed

Water in a drop8

Fast-forward3×

time on the page—

mean distance, cells: cyan—

magenta—

yellow—

dye kept—

![A black marker dot under a drop of water in the game, opened into a blue ring, a pink band and a yellow centre.](<https://professoroops.com/_assets/entity_GYybWRMkMASDEmafp2JB.webp>)

**The real thing, in the game.** A black marker dot a minute after a drop of water.

### A watercolour wash stays its own colour right up to its darker rim

A wash's dye has no reason to split. In a wash, free dye goes at the same speed in all three channels, so a blue wash stays blue to its edge. In an automated test, every spot of a blue, red or yellow wash 30 seconds into drying is within 3° of hue of the middle.

The pigment half is grains, and grains only ride along while the paper is properly wet. As a wash dries, its thin edge empties first, water flows out toward it and brings colour with it. In the game's test a dried wash's rim is 1.3 to 2.5 times as dark as its middle, as in a dried coffee drop <sup>[Deegan 1997](<https://professoroops.com/en/inside/research-simulation/#deegan-1997>)</sup>. The picture of water in the sheet carrying pigment to the edges comes from early computer watercolour <sup>[Curtis 1997](<https://professoroops.com/en/inside/research-simulation/#curtis-1997>)</sup>; the game gets there with a much simpler local rule. Wet a dried wash again and it blooms in its own colour.

[Under the hood](<#hood-wash>)

A watercolour wash stays its own colour right up to its darker rim

Under the hood

### A watercolour wash stays its own colour right up to its darker rim

Each pass, about 30 times a second, runs in JavaScript and as a WebAssembly twin that a test holds to the same result:

- **Water** flows down differences in wetness, faster where the paper's fibre is denser, so fronts come out ragged.
- **Evening out**: colour slowly evens between neighbours that are both wet.
- **Grains** ride a share of the water's flow that grows quickly with wetness, so they need properly wet paper.
- **Edge pull**: where one side is drier, water and colour are pulled toward it, capped so it stays stable. This is the coffee-ring effect.
- **Tide mark**: where wet meets dry, a faint brownish line is **added**. It is the one term here that makes colour.

An automated test holds the dye in a watercolour to within a ten-thousandth per channel over a minute on wet paper, in JavaScript and in the WebAssembly kernel alike.

The rim of a drying wash grows darker than its middle

A watercolour dab goes from 1.02 at 20 s to 2.54 at 180 s; an ink drop from 1.44 at 20 s to 4.15 at 60 s.

- watercolour dab
- ink drop

Data table

The rim of a drying wash grows darker than its middle

| seconds after laying it | watercolour dab | ink drop |
| --- | --- | --- |
| 20 | 1.02 | 1.44 |
| 60 | 1.15 | 4.15 |
| 180 | 2.54 | — |

Source: Measured on the released engine. An automated test holds a dried wash's rim to 1.3 to 2.5 times the inside.

Dye moves in damp paper; pigment grains need it wet

Free dye is carried at its full 0.9 share from a wetness of 0.2; pigment grains reach their 0.5 share only at a wetness of 0.5.

- free dye
- pigment grains

Data table

Dye moves in damp paper; pigment grains need it wet

| wetness of both cells | free dye | pigment grains |
| --- | --- | --- |
| 0 | 0 | 0 |
| 0.02 | 0.09 | 0.0008 |
| 0.04 | 0.18 | 0.0032 |
| 0.06 | 0.27 | 0.0072 |
| 0.08 | 0.36 | 0.0128 |
| 0.1 | 0.45 | 0.02 |
| 0.12 | 0.54 | 0.0288 |
| 0.14 | 0.63 | 0.0392 |
| 0.16 | 0.72 | 0.0512 |
| 0.18 | 0.81 | 0.0648 |
| 0.2 | 0.9 | 0.08 |
| 0.22 | 0.9 | 0.0968 |
| 0.24 | 0.9 | 0.1152 |
| 0.26 | 0.9 | 0.1352 |
| 0.28 | 0.9 | 0.1568 |
| 0.3 | 0.9 | 0.18 |
| 0.32 | 0.9 | 0.2048 |
| 0.34 | 0.9 | 0.2312 |
| 0.36 | 0.9 | 0.2592 |
| 0.38 | 0.9 | 0.2888 |
| 0.4 | 0.9 | 0.32 |
| 0.42 | 0.9 | 0.3528 |
| 0.44 | 0.9 | 0.3872 |
| 0.46 | 0.9 | 0.4232 |
| 0.48 | 0.9 | 0.4608 |
| 0.5 | 0.9 | 0.5 |
| 0.52 | 0.9 | 0.5 |
| 0.54 | 0.9 | 0.5 |
| 0.56 | 0.9 | 0.5 |
| 0.58 | 0.9 | 0.5 |
| 0.6 | 0.9 | 0.5 |
| 0.62 | 0.9 | 0.5 |
| 0.64 | 0.9 | 0.5 |
| 0.66 | 0.9 | 0.5 |
| 0.68 | 0.9 | 0.5 |
| 0.7 | 0.9 | 0.5 |
| 0.72 | 0.9 | 0.5 |
| 0.74 | 0.9 | 0.5 |
| 0.76 | 0.9 | 0.5 |
| 0.78 | 0.9 | 0.5 |
| 0.8 | 0.9 | 0.5 |
| 0.82 | 0.9 | 0.5 |
| 0.84 | 0.9 | 0.5 |
| 0.86 | 0.9 | 0.5 |
| 0.88 | 0.9 | 0.5 |
| 0.9 | 0.9 | 0.5 |
| 0.92 | 0.9 | 0.5 |
| 0.94 | 0.9 | 0.5 |
| 0.96 | 0.9 | 0.5 |
| 0.98 | 0.9 | 0.5 |
| 1 | 0.9 | 0.5 |

Source: The shape of the game's own rules for what the water carries.

## Red cabbage juice works as a real acid test, turning pink with vinegar and blue-green with baking soda

Red cabbage juice is a real acid detector. Lemon turns it pink, baking soda turns it blue and then green. In the game, a spot soaked with cabbage juice stores no colour for it at all. It stores how much dye is there. Each time that part of the page is packed for the screen, the game reads how acidic the spot is and looks the colour up in a chart.

The chart has 141 shades, one for every tenth of a pH unit from 0 to 14. They are blended from 8 hand-picked colours, in the order published cabbage charts give. The shades are ours, so we say the colour is looked up from a chart, not computed from chemistry.

Because the colour is never stored, it can never go out of date. Add soda and the spot changes colour the next time it's redrawn. Turmeric and tea work the same way, as a shift from their own stain colour. A blob of blueberry on soap turns blue-green, because goop carrying a dye reads how far the paper under it is from neutral. An automated test checks it.

[Under the hood](<#hood-cabbage>)

Red cabbage juice works as a real acid test

Under the hood

### Red cabbage juice works as a real acid test

When a part of the page is packed for the screen, each cell's amount of cabbage dye is multiplied by the chart's entry for the pH there, and added to the colour as absorbance.

The chart is built once when the game starts. Between two hand-picked colours it blends **in reflectance**, the light that comes back, and only then turns the result into absorbance, so the in-between shades look like real mixtures. A small lookup table means no logarithms while drawing. Turmeric and tea work the same way, but add only their shift away from their colour at neutral. The pH reading itself is covered in [Chemistry and pH](<https://professoroops.com/en/inside/chemistry/>).

Try it: the cabbage colour chart The game's own ruleDrag along the strip or use the pH slider. **What to look for:** the colour is the chart's entry times the amount of dye, so more juice gives a deeper shade from the same entry; only the pH moves you along the chart. The ticks under the strip are the 8 hand-picked knots.

![The red cabbage colour chart from pH 0 to 14, with the chosen pH marked and a large swatch of its colour on paper](<https://professoroops.com/_assets/entity_XNGrjJ1qwRe3IICzNVde.png>)

- pH 0 · acid
- 7 · neutral
- alkaline · 14
- on paper

pH3

pH—

Amount of dye1.00

table entry—

absorbance per unit: red—

green—

blue—

added: red—

green—

blue—

![In the game, paper stained purple with red cabbage juice, with a pink spot where vinegar was dropped and a blue spot round a little white heap of baking soda](<https://professoroops.com/_assets/entity_Bfd3ufymW7JyWLEgvTyG.webp>)

**One dye, three colours.** A drop of vinegar and a pinch of baking soda on cabbage-stained paper. The blue round the soda is the next update's next update; in the released game the same soda turns it blue-green.

## Bleach and sunlight fade colours unevenly, so black marker turns orange before it goes pale

Draw a bleach pen over black marker and it doesn't just go paler. It turns red-brown, then orange, then pale yellow, the way real bleach-pen art does. The game's bleach takes absorbance out faster in red and green than in blue. Black loses its yellow part last, so the in-between colours appear on their own. Crayon or soap under the colour keeps most of the bleach off, and every bit of colour it removes uses some of the bleach up, so a small drop on a dark patch runs out.

Bleach is a named rule in the game's table of reactions, so this part is written chemistry, not emergent chemistry. What it shares with everything else is that it reads the colour numbers, whatever put the colour there. Rust in the paper bleaches just like marker.

Sunlight fades too. Leave a page for a week in a sunny window and the dyes fade, reds and yellows first. Whatever lay on the paper, a sticker, tape, a leaf or a blob of paint, keeps its patch dark, and you get a sun print. In the released game the fade is three flat factors on every uncovered colour, pencil included. next update The fade depends on what made the colour. Marker dye takes the full fade, crayon and coloured pencil much less, grey pencil none, and the paper itself yellows a little.

[Under the hood](<#hood-fading>)

Bleach and sunlight fade colours unevenly

Under the hood

### Bleach and sunlight fade colours unevenly

Bleach shrinks absorbance exponentially, channel by channel, at a different rate in each: fastest in red, slowest in blue. That one difference is why black passes through brown and orange on its way to pale yellow.

- The rate grows with the bleach's strength and how wet the paper is, and wax or soap in the paper keeps most of it off.
- Bleach wears off in wet paper, and every bit of colour it takes out uses some of it up.
- Goop on top fades by its own material: food a lot, paint, mud, wax and plastic hardly. Cabbage dye fades too.

Sun in the released game: every uncovered cell keeps a fixed share of its colour in each channel, so reds and yellows fade most, and the paper yellows a touch. Anything lying on the paper counts as full shade.

next update The fade runs on every time skip, scaled by how much UV reaches the page and for how long. Dye takes the full fade; held colour is spared by its medium's lightfastness, with graphite fully lightfast. A lamp gives a small fraction of a window's UV, and bare paper yellows slowly over its first couple of weeks.

Try it: bleach on marker stripes The game's own ruleBlack, red and blue marker stripes, with an invisible white crayon stripe drawn down the right. Two drops of bleach have just landed. Tap to drop more, or press Drop bleach. **What to look for:** black goes through brown and orange to pale yellow, thinner bleach at a drop's edge leaves an orange ring, and the colour under the crayon stays. The drop's size is ours; the fading, the bleach used up and the wax's protection are the game's rule. In the game bleach also travels with the water; here it stays where it lands.

![Black, red and blue marker stripes on paper with a white crayon stripe, fading through brown, orange and yellow where bleach was dropped, except under the crayon](<https://professoroops.com/_assets/entity_O10equKt5pcBfszQ73os.png>)

Bleach in a drop2.5

Speed×0.25

bleach left—

colour taken out—

![In the game, three bleach-pen lines across a black marker patch: each fades to pale with red and orange edges, but where it crosses a white crayon stripe under the ink it stays dark red-brown](<https://professoroops.com/_assets/entity_Bjui6GZ9yrLHgHDoKpEb.webp>)

**Bleach-pen art.** Black marker fades through red and orange to pale. Where the lines cross a white crayon stripe under the ink, the wax keeps most of the bleach off and the black only turns dark brown.

A week in a sunny window, now and in the next updateWorked from the game's own fade rule \(arithmetic, not a screenshot\): each swatch is a solid patch on the game's paper colour. In the released game a week of sun applies the same three factors to everything uncovered. The next update next update fades by what made the colour and yellows the paper.

![Colours before and after a week in a sunny window, now and in the next update](<https://professoroops.com/_assets/entity_BUfPQVFFAIVITJevNn8V.png>)

- A week of sun
- Before
- now
- next update
- Red marker
- Yellow marker
- Blue marker
- Black marker
- Grey pencil
- Red crayon
- Bare paper

## The page on screen is drawn from those numbers, not kept as a picture

The page you see isn't stored as a picture. The game keeps only the numbers: absorbance, dye, wetness, goop height and the rest. The simulation runs in a background worker. It packs the parts of the page that changed into small square tiles and hands them to the graphics chip, which turns absorbance back into colour for every pixel, lights it with the room's light and adds relief and shine.

Some things get their look only at that moment. Cabbage colour is looked up then. Grease stains, salt crust and wires get their colour then, and oil floating on water is folded into what's under it. Because these are worked out at drawing time, they can't drift out of step with the simulation.

Wet paper is drawn darker, as wet paper looks. Clear goop like honey or oil is looked through, not painted over. Its colour is the light that comes back up through it, so honey or oil over a dried ketchup stain doesn't pale it. When you save a picture, the same shader draws the page again with sharper edges and pigment settling into the paper's grain, detail that exists only in the saved picture.

[Under the hood](<#hood-screen>)

The page on screen is drawn from those numbers, not kept as a picture

Under the hood

### The page on screen is drawn from those numbers, not kept as a picture

Colour reaches the graphics chip as absorbance, not as colour, and the chip filters it smoothly between cells. Filtering absorbance makes an edge between two cells blend as a geometric mean, the same way the paint itself mixes. Goop's colour and its amount are filtered separately and divided afterwards, so a thin edge gets no dark fringe; it is the premultiplied-alpha trick again.

The shader then works the colour out per pixel: absorbance back to light on the paper's own colour and fibre, wet spots darkened, goop laid over it with see-through goop letting what's under it show, and finally ambient shade, shadow, the room's light and a highlight.

On a busy page at a low detail setting, the changed tiles are sent under a per-frame budget, the longest-waiting ones first, and the tiles under the child's hand always go. The picture stays responsive where the child is looking.

### From the simulation's numbers to the screen

#### Numbers in the worker

Absorbance, dye, wetness, goop and the rest, simulated in a background Web Worker.

#### Pack what changed

Only tiles that changed. Cabbage, grease, salt and wire get their colour here; floating oil is folded in.

#### Hand over

Handed to the main thread without copying.

#### Smooth

Filtered as absorbance, so cell edges blend like paint.

#### Shade

Absorbance back to light, wet darkening, goop over it, shadow, light, shine.

#### Screen

A child's painting, from a handful of numbers a spot.

## Water, fire, bleach, tape and ants all act on the same colour, whoever put it there

Water, fire, bleach, smudging fingers, tape, stencils, sponges, ants and dogs all read or write the same colour channels. None of them asks who put the colour there. That's where the surprises come from: the water doesn't know about markers, and the bleach doesn't know what drew the colour it fades. Where we did write a special rule, such as bleach, iron-gall ink or the cabbage chart, it reads the shared numbers, never which tool put the colour there. Each tool's way of laying colour is its own rule, but they all write into the same numbers.

3

Numbers per spot of paper for the colour you see there, however many colours went into it.

2

Ways colours mix, stacking in paper and stirring in paint, from that one way of writing colour down.

512×384

Spots of paper on a large screen, each about half a millimetre across.

141

Cabbage shades in the colour chart, blended from 8 hand-picked colours.

30/s

Passes a second of water and colour through the wet parts of the page; calm patches go less often.

Shared: acid element → cabbage chart

### Run a battery through salty water on paper soaked in cabbage juice

The paper turns pink at one clip. The circuit writes acid; the chart reads it; neither knows the other.

*[Electricity](<https://professoroops.com/en/inside/electricity/>)* · pinned by a test

Shared: tannin \+ iron in the paper

### Leave a rusty pin in damp, tea-stained paper

Blue-black ink forms where water brings the tea to the rust, slower under a puddle.

*[Chemistry and pH](<https://professoroops.com/en/inside/chemistry/>)* · pinned by tests

Shared: free colour \+ surface flow

### Touch a soapy drop to a wet watercolour

The paint is pushed back into a ring, because surface flow moves whatever colour is free.

*[Runny, sticky and oily](<https://professoroops.com/en/inside/liquids/>)* · pinned by a test

Shared: carried colour

### Let a cat walk out of a paint puddle

Paw prints fade step by step as the paws run out of paint, by the same carrying rule balls, tyres and rollers use.

*[Animals with their own minds](<https://professoroops.com/en/inside/creatures/>)* · pinned by a test

Shared: water wicking faster through salt

### Touch a wet brush to a salty glue line

The colour races along the line and the crust takes it on.

*[Water in paper](<https://professoroops.com/en/inside/water/>)* · pinned by a test

Shared: wax in the paper

### Draw in crayon, then brush a wash or bleach over it

The crayon lines stay clean: wax keeps off the wash and most of the bleach.

*[Pencil, crayon and paper](<https://professoroops.com/en/inside/drawing/>)* · pinned by tests

## The game keeps paint mixing like paint and layers going darker, and skips the rest

Real colour is a spectrum of light meeting particles that absorb and scatter it. On a child's tablet we keep the part people recognise, that paint mixes like paint and layers go darker, and spend nothing on the rest. These are the trades we made, and what they cost.

**In real life.** Pigments absorb bands of a spectrum, and mixes depend on the whole spectrum

**In the game.** Three channels, worked on display values directly

**Why that's enough.** Cheap, fits a texture, runs on phones. Blue and yellow make green because of how the palette's colours were picked: its blue takes most red, its yellow most blue. Lost: colours that match in one light and not another, and true reflectance.

**In real life.** Paint scatters light as well as absorbing it <sup>[Kubelka 1931](<https://professoroops.com/en/inside/research-simulation/#kubelka-1931>)</sup>

**In the game.** Absorption only. A published pigment-mixing method <sup>[Sochorová 2021](<https://professoroops.com/en/inside/research-simulation/#sochorova-2021>)</sup> was considered and ruled out by its licence

**Why that's enough.** One number per channel, and both mixing laws are a single add or average. Lost: white is weak. Black and white stirred half and half come out about 0.28 grey, where a screen average gives 0.525. White crayon can't lighten a dark wash.

**In real life.** Glazes multiply exactly

**In the game.** Each channel creeps up to a ceiling set by the colour itself

**Why that's enough.** Dabs stay true and never turn to mud. Thin glazes still nearly multiply; two washes built all the way up end at the darker of the two ceilings in each channel, not at their sum.

**In real life.** How inks separate depends on the dyes, the solvent and the paper

**In the game.** Three tuned speeds per ink

**Why that's enough.** The rings must show. Not predictive. In the released game every marker uses black's speeds, so a yellow marker's yellow dye hardly runs.

**In real life.** Pigment is grains of many sizes

**In the game.** A share of the water's flow that grows with wetness

**Why that's enough.** Gives the coffee-ring rim. No particle sizes; granulation appears only in saved pictures.

**In real life.** Cabbage colour is chemistry

**In the game.** A chart of 8 hand-picked shades, in the order published charts give

**Why that's enough.** Reads clearly and can't go stale. No kinetics, no history: acid gone means pink gone.

**In real life.** Each dye fades at its own rate in light

**In the game.** Three factors per channel; next update one lightfastness per medium

**Why that's enough.** Readable: reds and yellows go first, blues last. That tendency is coded for every dye, and any cover counts as full shade, which gives crisp sun prints.

**In real life.** A stain moves colour from the liquid into the fibres

**In the game.** The paper gains colour; the goop doesn't lose any

**Why that's enough.** Cheap: nothing has to be booked between the two layers. So stains copy, and with the tide mark and iron-gall ink they're among the few places colour is made.
