Luxar Viewer API Documentation - v2026.9.22
    Preparing search index...
    • Pick an exposure in three phases:

      1. 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.
      2. 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.
      3. 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.

      Parameters

      Returns Promise<AutoExposureResult>