refactor examples

This commit is contained in:
Jérôme Bousquié
2026-09-25 10:19:24 +02:00
parent ab3f056dbb
commit 35aeb769a8
37 changed files with 3430 additions and 457 deletions
+107
View File
@@ -0,0 +1,107 @@
# Émissive + Exposure
## Principe
Deux features complémentaires (Étape 22) :
| Feature | Effet | Coût |
|---------|-------|------|
| **Exposure** (6.1) | Multiplie la luminance avant la courbe de tone mapping | Zéro si HDR inactif |
| **Emissive** (6.2) | Ajoute une couleur émise (indépendante des lumières) | Zéro si `emissive = [0,0,0,0]` |
## Exposure
### API
```rust
// Initialisation (optionnel, default = 1.0)
let app = AppBuilder::new()
.with_hdr(ToneMapper::Aces)
.with_exposure(1.5) // démarre plus clair
.build().await?;
// Runtime (dans update())
app.set_exposure(app.exposure() * 1.1); // +1 "stop"
app.set_exposure(1.0); // reset
```
### Comportement
- L'exposure est un **multiplicateur** appliqué à la texture HDR avant la courbe de tone mapping.
- `exposure = 2.0` → l'image est 2× plus claire (comme ouvrir le diaphragme d'un photo).
- `exposure = 0.5` → l'image est 2× plus sombre.
- Clampé à `[0.01, 10.0]` pour éviter les valeurs dégénérées.
- **N'a d'effet que si HDR est actif** (`with_hdr(...)`). En LDR, la valeur est ignorée.
### Clavier (demo)
| Touche | Effet |
|--------|-------|
| `+` | ×1.1 (plus clair) |
| `-` | ÷1.1 (plus sombre) |
| `0` | Reset à 1.0 |
## Emissive
### API
```rust
use wsg_lib::resources::Material;
// Créer un matériau avec émissivité
let mut mat = /* ... */;
mat.emissive = [1.0, 0.3, 0.1, 1.5]; // orange, intensité 1.5 (> 1.0 = glow HDR)
```
### Format
`emissive = [r, g, b, intensity]` :
- **rgb** : la couleur de l'émission (même espace que la couleur base du vertex)
- **a (intensity)** : le multiplicateur. `1.0` = couleur normale, `> 1.0` = surbrillance (ne se voit qu'en HDR)
### Formule shader
```
final_color = lit + base_color * emissive.rgb * emissive.a
```
- L'émission est **additive** : visible même dans le noir total (pas de lumière nécessaire).
- Elle est **indépendante des ombres** : un objet émissif ne projette pas d'ombre et n'est pas ombragé.
- `emissive = [0,0,0,0]` (default) → aucun changement (non-régression garantie).
### Cas d'usage
| Usage | Valeur |
|-------|--------|
| LED / indicateur | `[0, 1, 0, 1.0]` (vert, intensité normale) |
| Flamme / soleil | `[1, 0.8, 0.2, 3.0]` (orange, glow HDR) |
| Neon | `[0, 0.5, 1, 2.5]` (cyan, glow) |
| Inactif | `[0, 0, 0, 0]` (default) |
### Clavier (demo)
| Touche | Effet |
|--------|-------|
| `E` | Toggle glow orange sur la sphère/cylindre |
## Interactions
| Combination | Résultat |
|-------------|----------|
| Emissive + HDR + ACES | Glow doux, highlights roll off (le plus joli) |
| Emissive + LDR | Clamped à 1.0 (pas de glow, mais couleur visible dans le noir) |
| Emissive + shadows | L'objet émissif n'est PAS ombragé (l'émission bypass le shadow term) |
| Exposure + Emissive | L'exposure amplifie aussi l'émission (cohérent : tout est dans la texture HDR) |
## Non-régression
- **Emissive** : `[0,0,0,0]` par défaut → le shader additionne `base * 0 * 0 = 0` → aucun changement.
- **Exposure** : `1.0` par défaut → `pow(color, 1/1) = color` → aucun changement.
- Les deux sont **opt-in** : sans `with_hdr(...)` ni `emissive != 0`, le pipeline est identique à l'état précédent.
## Limitations (MVP)
- L'emissive est **par matériau**, pas par vertex (pas de gradient d'émission dans un mesh).
- L'emissive est **statique** à la création du matériau (changer `mat.emissive` requiert de re-registrer le matériau via `add_material`).
- Pas de **bloom** (Étape 23) : le glow HDR est visible mais pas "flou" / diffusé.