--- type: Roadmap title: WSG Engine Development Roadmap description: Development roadmap for the WSG engine from prototype to full-featured 3D rendering engine tags: [roadmap, development, planning, wsg-lib, 3d-rendering] status: stable generated: { by: human:jerome, at: 2026-07-31T00:00:00Z } --- # Roadmap WSG — Prototype → Moteur Complet > Basé sur l'architecture existante (ARCHI_APP, ARCHI_ARENES, ARCHI_CPU_GPU, ARCHI_RENDU). > Objectif : prototype fonctionnel d'abord, enrichissement progressif ensuite. > > **Point de départ (état réel au 2026-09-16 — la source de vérité est README.md).** > Les fondations suivantes existent et fonctionnent déjà ; cette roadmap décrit la **trajectoire à > venir** à partir de cet état (elle reprend les étapes 1-4 du README avant la montée GPU-driven) : > - Workflow manuel (`Context` + `Renderer` + `PipelineCache`) : ✅ fonctionnel (exemple `manual`). > - Façade `App` / `AppBuilder` / `AppHandler` : ✅ **Scene auto-render** (2026-09-16) — la vue de frame > est exposée (`Frame::view()`), `render()` dessine la scène en une passe groupée > (`App::render_scene`) et la présentation est automatique dans `App::run` (exemple `simple`). > - `Scene` avec identifiants **String** (décision prise — voir tableau Notes de Décision) : 🚧 enregistrement seul. > - `Camera` / `Transform` et `glam` : types et mathématiques présents (`math/`, `resources/camera.rs`), > initialement non branchés au pipeline — **désormais branchés** (caméra active + matrices monde écrites > chaque frame, Étape 4.3, 2026-09-16 ; voir §1.1/1.5 ci-dessous). > **Étape suivante (résolue 2026-09-17).** « 3D + éclairage Phong » (ROADMAP 1.3 + 1.5) est **atteinte** : > le rendu automatique n'est plus plat. L'infrastructure (Étapes 3+4, 2026-09-16) — `standard_shader.wgsl` > Phong (matrice `projection * view * world` + lumière directionnelle), uniform buffers branchés > (frame : view/proj/cam_pos + lumière ; par mesh : `world` dérivé du `Transform`), `Renderer` écrivant > chaque frame la caméra active et la matrice monde de chaque entité — est **branchée** sur l'exemple > `cube` (Étape 5, 2026-09-17) : un cube unitaire éclairé qui tourne à l'écran via `App::render_scene`. > Le shader `basic` est supprimé : le 2D plat devient la variante **unlit** de `standard` > (`Renderer::set_unlit(true)`). Objectif MVP **atteint**. --- ## Phase 1️⃣ — Prototype MVP : Un Mesh 3D éclairé à l'écran **Objectif** : Afficher un cube (ou autre mesh) 3D avec un éclairage Phong basique. ### 1.1 Dépendances & Mathématiques - [x] `glam = "0.33"` ajouté (`lib/Cargo.toml`) — déjà présent, utilisé par `math/transform.rs` et `resources/camera.rs` - [x] `slotmap` **retiré** — décision prise : **String IDs pour le MVP** ; slotmap reporté à l'étape "handles typés" (voir Notes de Décision) - [x] Module `math/` / `transform.rs`: - [x] Struct `Transform { translation: Vec3, rotation: Quat, scale: Vec3 }` - [x] Méthode `to_matrix() -> Mat4` pour calculer la matrice locale - [x] Struct `Camera { position: Vec3, target: Vec3, up: Vec3 }` : resources/camera.rs — enrichi en Étape 4.3 (fov/near/far + `with_perspective`) - [x] Fonctions `view_matrix()` et `projection_matrix(fov, aspect, near, far)` (Étape 4.3 : `projection_matrix(aspect)` utilise fov/near/far stockés) ### 1.2 Geometry & Mesh - [x] Créer struct `Geometry` (math/geometry.rs) — **fait** : - [x] `positions: Vec<[f32; 3]>` (obligatoire) - [x] `indices: Option>` (optionnel) - [x] `normals: Option>` (pour Phong) — plus `uvs: Option>` - [ ] Refactorer `Mesh` pour contenir : - [ ] `geometry: Arc` - [ ] `vertex_buffer: wgpu::Buffer` - [ ] `index_buffer: Option` - [ ] `transform: Transform` (état CPU) - [x] Ajouter un mesh de test (cube unitaire) en exemple — **fait** (helper `cube_geometry` dans l'exemple `cube`, Étape 5, 2026-09-17) > **Note (2026-09-17, DRAFT Étape 7)** : le refactor « Mesh contient `Arc` » ci-dessus reste > **reporté** (il porte sur le *stockage CPU* des données géométriques). En revanche le volet *matériau* > de `Mesh` a été fait en Étape 7 : `Mesh.material: Option>` (cf. PLAN Phase 2, gestion des > matériaux), indépendant de la structure `Geometry`. ### 1.3 Shader Phong Minimal - [x] Créer `standard_shader.wgsl` (Étape 2, 2026-09-16) : - [x] Vertex shader : projection * view * world * position - [x] Fragment shader : éclairage directionnel (+ hémisphérique) - [x] Uniforms : `view`, `proj`, `cam_pos`, `light_dir`, `light_color`, `options` - [x] Mettre à jour `Material` / pipeline pour supporter les uniforms du shader Phong (bind group layouts frame+object, Étape 3) — **désormais branché** sur l'exemple `cube` (Étape 5, 2026-09-17) ### 1.4 Scene avec identifiants (MVP : String IDs) - [x] `Scene` implémentée avec **String IDs** (`HashMap>`, `...Material`, entités) — état actuel validé ; décision : rester en String IDs pour le MVP - [x] Méthodes : `add_mesh()`, `get_mesh()`, `add_material()`, `add_entity()`, `iter_entities()`, `remove_entity()` - [x] Caméra active dans la `Scene` : `set_camera()` / `camera()` (Étape 4.3) - [ ] **Reporté (étape "Handles typés")** : migrer vers `slotmap` générationnel (`MeshId`/`MaterialId`) quand l'éviction/les performances le justifieront ### 1.5 Rendu du Prototype - [x] Uniform buffer pour la frame : `view`, `proj`, `cam_pos`, `light_dir` (Étapes 3+4) — écrit chaque frame depuis la caméra active - [x] Uniform buffer par mesh : `world` (calculée sur CPU depuis `transform.to_matrix()`, Étape 4.2) - [x] `Renderer::render_scene()` itère sur les entités de la Scene et dessine chacune (liaison bind groups frame+object) - [x] Exemple fonctionnel : un cube éclairé tourne à l'écran — **fait** (Étape 5, 2026-09-17 : brancher `standard` sur l'exemple `cube` + mesh cube + rotation via `App::render_scene`) --- ## Phase 2️⃣ — Système de Ressources complet **Objectif** : Étoffer la Scene avec tous les types de ressources. ### 2.1 Arènes complètes - [ ] `SlotMap` - [ ] `SlotMap` (struct de base) - [ ] `SlotMap` (struct de base) - [ ] `SlotMap` pour les entités de la scène ### 2.2 Entités & Hiérarchie - [ ] Struct `Entity { mesh_id: Option, material_id: Option, transform: Transform }` - [ ] `Scene::add_entity()` → retourne `EntityId` - [ ] `Scene::iter_entities()` → pour le render loop ### 2.3 Camera dans la Scene - [x] Intégrer `Camera` comme ressource de la Scene (Étape 4.3 : `Scene::set_camera` / `camera()`, caméra active unique) - [ ] Permettre plusieurs caméras (actuelle/inactive) et une sélection par identifiant (`scene.set_active_camera(camera_id)`) - [ ] Exposer une caméra orbitale contrôlable (exemple final, Phase 5) --- ## Phase 3️⃣ — GPU-Driven Rendering **Objectif** : Déléguer les calculs de transformation et culling au GPU (suivre ARCHI_CPU_GPU.md). ### 3.1 Compute Shader - [ ] Buffer `TransformBuffer` (CPU → GPU) : positions/rotations/échelles brutes - [ ] Buffer `MatrixBuffer` (GPU calculé) : World Matrices finales - [ ] Compute shader : calcul des World Matrices pour tous les meshes ### 3.2 Frustum Culling GPU - [ ] Ajouter `BBox` dans `Geometry` (center + extents) - [ ] Buffer `BoundingBoxBuffer` (CPU → GPU, statique) - [ ] Compute shader : culling basé sur la frustum de caméra - [ ] Buffer `IndirectDrawBuffer` rempli par le GPU ### 3.3 Rendu Indirect - [ ] `draw_indexed_indirect()` au lieu de draw calls individuels - [ ] Un seul command draw pour tous les objets visibles --- ## Phase 4️⃣ — Fonctionnalités Avancées **Objectif** : Qualité visuelle et performances. ### 4.1 Textures - [ ] Struct `Texture` avec chargement d'image - [ ] Ajouter `uvs: Option>` dans `Geometry` - [ ] BindGroup pour les textures dans le shader - [ ] `Material` supporte une texture diffuse ### 4.2 Éclairage avancé - [ ] Support multi-lumières (directionnelles, ponctuelles) - [ ] Lumières hémisphériques - [ ] Shadows (optionnel) ### 4.3 Optimisations - [ ] Batching par Material (réduction des state changes GPU) - [ ] Level of Detail (LOD) - [ ] HDR + Tone Mapping (optionnel) --- ## Phase 5️⃣ — Documentation & Polish - [ ] Exemple complet : mesh texturé, éclairé, avec caméra orbitale - [ ] Documentation API (`docs/ARCHI_SCENE.md`) - [ ] Tests unitaires : `Geometry`, `Scene`, `Transform` - [ ] README mis à jour avec les nouvelles fonctionnalités --- ## Notes de Décision | Décision | Raison | |----------|--------| | **Normals dès Phase 1** | Nécessaires pour le shader Phong ; sans elles, pas d'éclairage | | **UVs en Phase 4** | Inutiles avant les textures ; on garde `Geometry` simple au départ | | **BBox en Phase 3** | Utile uniquement pour le frustum culling GPU | | **World Matrix CPU → MVP, GPU → Phase 3** | Le MVP est plus simple avec un uniform par mesh ; la migration GPU-driven est progressive | | **String IDs pour le MVP, slotmap reporté** | Le code et le README utilisent des String IDs (simples, sûrs, figés avant la boucle de rendu) ; `ARCHI_ARENES.md` reste la cible "handles typés" pour plus tard. La dépendance `slotmap` a été retirée tant qu'elle est inutilisée | | **Present mode FIFO figé pour l'instant** | Le swapchain utilise `PresentMode::Fifo` avec `desired_maximum_frame_latency: 2` (double buffering vsync) — défaut sûr : pas de tearing, énergie minimale, zéro artefact. On **gèle ce choix** ; `Mailbox` (triple buffering) pourra être exposé en option et `Immediate` restera réservé à l'offscreen, **on s'occupera du present mode le moment venu** (quand le pipeline GPU-driven arrivera, Phase 3) — ce n'est pas bloquant pour les étapes 1-2 |