Skip to content

fix(#18): HDRP sample washed out — Neutral tonemapping + physically derived exposure - #19

Merged
dfattal merged 1 commit into
mainfrom
fix/hdrp-sample-washed-out
Oct 2, 2026
Merged

dfattal merged 1 commit into
mainfrom
fix/hdrp-sample-washed-out

Conversation

@dfattal

@dfattal dfattal commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Fixes #18 — the HDRP sample's washed-out look. A same-build A/B (pre-fix vs DisplayXR/displayxr-unity#348 DLL) showed the 3D scene unchanged, so this is the sample's HDRP tuning. It is not a plugin or runtime colour bug (DisplayXR/displayxr-unity#347).

Changes (two one-line YAML edits)

Asset Component.field Before After
Assets/HDRPDefaultResources/DefaultSettingsVolumeProfile.asset Tonemapping.mode (override on) 2 = ACES 1 = Neutral
Assets/CubeTest/Sky and Fog Settings.asset (scene global volume, weight 1, priority 0) Exposure.fixedExposure (override on; mode stays 0 = Fixed) 12.696428 14.3

Nothing else was changed: no lighting rebalance, no colour-space change, and the R11G11B10 colour buffer is kept.

Why Neutral (not None)

ACES has a strong filmic curve that desaturates the bright end. On an over-exposed sunlit crate it flattens everything, which is the look we saw. Neutral is a gentle curve: it keeps hue and saturation through the midtones and still rolls off highlights. The direct sun is 100,000 lux, so the specular and sunlit highlights go well past 1.0. With None those would hard-clip to white, which is ugly. Fall back to None only if the panel check shows Neutral still looks flat.

Why Fixed 14.3 EV100 (not Automatic)

For a test sample, exposure should stay put. With Fixed, panel and atlas-capture A/Bs are reproducible pixel for pixel. Auto-exposure would breathe as the cube rotates, and it would meter on the large sky area. The value comes from the scene's own lights:

  • Sun: Directional Light, 100,000 lux (m_LightUnit: 2 = Lux), colour temp 6570 K. Rotation ≈ (50°, -30°), so the light direction is ≈ (-0.32, -0.77, 0.56).
    • Top face: 100k · 0.77 ≈ 77k lux, plus ~13k sky ≈ 90k lux
    • Camera-facing (-Z) face: 100k · 0.56 ≈ 56k lux, plus ~7k sky ≈ 63k lux
    • Representative lit-face illuminance: geometric mean ≈ 75k lux
  • Sky: PhysicallyBasedSky, default (Exposure intensity mode, exposure 0, multiplier 1). Its illuminance comes from the sun, roughly 10–20k lux on a horizontal surface.
  • HDRP maps EV100 to an exposure multiplier of 1 / (1.2 · 2^EV). An 18% grey Lambertian surface under E lux has luminance 0.18 · E / π. Setting that to 0.18 scene-linear (mid-grey):
    2^EV = E / (π · 1.2) = 75000 / 3.77 ≈ 19,900 → EV100 ≈ 14.28 → 14.3
    (The range across the two faces is 14.0–14.6. Sunny-16 at full sun+sky gives ≈ 15. The Main Camera's physical settings, ISO 200, 1/200 s, f/16, give 14.6.)
  • The old value of 12.7 is 1.6 stops over: mid-grey landed at ≈ 0.54 scene-linear before tonemapping, and ACES then compressed it.

Verification

  • Windows player builds (unity_build.bat, exit 0) with the normal pin #upm/v2.19.2. Both assets import cleanly.
  • Unity's incidental rewrites were reverted and are not in this PR: HDRenderPipelineGlobalSettings.asset (the build filled in m_RuntimeSettings.m_List) and XR/Settings/OpenXR Package Settings.asset (line endings only).
  • Panel check by eye — pending (David)
  • Atlas capture of the crate: compare with the pre-fix pixel (137,103,85) — pending

Do not merge until the panel check is done. If Neutral at 14.3 reads too dark or too flat, the knobs are fixedExposure (±0.5 EV steps) and Tonemapping.mode.

🤖 Generated with Claude Code

…erived exposure

The scene volume fixed exposure at 12.7 EV100 (~1.6 stops over for the
100,000 lux sun) and the default profile tonemapped with ACES, which
flattened and desaturated the over-exposed result.

- DefaultSettingsVolumeProfile: Tonemapping ACES (2) -> Neutral (1).
- Sky and Fog Settings: Exposure stays Fixed, 12.696428 -> 14.3 EV100,
  derived so an 18% grey surface on the crate's sunlit faces (~75k lux:
  sun 100k lux at ~50 deg elevation + sky) maps to 0.18 scene-linear:
  2^EV = E / (pi * 1.2) = 75000 / 3.77 -> EV100 = 14.28.

Nothing else changed (lighting, colour space, colour buffer untouched).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dfattal
dfattal marked this pull request as ready for review October 2, 2026 08:57
@dfattal
dfattal merged commit a5deeb2 into main Oct 2, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HDRP sample looks washed out: over-exposed fixed EV + ACES tonemapping (not a plugin colour bug)

1 participant