80 lines
2.7 KiB
Markdown
80 lines
2.7 KiB
Markdown
# MSAA (anti-aliasing)
|
|
|
|
MSAA (Multisample Anti-Aliasing) smooths the edges of meshes by sampling each pixel multiple
|
|
times **at rasterization time** (before the fragment shader).
|
|
|
|
## Enabling
|
|
|
|
```rust
|
|
use wsg_lib::prelude::*;
|
|
|
|
let app = AppBuilder::new()
|
|
.with_msaa(4) // 4x MSAA
|
|
.build()
|
|
.await?;
|
|
```
|
|
|
|
- **Without** `with_msaa`: the swapchain is used as-is (1x, no cost).
|
|
- **With** `with_msaa(4)`: the swapchain is created with `sample_count = 4`, and a
|
|
**resolve** pass (multisample → swapchain) runs at the end of each frame.
|
|
|
|
## Cost
|
|
|
|
- The **main pass** becomes more expensive (fragment shader run `sample_count` times per pixel
|
|
on aliased edges — in practice much less, since fully-covered pixels are only processed once).
|
|
- One extra **fullscreen resolve** per frame (GPU-native, very cheap).
|
|
- VRAM: the swapchain buffer is multiplied by `sample_count` (4x for 4x MSAA).
|
|
|
|
In practice: 4x MSAA is **negligible** on a discrete GPU and perfectly acceptable on an
|
|
integrated one for scenes of this complexity.
|
|
|
|
## MSAA + HDR
|
|
|
|
The two compose naturally:
|
|
|
|
```
|
|
Scene ──→ HDR multisample texture (sample_count = N)
|
|
│
|
|
▼ resolve
|
|
HDR texture (single sample)
|
|
│
|
|
▼ (bloom?)
|
|
▼ tone mapping
|
|
Swapchain (sRGB)
|
|
```
|
|
|
|
- `with_msaa(4)` + `with_hdr(…)`: the offscreen HDR texture becomes multisample and is
|
|
**resolved** before tone mapping (and before bloom, which operates on the single-sample
|
|
buffer).
|
|
- `with_msaa(4)` without HDR: the swapchain itself is multisample, resolved at the end of the
|
|
frame.
|
|
|
|
## MSAA + fog
|
|
|
|
Fog is applied **inside** the fragment shader (per sample), so it is inherently MSAA-compatible:
|
|
each sample computes its own fog factor based on its own depth. No aliasing on the fog
|
|
boundaries.
|
|
|
|
## What MSAA does NOT fix
|
|
|
|
- **Transparency aliasing** (there is no transparency in the engine — all opaque).
|
|
- **Texture shimmering** at distance: this is the domain of **anisotropic filtering** (already
|
|
enabled: `SampleFilter::AnisotropicClamped` + `anisotropy = 4`).
|
|
- **Temporal flicker** of fine details: this would be the domain of TAA (out of scope).
|
|
|
|
## Limitations
|
|
|
|
- `sample_count` is fixed **at swapchain creation** (not changeable at runtime without
|
|
recreating the window/surface).
|
|
- `2` and `4` are the useful values. `8` exists but the cost/quality ratio is bad.
|
|
- Not all adapters support MSAA on the swapchain — if unsupported, the builder falls back to
|
|
1x with a warning.
|
|
|
|
See `lib/examples/effects/msaa.rs` for a full interactive demo (torus + Icosphere, with
|
|
zoom/orbit, MSAA 4x by default).
|
|
|
|
## Links
|
|
|
|
- [User README](../README.md) · [HDR & tone mapping](hdr.md) · [Examples](../examples.md)
|
|
- [Root README](../../../README.md)
|