Specify a scene-referred pipeline (D19)
The spec missed Ansel, and with it Aurélien Pierre's argument that a display-referred curve early in the pipeline throws away what every later stage needs. Read against that argument, the code broke it four ways: the base curve was flat past its last point and so clipped every recovered highlight; the detail stage was handed curved, clipped values while its comments promised linear ones; the edits ran in camera RGB because the matrix had drifted to after them, against ARCH §5.2; and the tone curve clamped to [0, 1] around a 2.2 gamma mid-chain. D19 records the decision: unbounded scene-linear colour from the matrix to one view transform, last, after the detail stage. FR-DEV-3j specifies that view transform as an adjustable operation (contrast, white) with a default fitted to where the retired default curve put middle grey. FR-DEV-3e retires the per-body base curves, whose own file called them hand-tuned shapes of unknown provenance. FR-DEV-3f makes a film stock the view transform when one is chosen, instead of a rendering at order 25 that the later edits acted on. FR-DEV-2 gains the acceptance test that holds the rule, and ARCH gains §6.14 and the corrected §5.2 order.
This commit is contained in:
@@ -355,11 +355,12 @@ RawImage (sensor data, CPU)
|
||||
├─────────────────────┤
|
||||
│ AI denoise │ optional; raw-domain, joint with demosaic where possible
|
||||
├─────────────────────┤
|
||||
│ camera profile │ matrices + per-body base curve (FR-DEV-3e)
|
||||
│ white balance │ camera RGB: as-shot, then the operation
|
||||
├─────────────────────┤
|
||||
│ → working space │ linear, wide-gamut, f16
|
||||
│ camera profile │ the matrix (FR-DEV-3e) — no curve (D19)
|
||||
├─────────────────────┤
|
||||
│ → working space │ linear, unbounded, f16
|
||||
├─────────────────────┤
|
||||
│ white balance │
|
||||
│ exposure/contrast │
|
||||
│ highlights/shadows │ ← masks apply per-op from here down
|
||||
│ tone curve │
|
||||
@@ -368,10 +369,11 @@ RawImage (sensor data, CPU)
|
||||
│ spot removal │
|
||||
│ sharpen / NR │
|
||||
│ lens corrections │
|
||||
│ look (HaldCLUT) │ FR-DEV-3f
|
||||
├─────────────────────┤
|
||||
│ geometry │ crop, straighten, rotate
|
||||
├─────────────────────┤
|
||||
│ view transform │ sigmoid, or the film stock (FR-DEV-3j)
|
||||
├─────────────────────┤
|
||||
│ output transform │ → display or export profile
|
||||
└─────────────────────┘
|
||||
│
|
||||
@@ -381,6 +383,14 @@ RawImage (sensor data, CPU)
|
||||
|
||||
Working precision is f16 in a linear wide-gamut space, quantising once at the output transform.
|
||||
|
||||
**Scene-referred until the view transform (D19, §6.14).** Everything between the matrix and the
|
||||
view transform is linear and unbounded. The view transform is the one stage allowed to compress
|
||||
the scene into a display range. With a detail stage it runs as a dispatch of its own after the
|
||||
detail passes, generated by the same composer as the fused pass so that it gets the mask layers,
|
||||
the film tables and the grain's source position. Without one it is the fused pass's tail. Both
|
||||
the view transform and the output transform (primaries, gamut clip, encode) come after
|
||||
everything that reads a neighbourhood.
|
||||
|
||||
**A hot or dead photosite is repaired before the demosaic, not after.** Past it, one photosite of
|
||||
nonsense is a coloured cross three pixels wide that no later stage can tell from detail. The pass
|
||||
(`shaders/hot_pixels.wgsl`, run by `Demosaicer::run` into a second buffer) replaces a photosite that
|
||||
@@ -1255,6 +1265,17 @@ differently, f16 rounding varies. Cache keys and graph hashes are computed over
|
||||
state, which is exactly deterministic. Cross-platform *rendering* equality is a bounded tolerance
|
||||
(R1), not a checksum.
|
||||
|
||||
### 6.14 Scene-referred until the view transform
|
||||
|
||||
Added 2026-09-27 (D19). Between the camera matrix and the view transform, values are scene-linear
|
||||
and unbounded, and no operation clamps above 1.0, applies a transfer function or maps to a display
|
||||
gamut. The view transform (FR-DEV-3j) is the one stage that does, and the output transform after
|
||||
it clips and encodes. This is the constraint the base curve broke and ARCH §5.2 had drawn all
|
||||
along: a display-referred curve in the middle of the chain throws away what every later stage,
|
||||
the neighbourhood ones above all, needs. A test (`scene_referred_until_the_view`) runs every point
|
||||
operation over a ramp to 16.0 so that a fragment that clips fails the build rather than the
|
||||
photograph.
|
||||
|
||||
---
|
||||
|
||||
## 13. Decisions
|
||||
@@ -1278,6 +1299,7 @@ Full rationale in [requirements.md §8](requirements.md). Summary:
|
||||
| D13 | Face inference runtime and model licensing | **Runtime answered**, reopened for per-device backends (docs/inference.md); licensing open |
|
||||
| D14 | Segmentation source for local masking | Decided — arm C (docs/segmentation.md §14) |
|
||||
| D15 | Target devices — 12-inch tablet and desktop, no phone | Decided (requirements D15) |
|
||||
| D19 | Scene-referred pipeline, one view transform last | Decided (requirements D19) |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user