eng doc
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
# HDR & tone mapping
|
||||
|
||||
> **Step 20** — Opt-in HDR rendering with tone mapping.
|
||||
|
||||
## Principle
|
||||
|
||||
By default, WSG renders **directly to the swapchain** in 8-bit sRGB. This is fine for simple
|
||||
scenes, but the moment you want **bloom** or physically plausible intensities, you hit the
|
||||
ceiling: 8-bit clamps everything to [0,1] before any post-process can run.
|
||||
|
||||
When HDR is enabled, the scene is first rendered into an **offscreen float texture**
|
||||
(`Rgba16Float`, full window resolution), where values are unbounded (no clamping). The
|
||||
**tone mapping** pass then compresses the HDR signal into [0,1] sRGB for the swapchain.
|
||||
|
||||
```
|
||||
Without HDR (default) With HDR (.with_hdr(ToneMapper::Aces))
|
||||
───────────────────── ──────────────────────────────────────
|
||||
Scene ──────────→ Swapchain Scene ──→ HDR texture (Rgba16Float)
|
||||
(8-bit sRGB, clamped) │ (float, unbounded)
|
||||
▼
|
||||
Tone Mapping (ACES / Reinhard)
|
||||
│
|
||||
▼
|
||||
Swapchain (sRGB)
|
||||
```
|
||||
|
||||
## Enabling
|
||||
|
||||
```rust
|
||||
use wsg_lib::prelude::*;
|
||||
|
||||
let app = AppBuilder::new()
|
||||
.with_hdr(ToneMapper::Aces) // or ToneMapper::Reinhard
|
||||
.build()
|
||||
.await?;
|
||||
```
|
||||
|
||||
- **Without** `with_hdr`: the pipeline is untouched, **zero cost** (no extra texture, no
|
||||
extra pass).
|
||||
- **With** `with_hdr`: one extra full-res texture + one fullscreen pass per frame. Negligible
|
||||
cost on any discrete GPU; moderate on an integrated one (full-res read+write).
|
||||
|
||||
## Tone mappers
|
||||
|
||||
| Curve | Characteristics |
|
||||
|-------|----------------|
|
||||
| `Aces` | **Default.** Filmic look, good highlight roll-off, slightly desaturated in the shadows. The standard for games and engines. |
|
||||
| `Reinhard` | Simple `c / (1 + c)`. Neutral and fast, but highlights "washed out" (the curve saturates quickly). |
|
||||
|
||||
> The `demo` example starts in **LDR** (no HDR): the sphere's emissive intensity of 3.0 is
|
||||
> clamped to 1.0 — it looks "burnt" but no glow. Pressing a key enables HDR+ACES and the
|
||||
> highlight rolls off gracefully.
|
||||
|
||||
## Exposure
|
||||
|
||||
Runtime-adjustable since Step 22: initialize with `AppBuilder::with_exposure(…)`, adjust with
|
||||
`app.set_exposure(…)` (multiplicative, clamped to [0.01, 10.0] — only active when HDR is on).
|
||||
See [Emissive + Exposure](../lights/emissive-exposure.md).
|
||||
|
||||
## Interaction with other features
|
||||
|
||||
| Feature | Behavior under HDR |
|
||||
|---------|-------------------|
|
||||
| **Shadows** | Unchanged — the shadow pass still writes depth; the color pass just targets the HDR texture instead of the swapchain. |
|
||||
| **Fog** | Applied **before** tone mapping (inside the main pass). The fog color must be chosen in linear space, consistent with the tone curve. |
|
||||
| **MSAA** | Compatible — the HDR texture becomes the multisample render target and is resolved before tone mapping. |
|
||||
| **Bloom** | **Requires** HDR. Without it, bloom is ignored (warning). |
|
||||
|
||||
## Cost and non-regression
|
||||
|
||||
- No HDR (default): nothing is allocated, nothing is run. The swapchain is targeted directly.
|
||||
- HDR enabled: one extra `Rgba16Float` texture + one fullscreen pass (tone mapping). If bloom
|
||||
is also enabled, three more half-res textures and a few more passes (see the bloom page).
|
||||
- The `demo` example shows both paths side by side: the LDR start (emissive clamped) and the
|
||||
HDR+ACES mode (highlight roll-off).
|
||||
|
||||
## Limitations
|
||||
|
||||
- No **auto-exposure** (histogram-based). Exposure is fixed at build time (the demo hardcodes
|
||||
1.0).
|
||||
- No **DITHERING** on the output: banding may appear in smooth gradients near black (sRGB 8-bit
|
||||
ceiling).
|
||||
|
||||
## See also
|
||||
|
||||
- [Shadows](../lights/shadows.md)
|
||||
- [GPU-driven rendering](../cameras/gpu-driven.md)
|
||||
- [Examples](../examples.md)
|
||||
Reference in New Issue
Block a user