Describe the film's tables as 0.18.2 bakes them

dr-film's README still described one 32³ lookup that took a negative
through the print and the paper, with the sliders' values baked into
it. Since 6b99f67 nothing a slider moves is baked: the curves are one
row per development time the datasheet measures and push interpolates
between them, a print is two lookups split at the paper's log exposure
with the enlarger's exposure added between them, and exposure, push,
print exposure and format reach the shader as uniforms. That is what
lets a mask layer hold film settings of its own.

The section now says so, and that the film's Exposure on the whole
photograph is the one setting that rebakes, because the enlarger's
filtration is solved against it.
This commit is contained in:
2026-09-27 07:59:38 -04:00
parent 7558053932
commit 1fdfb5990c
+22 -6
View File
@@ -41,18 +41,34 @@ matters — see [`src/bake.rs`](src/bake.rs) for the argument:
1. **A 3×3 matrix**, linear sRGB to the three layers' exposure. Exact, not an 1. **A 3×3 matrix**, linear sRGB to the three layers' exposure. Exact, not an
approximation: the reconstructed scene spectrum is linear in the sRGB approximation: the reconstructed scene spectrum is linear in the sRGB
triple, so the integral collapses into nine numbers. triple, so the integral collapses into nine numbers.
2. **Three 1D curves**, log exposure to density, sampled at 256 points. 2. **Three 1D curves**, log exposure to density, sampled at 256 points — one
3. **One 32³ lookup**, density to linear sRGB — dye absorption, the print row per development time the datasheet measures. Push picks between the
through the negative, the paper, the viewing illuminant and the chromatic rows, and interpolating them is exact, because density is linear in push
adaptation, all of which take exactly three numbers in. between two measured processes.
3. **One 32³ lookup**, density to linear sRGB — dye absorption, the viewing
illuminant and the chromatic adaptation, all of which take exactly three
numbers in. A printed negative is two: the film's cube ends at the paper's
log exposure through the negative, the enlarger's exposure is added there,
and the paper's own curve row and cube take it to linear sRGB.
Per pixel that is a matrix multiply, three curve taps and one texture fetch. Per pixel that is a matrix multiply, a handful of curve taps and one texture
Splitting 2 from 3, rather than baking one LUT over exposure, is measured fetch — two for a print. Splitting 2 from 3, rather than baking one LUT over exposure, is measured
rather than assumed: the curve carries all the sharp shape and the dye mixing rather than assumed: the curve carries all the sharp shape and the dye mixing
is smooth, so folding the curve into the 3D lookup would need it three times is smooth, so folding the curve into the 3D lookup would need it three times
larger for the same error. At 32³ the worst interpolation error is about 0.003 larger for the same error. At 32³ the worst interpolation error is about 0.003
in linear sRGB, below one 8-bit code value, and there is a test that says so. in linear sRGB, below one 8-bit code value, and there is a test that says so.
**No slider is baked.** Camera exposure is a gain before the matrix, push
chooses between curve rows, print exposure is the addition between the two
cubes, and format sets the grain; each reaches the shader as a uniform that is
linear in what it does. That is what lets a mask layer hold its own film
settings, and a pixel under several layers take the weighted average of them.
Only the enlarger's filtration is solved at bake time, against the
photograph's exposure — an enlarger has one filtration for the whole print —
so the film's Exposure, set on the whole photograph, is the one slider that
rebakes. The stock and its
paper are the photograph's; a layer has no picker.
## Adding a stock ## Adding a stock
If spektrafilm has it, add its name to `STOCKS` in If spektrafilm has it, add its name to `STOCKS` in