Percentile pass — converge so the lit foreground's high percentile hits
TARGET_HI (bright but not clipped). Exposure is ~log-linear in
luminance, so a few log2 corrections converge.
Flat-subject pass — if the lit histogram's spread (p99 − p10) is under
NARROW_SPREAD_MAX the subject has essentially no internal dynamic range
(a flat shaded surface), so p99 is a meaningless anchor: re-target
the MEDIAN to TARGET_MID instead. The spread is evaluated AFTER phase 1,
i.e. at the exposure where p99 ≈ 0.9 for every subject, which is what
makes one absolute threshold comparable across geometries. It is an
EMPIRICAL gate, not a proof — see NARROW_SPREAD_MAX for the measured
margins on both sides and the false-fire risk. flatSubject in the
result records whether it fired.
Guard — step exposure DOWN while EITHER >5% of the subject is blown to
white OR the background is lifted to grey (frame p10 above near-black).
Phase 1 (p99 target) over-boosts sparse/bloomy scenes into a grey wash;
the background term is what pulls those back to a black background. The
predicate or EXPOSURE_MIN terminates the guard; guardExhausted reports
a frame that still violates either guard condition at the floor. For a
screen-filling subject, whole-frame p10 can be subject luminance rather
than background, so this term may remain unsatisfied; use the per-demo
exposure override for that case.
NOTE (preserved quirk): when a pass's correction is already negligible it
records the corrected value and breaks WITHOUT applying it, so the returned
stops can differ from the applied exposure by up to the pass's tolerance, and
the next phase's first measurement is taken at the old applied exposure.
Deliberate — "fixing" it would shift every existing tile.
Pick an exposure in three phases:
flatSubjectin the result records whether it fired.guardExhaustedreports a frame that still violates either guard condition at the floor. For a screen-filling subject, whole-frame p10 can be subject luminance rather than background, so this term may remain unsatisfied; use the per-demoexposureoverride for that case.NOTE (preserved quirk): when a pass's correction is already negligible it records the corrected value and breaks WITHOUT applying it, so the returned stops can differ from the applied exposure by up to the pass's tolerance, and the next phase's first measurement is taken at the old applied exposure. Deliberate — "fixing" it would shift every existing tile.