Make the view transform an operation the photographer can set

FR-DEV-3j gives the view transform two controls, contrast and the white
point in stops above middle grey, persisted and held per mask layer like
any other setting. A scene-referred pipeline whose white point cannot be
moved hands the photographer a shoulder they cannot place.

`view_transform` is a hand-written node in `Stage::View`, a new stage
the composer emits last and emits whatever the node's state: a neutral
operation is otherwise left out of the shader, but a photograph with no
view transform is a scan. "Active" keeps meaning "moved from the
defaults", so an untouched photograph writes nothing for it and
`every_node_starts_neutral` still holds. A caller whose chain holds no
view operation gets a default one.

The composer's loop becomes an ordered list of steps — camera nodes, the
matrix, scene nodes, layer-only nodes, the view — so each is emitted in
exactly one place. The base curve could not be a node because it
belonged to the camera; the ops README records why that argument went
with it (D19). The panel shows it in the Light group as "Tone Mapping".

Tests that counted the blocks of a neutral graph now count one, the
view transform, and the two chain-wide tests that load a film expect the
view transform to be absent, since a stock replaces it.
This commit is contained in:
2026-09-27 16:52:54 -04:00
parent 37a6d99dc4
commit 92afaebd34
11 changed files with 386 additions and 99 deletions
+3 -1
View File
@@ -32,7 +32,8 @@
//! # What is not covered, and why that is honest
//!
//! A `rust:` node — `tone_curve`, `colour_mixer`, `film_sim`,
//! `capture_sharpen`, `noise_reduction`, `clarity`, `texture`, `dehaze` —
//! `capture_sharpen`, `noise_reduction`, `clarity`, `texture`, `dehaze`,
//! `view_transform` —
//! names a hand-written type and has no declaration to interpret. It is not skipped
//! silently: [`every_declared_node_is_checked`] asserts the two sets partition
//! `ops/` between them, so a node that stops being declared cannot quietly
@@ -403,6 +404,7 @@ fn every_declared_node_is_checked() {
"noise_reduction",
"texture",
"tone_curve",
"view_transform",
"vignetting",
],
"the set of hand-written nodes changed; if that is deliberate, update \