ajout material et pipeline_cache

This commit is contained in:
Jérôme Bousquié
2026-07-06 10:40:00 +02:00
parent 22edac6ad5
commit 6c94fc96d6
12 changed files with 464 additions and 316 deletions
+45 -28
View File
@@ -1,45 +1,62 @@
La nouvelle vision architecturale
Pour comprendre ce changement, imagine que tu veux peindre 10 tableaux différents.
# ARCHI_MESH_MATERIAL.md (Version corrigée)
Avant (Ton code actuel) : Chaque tableau possède sa propre cuisine, son propre chef (le pipeline), et son propre matériel de peinture. C'est inefficace.
## La nouvelle vision architecturale : L'Atelier de Rendu
Après (La nouvelle structure) : Tu as un Atelier (le Renderer) qui contient des Recettes (le Material / Shader) et tu apportes tes Toiles (le Mesh). Tu peux utiliser la même recette pour 50 toiles différentes sans effort.
Pour comprendre notre structure, imagine que tu veux peindre 10 tableaux différents.
Voici la nouvelle répartition des responsabilités :
**Avant :** Chaque tableau possédait sa propre cuisine, son propre chef (le pipeline), et son propre matériel. C'était inefficace et lourd.
1. Le Mesh (La géométrie)
Il ne sait pas comment il est affiché, il sait seulement ce qu'il est.
**Après :** Tu as un Atelier (Renderer) qui orchestre le dessin. Il utilise des Recettes (Material + PipelineCache) pour définir l'apparence et traite des Toiles (Mesh) pour la géométrie. Tu peux utiliser la même recette pour 50 toiles différentes sans effort.
Contenu : Il possède les données brutes (le VertexBuffer et éventuellement un IndexBuffer pour optimiser le dessin).
---
Rôle : Il est passif. C'est juste un conteneur de données prêtes à être envoyées à la carte graphique.
## 1. Le Mesh (La Géométrie)
2. Le Material (Le look)
Il définit l'apparence de l'objet.
Il est purement passif. Il ne sait pas comment il est affiché, il sait seulement ce qu'il est.
Contenu : Il possède le RenderPipeline. Le pipeline contient tout ce qui est "lourd" à créer (le shader compilé, les états de fusion, le mode de tracé).
- **Contenu :** `vertexBuffer`, optionnellement `indexBuffer`, et les compteurs associés (`num_vertices`, `num_indices`).
- **Rôle :** Fournir les données brutes au GPU.
Rôle : Il est réutilisable. Si tu as 10 objets en métal, ils partagent tous le même Material (donc le même pipeline).
---
3. Le Renderer (L'Orchestrateur)
Il devient beaucoup plus léger et efficace.
## 2. Le Material & PipelineCache (Le Look & La Recette)
Contenu : Il ne possède plus de buffers en dur. Il possède une méthode render qui accepte un Mesh ET un Material.
Le look est désormais découplé de la géométrie via une gestion centralisée.
Rôle : Il fait la liaison au moment de l'appel :
**PipelineCache :** C'est la bibliothèque de recettes. Il charge les shaders (WGSL), compile les RenderPipeline, et les met en cache (via `HashMap` + `Arc`) pour éviter de dupliquer les ressources GPU.
Rust
**Material :** C'est une instance légère qui pointe vers une recette compilée. Il contient un `shader_id` et une référence partagée (`Arc`) vers le RenderPipeline.
- **Rôle :** Garantir la réutilisation. Si 100 objets partagent le même shader, ils pointent tous vers la même instance compilée en mémoire.
---
## 3. Le Renderer (L'Orchestrateur)
Il est devenu ultra-léger et généraliste. Il ne possède plus aucun buffer ni pipeline en dur.
- **Contenu :** Aucun état lourd.
- **Rôle :** Il fait la liaison au moment de l'appel :
```rust
// Schématiquement
renderer.render_pass.set_pipeline(&material.pipeline); // On change de recette
renderer.render_pass.set_vertex_buffer(0, &mesh.buffer); // On pose la toile
renderer.render_pass.draw(...);
Pourquoi cette structure est-elle meilleure ?
Réutilisation (Performance) : Si tu as 100 objets avec le même shader, tu ne compiles ton shader qu'une seule fois. Tu gagnes énormément en vitesse de chargement et en occupation mémoire.
render_pass.set_pipeline(&material.pipeline); // On change de recette
render_pass.set_vertex_buffer(0, mesh.vertex_buffer.slice(..)); // On pose la toile
// Puis dessin indexé ou simple...
```
Modularité : Tu peux créer un Mesh "Cercle" et un Mesh "Carré". Tu peux créer un Material "Rouge" et un Material "Bleu". Tu peux combiner n'importe quel Mesh avec n'importe quel Material sans changer une ligne de code.
---
Nettoyage : Ton renderer.rs devient un orchestrateur pur au lieu d'être un fourre-tout.
## Pourquoi cette structure est-elle meilleure ?
La note technique : "Pipeline Cache"
Dans cette nouvelle structure, tu devras faire attention à un détail : le couplage entre le Mesh et le Material.
Si ton Mesh a une structure de Vertex différente de ce que le Material (Shader) attend, le rendu sera invalide. Le Material doit donc garantir qu'il est capable de traiter le format de données fourni par le Mesh.
1. **Performance :** Les shaders sont compilés une seule fois. La mémoire GPU est optimisée grâce au partage des RenderPipeline via `Arc`.
2. **Modularité :** Tu peux combiner n'importe quel Mesh avec n'importe quel Material.
3. **Propreté :** Ton Renderer est désormais un orchestrateur pur. Il ne connaît plus le détail des shaders ou des layouts de sommets : il se contente d'exécuter la commande de dessin.
---
## Quelques notes techniques pour ta doc
- **Découplage :** Le Material demande au PipelineCache de lui fournir un pipeline au moment de sa création.
- **Sécurité :** Le PipelineCache utilise un `HashMap` pour retrouver instantanément un pipeline existant par son `shader_id`, évitant les compilations inutiles.
- **Flexibilité :** Le Mesh gère lui-même ses indices, permettant de passer facilement du rendu simple au rendu indexé optimisé.