# BVLE Voxels - Prototype de Moteur Voxel Hybride

## Vue d'ensemble

Prototype de moteur voxel basé sur **Wicked Engine** (MIT, C++17, DX12/Vulkan) pour valider les performances de rendu sur GPU moderne (AMD RDNA 2+ / Nvidia RTX 3060+). Le document de spécification complet est dans `voxel_engine_spec.md` à la racine du projet.

Cible : 60+ fps en 1440p, monde de 512x512x256 voxels visibles.

## Architecture

```
bvle-voxels/
├── CMakeLists.txt              # Build CMake racine
├── engine/                     # Wicked Engine (clone --depth 1, branche main)
│   └── WickedEngine/shaders/voxel/  # Nos shaders copiés ici pour compilation DXC
├── src/
│   ├── voxel/                  # Bibliothèque VoxelEngine (static lib)
│   │   ├── VoxelTypes.h        # Types fondamentaux (VoxelData, PackedQuad, MaterialDesc, ChunkPos)
│   │   ├── VoxelWorld.h/.cpp   # Monde voxel (hashmap de chunks, génération procédurale)
│   │   ├── VoxelMesher.h/.cpp  # Binary Greedy Mesher CPU + SmoothMesher (Naive Surface Nets)
│   │   ├── VoxelRenderer.h/.cpp# Renderer + VoxelRenderPath (sous-classe RenderPath3D)
│   │   └── TopingSystem.h/.cpp # Système de topings (biseaux décoratifs sur faces +Y)
│   └── app/
│       └── main.cpp            # Point d'entrée Win32 + crash handler SEH
├── shaders/                    # Sources HLSL des shaders voxel (copiés dans engine/ au build)
│   ├── voxelCommon.hlsli       # Root signature et CB partagés (inclus par tous les shaders)
│   ├── voxelVS.hlsl            # Vertex shader (vertex pulling, triple-mode: CPU/MDI/GPU mesh)
│   ├── voxelPS.hlsl            # Pixel shader (triplanar + lighting)
│   ├── voxelCullCS.hlsl        # Compute shader frustum+backface cull (Phase 2.3)
│   ├── voxelMeshCS.hlsl        # Compute shader GPU mesher 1×1 (Phase 2.4-2.5)
│   ├── voxelTopingVS.hlsl      # Vertex shader topings (instanced vertex pulling, t4/t5)
│   ├── voxelTopingPS.hlsl      # Pixel shader topings (triplanar + directional lighting)
│   ├── voxelSmoothVS.hlsl      # Vertex shader smooth Surface Nets (vertex pulling, t6)
│   ├── voxelSmoothPS.hlsl      # Pixel shader smooth (triplanar + material blending)
│   ├── voxelBLASExtractCS.hlsl # Compute shader BLAS position extraction (Phase 6.1)
│   ├── voxelShadowCS.hlsl     # Compute shader RT shadows + raw AO (inline ray queries, Phase 6.2+6.3)
│   ├── voxelAOBlurCS.hlsl     # Compute shader bilateral AO blur (separable H/V, Phase 6.3)
│   └── voxelAOApplyCS.hlsl    # Compute shader AO apply + tone mapping + saturation (Phase 6.3 + 7)
├── CLAUDE.md
└── TROUBLESHOOTING.md          # Pièges techniques, debugging, APIs Wicked
```

## Build

### Prérequis

- CMake 3.19+ (`winget install Kitware.CMake`)
- Visual Studio 2022 Build Tools (`winget install Microsoft.VisualStudio.2022.BuildTools`)
- Windows SDK 10.0.26100+ (`winget install Microsoft.WindowsSDK.10.0.26100`)

### Commandes

```bash
# Configurer (depuis la racine du projet)
cmake -B build -G "Visual Studio 17 2022" -A x64 -DCMAKE_SYSTEM_VERSION=10.0.26100.0

# Compiler
cmake --build build --config Release --target BVLEVoxels --parallel

# Exécutable produit dans build/Release/BVLEVoxels.exe
```

Le SDK 10.0.26100 est requis car les headers DX12 (`d3dx12_check_feature_support.h`) fournis par Wicked Engine ne sont pas compatibles avec le SDK 22621.

### Post-build automatique (CMakeLists.txt)

Le build copie automatiquement :
1. `dxcompiler.dll` → à côté de l'exe (requis pour la compilation runtime des shaders)
2. `shaders/*.hlsl` → `engine/WickedEngine/shaders/voxel/` (pour que `LoadShader` les trouve via `SHADERSOURCEPATH`)
3. `engine/Content/` → à côté de l'exe (assets Wicked Engine)

## Intégration Wicked Engine

### Backend graphique

Wicked Engine utilise **DX12 par défaut sur Windows**, Vulkan sur Linux. Les shaders sont écrits en **HLSL** et compilés via DXC. Pour forcer Vulkan sur Windows, passer `"vulkan"` en argument de ligne de commande.

### Point d'entrée et architecture de rendu

`VoxelRenderPath` hérite de `wi::RenderPath3D`. Le rendu voxel utilise ses propres render targets (`voxelRT_`, `voxelDepth_`) et est exécuté dans `Render()` sur un **command list dédié**. Le résultat est composité dans `Compose()` via `wi::image::Draw()`.

**NE JAMAIS créer un render pass dans `Compose()`** : cette méthode est appelée à l'intérieur du render pass du swapchain. Imbriquer des render passes est interdit en D3D12.

```
Render()  → RenderPath3D::Render()     // Wicked rend sa scène
          → device->BeginCommandList() // Nouveau cmd list
          → renderer.render(cmd, ...)  // Notre render pass (clear + draw voxels → voxelRT_)
Compose() → RenderPath3D::Compose()    // Wicked affiche son résultat
          → wi::image::Draw(voxelRT_)  // On overlay nos voxels par-dessus
```

La caméra est gérée manuellement dans `Update()` en écrivant directement `camera->Eye`, `camera->At` (direction LookTo), `camera->Up`.

> See `TROUBLESHOOTING.md` for the detailed Wicked API reference table, shader binding pitfalls, DX12 resource state management, and debugging guides.

## Détails d'implémentation

### VoxelData (16 bits)

```
[15:8] material ID (256 matériaux)
[7:4]  flags (smooth, transparent, emissive, custom)
[3:0]  metadata (orientation, variant)
```

### PackedQuad (64 bits = 8 octets par quad)

```
[5:0]   position X (0-63)       [23:18] width (1-32)
[11:6]  position Y (0-63)       [29:24] height (1-32)
[17:12] position Z (0-63)       [32:30] face (0-5)
[40:33] material ID              [48:41] blendMatID
[59:49] chunkIndex (11 bits)     [63:60] blendEdges (4 bits)
```

### Binary Greedy Mesher (CPU, `VoxelMesher.cpp`)

Masques binaires par axe, face culling par shift/XOR, greedy merge rectangulaire par tranche de profondeur.

### Génération procédurale (`VoxelWorld.cpp`)

Perlin noise 3D, fBm 5 octaves (2 en animation), caves 3D, matériaux par altitude. Chunks Y=0..7. Animation 60 Hz via `regenerateAnimated()` parallélisé avec `wi::jobsystem`.

### Renderer (`VoxelRenderer.cpp`)

- **Triple-mode VS** : CPU path, MDI path, GPU mesh path (défaut)
- **GPU mesh** : compute shader `voxelMeshCS` → barrier UAV→SRV → `DrawInstanced` (readback 1-frame-delay)
- **Vertex pulling** via `SV_VertexID`, pas de vertex buffer classique
- **Per-chunk info** : `StructuredBuffer<GPUChunkInfo>` (80 bytes/chunk)
- **Height-based blending** (Phase 3) : PS lit `voxelDataBuffer` (t3), winner-takes-all heightmap, corner attenuation
- **Render targets propres** : `voxelRT_` (R8G8B8A8) + `voxelDepth_` (D32_FLOAT)
- **CPU profiling** : `ProfileAccum` avec moyennes toutes les 5s

## Phases de développement

### Phase 1 - Setup et meshing de base [FAIT]

Fork Wicked Engine, VoxelWorld procédural, Binary Greedy Mesher CPU (~300K quads), rendu vertex pulling, caméra libre, crash handler SEH.

### Phase 2 - Performance GPU [FAIT]

- **2.1** : Mega-buffer + CPU frustum/backface cull + per-face DrawInstanced
- **2.2** : CPU-filled indirect args + DrawInstancedIndirectCount (MDI)
- **2.3** : GPU compute culling (0.006 ms / 168 chunks)
- **2.4** : GPU compute mesher benchmark (CPU 277ms vs GPU 5.3ms)
- **2.5** : GPU meshing production + CPU optimisations (fused regen+pack, memcpy, dirty cache)
- **Résultat** : 80-110 FPS avec animation 60 Hz, 700+ FPS statique

### Phase 3 - Texture blending [FAIT]

PS-based heightmap blending, winner-takes-all, corner attenuation subtractive. GPU mesh path uniquement.

### Phase 4 - Toping [EN COURS]

- **4.1** [FAIT] : TopingSystem infrastructure, 4-bit adjacency, priority-based, stone wedges + grass tufts
- **4.2** [FAIT] : Shaders dédiés, vertex pulling instancié, half-Lambert + translucency vegetation
- **4.3** [A FAIRE] : Plus de types, LOD, animation vent, compute shader instances

### Phase 5 - Rendu smooth [EN COURS]

- **5.1** [FAIT] : Naive Surface Nets CPU, SDF binaire, cross-chunk connectivity, smooth/blocky boundary
- **5.2** [FAIT] : Smooth vertex normals, geometric normals triplanar, optimisations CPU (560ms → 17ms)
- **5.3** [A FAIRE] : GPU compute Surface Nets
- **5.4** [A FAIRE] : SDF lissé, LOD, pipeline asynchrone

### Phase 6 - Ray tracing hybride [EN COURS]

- **6.1** [FAIT] : Normal RT (MRT), BLAS extraction CS, 3 BLAS (blocky+smooth+topings), TLAS
- **6.2** [FAIT] : RT shadows (3 jittered rays, TMin adaptatif, colored shadows)
- **6.3** [FAIT] : RT AO (4 cosine-weighted rays, IGN + Cranley-Patterson, temporal accumulation, bilateral blur)
- **6.4** [A FAIRE] : Fallback shadow maps + SSAO

### Phase 7 - Stylized Lighting [EN COURS]

- **7.1** [FAIT] : Hemisphere ambient, colored shadows, rim light, tone mapping + saturation, screenshot mode

## Métriques cibles et résultats

| Métrique | Cible | Résultat (Ryzen 7 9800X3D + RX 9070 XT) |
|----------|-------|---------------------------------------|
| FPS 1440p | > 60 fps | 80-110 FPS (anim blocky), 700+ FPS (statique) |
| FPS anim smooth+topings | > 15 fps | 17 FPS (smooth+topings+blocky anim 60Hz) |
| Meshing GPU (blocky) | < 200 us/chunk | ~0.6 us/chunk (0.1ms / 171 chunks) |
| Meshing CPU (smooth) | < 30ms | 17ms (parallele, 648 chunks) |
| Memoire GPU | < 500 Mo | ~30 Mo |
| Draw calls | < 100 | 1 (GPU mesh) ou 1 (MDI) |

## Conventions

- Namespaces : tout le code voxel est dans `namespace voxel`
- Chunks : 32x32x32, configurable via `CHUNK_SIZE`
- Coordonnées : Y = haut, monde infini en X/Z, hashmap sparse
- Matériaux : palette de 256, index 0 = air (vide), 1=grass, 2=dirt, 3=stone (blocky), 4=sand, 5=snow (smooth), 6=smoothstone (smooth)
- Faces : 0=+X, 1=-X, 2=+Y, 3=-Y, 4=+Z, 5=-Z
- Smooth flag : `FLAG_SMOOTH = 0x1` dans VoxelData flags — active Surface Nets au lieu du rendu blocky
