Ink on paper — ink_amount, paper_, ink_, ink_gamma
The last stage before present, and the only engine-wide one that is not
per-preset: it remaps the one finished frame, which during a cross-preset dissolve
is the blended frame of both presets. Your ink_*/paper_*
values therefore crossfade with the dissolve rather than snapping — a switch from a
white-paper preset into a black-ink one travels between the two poles. It reads each
pixel’s brightness as an ink density and repaints the frame between two colours:
paper where the frame was dark, ink where it was bright. The defaults are white paper and
black ink, so ink_amount = "1" alone gives black marks on a white field —
the “ink on paper” look. Works on any scene, sparse or full-screen, because it
operates on the finished frame rather than a scene’s pipeline.
This is the one control that reaches a dark-on-light look at all. The scenes draw
additively (a lightening model), so a dark stroke colour adds nothing and a
light bg_bright just washes the strokes out — no combination of bg_* and
palette colours gets there. The remap inverts the tone at the end instead.
Ink reads the frame after the tonemap, which is what it has always read —
display-referred pixels in 0..1. So nothing in this section changed with Plan
0045’s linear light, with one practical consequence worth stating: exposure and
bloom_amount are upstream of the remap, so raising either pushes more of the
frame toward the ink pole. That is the lever for an ink preset whose drawing is
coming out too faint, and it is a better one than widening the two poles — see
the note below on why the poles do not do what they look like they do. It is
not the lever for “the ink should bite harder” — that one is ink_gamma, and
the three-lever note below says which does what.
| Param | Default | Meaning |
|---|---|---|
ink_amount | 0 | 0 = off (passthrough). 1 = full remap. Bindable — try "beat" to snap into ink on each hit. Read the note below before resting it between the two. |
paper_hue | 0 | Paper (dark-input) hue, into the HSV wheel; wraps, so it can sweep freely. |
paper_sat | 0 | Paper saturation. 0 = neutral. |
paper_bright | 1 | Paper brightness. 1 = white. |
ink_hue | 0 | Ink (bright-input) hue. |
ink_sat | 0 | Ink saturation. 0 = neutral. |
ink_bright | 0 | Ink brightness. 0 = black. |
ink_gamma | 1 | Response between the two poles — how fast a pixel travels from paper to ink. 1 is the identity. Above 1 thins the mid-tones toward paper, so only the strongest strokes keep full ink; below 1 inks the mids for a heavier, flatter print. Neither pole moves at any value. Bindable and continuous; clamped to 0.05 .. 20, both far outside anything a look wants. |
These poles are LINEAR LIGHT, and a
[palette]stop is not. A stop is sRGB and is decoded at load, so the hex you write is the colour that renders.paper_brightandink_brighttake no decode — they are the light itself, so a “dark” paper needs a far smaller number than the display value suggests:lsystem_vellummeasured0.07as a mid violet and settled on0.015for a true near-black. The same is true ofbg_bright. If a pole reads far brighter than the number you typed, this is why, and the fix is a smaller number rather than a different hue.
[params]ink_amount = "1" # black on white - nothing else needed
# ...or a colored duotone: indigo ink on cream paperpaper_hue = "0.11"paper_sat = "0.13"paper_bright = "0.97"ink_hue = "0.68"ink_sat = "0.85"ink_bright = "0.30"
# ...and hold the mids off the ink pole, leaving it to the strong strokes.# The paper stays exactly where it was - see the three-lever note below.ink_gamma = "2"A partial ink_amount is a transition, not a resting value. The stage
crossfades between the remapped frame and the untouched source, and the source
is a near-black frame — so at 0.5 the paper is half black. That reads as a dirty
page rather than a faint drawing, and the strokes lose contrast at the same time.
Bind ink_amount when you want to travel between the glowing and the drawn look
("beat", or an eased ramp via [smoothing], both of which pass through the
middle rather than sit in it); pick 0 or 1 when you want to stay somewhere. A
sparse, faint drawing comes from the scene — a finer size, a shorter fade —
not from a half-strength remap.
Three levers shape one response, and they are not interchangeable. An ink look that is “not contrasty enough” has three places to go, and picking the wrong one costs structure:
exposuremoves the level going in. It sits upstream of the remap, so raising it pushes more of the frame toward the ink pole — and it moves the paper with it, because a brighter base is no longer near zero. Reach for it when the drawing itself is too faint.ink_gammareshapes the response between the poles, and only that. The paper does not move: a black pixel lands on paper and a full-brightness one lands on ink at every value — that is the exponent’s defining property, not a tuning — so raising it leaves less of the frame inked without lifting the page or dimming the strokes. This is the lever for “the dark pole should bite harder”.ink_amountis how much remap happens at all, not how hard it bites. A partial value blends the remapped frame back toward the untouched source (see the note above), which greys the page. It is a transition, not a contrast control.
Measured on a 256-step grey ramp put through the remap with the default poles (white paper, black ink) — mean output byte over the ramp’s interior, higher = more paper:
ink_gamma | 0.25 | 0.5 | 1 | 2 | 4 |
|---|---|---|---|---|---|
| mean output byte | 147 | 180 | 209 | 229 | 241 |
Read the direction and size of the move, not the absolute: the ramp’s levels are sRGB bytes while the key is linear light, so a byte-50 % grey is already a low density and the identity row leans toward paper before anything is bound. The two ends of that ramp — pure black in, pure white in — came back as exactly the same two bytes at every one of those five exponents.
Which way you want to go depends on how dense the drawing already is, and
the identity row above is the reason. Rendered on attractor_ink (a sparse,
mid-density figure) at the same four values: 0.5 gives a heavier, sootier
mark; 2 drops the fine tracery and leaves the strong strokes; 4 thins the
whole figure to a ghost. So on a faint drawing, raising it separates the
strokes and costs weight — pair it with exposure, or go below 1 for a
heavier print — while on a drawing that is already crowding into a blot, raising
it is what buys the page back. The cream paper was pixel-identical in all four.
Like the rest of the ink_* family, ink_gamma crossfades across a cross-preset
dissolve rather than snapping.
Swapping the poles does not make a dark look on a continuous field. The pass
is mix(paper, ink, luminance) — it interpolates, it does not map. Setting a
dark paper against a bright ink is the obvious way to try to turn a print into a
glow, and it works only where most pixels already sit near 0 or near 1: a line
scene against black, not a continuous field. A source at mid luminance lands
halfway between the poles no matter how far apart you set them. Measured:
paper_bright = 0.055 against ink_bright = 0.94 on a developed Gray-Scott
field renders flat slate grey. To darken a continuous field, change what the
scene produces — exposure, contour density, the palette — not the poles.
In ink mode a scene’s palette collapses to the duotone. The remap keys on
luminance only, so the hue a [palette] produced is discarded and every pixel
lands somewhere on the paper→ink ramp. The palette still matters — it shapes which
parts of the frame are bright, and therefore which parts become ink — but the two
colours you actually see come from paper_*/ink_*. Reach for saturation and
the palette to sculpt contrast in an ink preset, not colour.
The HUD, the browse overlay, and the diagnostics overlay draw after this stage, so they are never inverted.
Built from a8ce055 at version 0.115.0. This site tracks main and is not versioned per release.