Skip to content

Flat colour on shape_collage — stay under the knee

shape_collage is the one system that draws a graphic rather than light: flat opaque elements on their own paper, hard-edged, in painter order. Everything that makes that look work comes from a single palette constraint, and it comes off the tonemap rather than off any parameter.

Keep every element colour’s brightest channel at or under linear 0.6 — sRGB byte 0xcb in the hex you write.

That is ADR-0046’s KNEE, and below it the tonemap curve is exactly the identity — so the fill survives the whole post chain unshaded: the value the element wrote is the value that leaves the tonemap, to within the 8-bit write’s own rounding. Bloom’s threshold sits above that same knee, so a canvas living under it also gets no halo and its edges stay hard. One constraint, both properties, and neither is a parameter you can reach for instead. Author a brighter palette and you lose the flat fill and the hard edge together, with nothing to tell you why.

[!IMPORTANT] Under the knee the hex you typed is the hex on screen. A stop is sRGB and is decoded once at load — the same mapping stated at the top of this file — so the decode and the display encode are inverses and the identity curve between them changes nothing. On collage_suprematist: #494949 renders #494949, #c24f63 renders #c24f63. The residual is the LUT’s own 8-bit linear storage, up to two levels on a very dark channel and nothing on a bright one. What the knee buys on top of that is that no element is shaded, tinted or haloed on the way — which is the whole of the flat-graphic look. The paper is the exception, because it is the one plateau deliberately above the knee: at linear 0.851 the tonemap is no longer the identity, so #eeece5 renders #e2e0da. Author the elements by the hex; author the paper by the result.

The paper is the deliberate exception. The curve’s own table records f(1.0) = 0.800 and 1.0 is asymptotically unreachable, so pure white paper does not exist: #ffffff presents at about 80 % and anything near it costs a linear emission well over 1, which re-enters bloom’s threshold and forfeits the free hard edge. Off-white is the affordable ground, and both of the reference canvases this system was built from are off-white anyway. #e6e3d8 and #d9d5c8 are what the two shipped presets use.

Author the palette as plateaus, not as a gradient. An element takes one colour off the LUT at its coordinate, so a smooth ramp shades every element by wherever it happens to sit. A pair of stops a ten-thousandth apart is a hard transition:

[palette]
stops = [
{ at = 0.0000, color = "#1a1a1a" }, # band 0 — an element at coord 0.0625
{ at = 0.1249, color = "#1a1a1a" },
{ at = 0.1251, color = "#8c1c24" }, # band 1 — an element at coord 0.1875
{ at = 0.2499, color = "#8c1c24" },
# … six more, the last one the paper …
]

Eight bands is not arbitrary. The layout grammar draws each element’s colour from eight evenly spaced coordinates at band centres (k/8 + 1/16) and reserves the last for the paper, so an eight-plateau palette resolves every generated element exactly and no element ever draws the ground’s own colour and vanishes. Other counts work; their elements just land wherever those eight coordinates fall.

presets/collage_suprematist.toml and presets/collage_onwhite.toml are both built this way and carry the arithmetic in their headers.


Built from a8ce055 at version 0.115.0. This site tracks main and is not versioned per release.