dof
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
# Brouillard de distance (Fog)
|
||||
|
||||
## Principe
|
||||
|
||||
Le brouillard de distance fond les objets vers une couleur prédéfinie en fonction
|
||||
de leur distance à la caméra. C'est l'outil standard pour :
|
||||
|
||||
- **Masquer le bord du monde rendu** — illusion d'un monde infini (Skyrim, GTA, Minecraft)
|
||||
- **Donner de la profondeur** — effet atmosphérique naturel
|
||||
- **Camoufler les transitions** — chargement de tuiles, LOD pops
|
||||
|
||||
## Activation
|
||||
|
||||
```rust
|
||||
use wsg_lib::prelude::*;
|
||||
|
||||
let app = AppBuilder::new()
|
||||
.with_fog(FogConfig::exponential2([0.7, 0.75, 0.85], 0.06))
|
||||
.build()
|
||||
.await?;
|
||||
```
|
||||
|
||||
Sans `.with_fog()`, le brouillard est désactivé — **zéro coût GPU** (la branche
|
||||
shader est jamais prise).
|
||||
|
||||
## Modes
|
||||
|
||||
| Mode | Formule | Usage |
|
||||
|------|---------|-------|
|
||||
| `Linear` | `saturate((far - d) / (far - near))` | Cutoff net entre deux distances |
|
||||
| `Exponential` | `exp(-density × d)` | Brouillard naturel (forêt, lac) |
|
||||
| `Exponential2` | `exp(-density² × d²)` | Départ progressif, cutoff net — **idéal pour masquer** |
|
||||
|
||||
### Constructeurs
|
||||
|
||||
```rust
|
||||
// Linéaire : fondu entre near et far
|
||||
FogConfig::linear([0.7, 0.8, 0.9], 5.0, 50.0)
|
||||
|
||||
// Exponentiel : fondu naturel
|
||||
FogConfig::exponential([0.6, 0.7, 0.8], 0.03)
|
||||
|
||||
// Exponentiel² : masquage de bord de monde
|
||||
FogConfig::exponential2([0.7, 0.75, 0.85], 0.08)
|
||||
```
|
||||
|
||||
## Paramètres
|
||||
|
||||
| Champ | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `mode` | `FogMode` | Linéaire / Exponentiel / Exponential2 |
|
||||
| `color` | `[f32; 3]` | Couleur du brouillard (RGB, espace linéaire) |
|
||||
| `near` | `f32` | Distance début (mode linéaire uniquement) |
|
||||
| `far` | `f32` | Distance fin, brouillard complet (mode linéaire) |
|
||||
| `density` | `f32` | Densité (modes exp / exp²). Typique : 0.01–0.3 |
|
||||
|
||||
### Choisir la couleur
|
||||
|
||||
La couleur du brouillard **doit correspondre à la couleur du ciel/clear color**
|
||||
pour un effet "monde infini" seamless. Avec HDR + ACES, utiliser des valeurs
|
||||
linéaires cohérentes avec le tone mapping.
|
||||
|
||||
### Choisir la densité (exp²)
|
||||
|
||||
Pour masquer le bord du monde à une distance `D` :
|
||||
|
||||
```
|
||||
density ≈ 2.0 / D
|
||||
```
|
||||
|
||||
Exemples :
|
||||
- Monde visible jusqu'à 25 unités → `density = 0.08`
|
||||
- Monde visible jusqu'à 50 unités → `density = 0.04`
|
||||
- Monde visible jusqu'à 100 unités → `density = 0.02`
|
||||
|
||||
## Changement à l'exécution
|
||||
|
||||
```rust
|
||||
// Dans update() :
|
||||
if key_pressed(KeyCode::Digit1) {
|
||||
app.renderer_mut().set_fog(Some(FogConfig::linear([0.7, 0.8, 0.9], 5.0, 30.0)));
|
||||
}
|
||||
if key_pressed(KeyCode::Digit4) {
|
||||
app.renderer_mut().set_fog(None); // désactiver
|
||||
}
|
||||
```
|
||||
|
||||
Le changement prend effet au frame suivant.
|
||||
|
||||
## Pipeline
|
||||
|
||||
```text
|
||||
Main pass (shader fragment)
|
||||
↓
|
||||
Lighting → final_rgb
|
||||
↓
|
||||
FOG: mix(final_rgb, fog_color, 1 - fog_factor) ← ici
|
||||
↓
|
||||
→ HDR texture / swapchain
|
||||
↓
|
||||
(Bloom) → Tone Mapping → surface
|
||||
```
|
||||
|
||||
Le brouillard s'applique **avant** le tone mapping : les valeurs HDR restent
|
||||
non clampées, et le TM applique la courbe ACES/Reinhard au résultat déjà
|
||||
brouillé. Résultat : le brouillard est perceptuellement cohérent.
|
||||
|
||||
## Compatibilité
|
||||
|
||||
| Avec | OK ? | Note |
|
||||
|------|------|------|
|
||||
| HDR + TM | ✅ | Fog avant TM (recommandé) |
|
||||
| Bloom | ✅ | Le bloom extrait les zones brillantes du résultat post-fog |
|
||||
| MSAA | ✅ | Indépendant (rasterizer vs fragment shader) |
|
||||
| Culling GPU | ✅ | Indépendant (culling décide quoi dessiner, fog décide la couleur) |
|
||||
| Shadows | ✅ | L'ombre est calculée avant le fog |
|
||||
|
||||
## Limitations (v1)
|
||||
|
||||
- **Scene-level uniquement** : un seul brouillard pour toute la scène.
|
||||
Un brouillard par matériau nécessiterait un paramètre additionnel dans le
|
||||
bind group par objet.
|
||||
- **Distance euclidienne** : pas de brouillard volumétrique ni directionnel.
|
||||
- **Couleur fixe** : pas de gradient de couleur avec la distance.
|
||||
|
||||
## Exemple
|
||||
|
||||
Voir `examples/fog.rs` : 15 cubes en rangée + 5 sphères sur un plan 80×80,
|
||||
avec commutation runtime entre les 3 modes.
|
||||
|
||||
```sh
|
||||
cargo run -p wsg-lib --example fog --features "all-prims"
|
||||
```
|
||||
Reference in New Issue
Block a user