Pendenzen: Textur-Spike render3d in Queue (Als Naechstes)
- SPIKE_TEXTUR_render3d.md: Auftrag/Uebergabe fuer den kleinsten ehrlichen Durchstich (RenderStyle::Textured real: UVs, prozedurales Schachbrett, Textur-Bind-Group, MESH_TEXTURED_WGSL, spike3d umschaltbar). - PENDENZEN: Spike als konkretes Item unter 'Als Naechstes', verlinkt am bestehenden Textur-/PBR-Backlog-Eintrag als dessen erster Durchstich.
This commit is contained in:
+2
-2
@@ -32,7 +32,7 @@ _(leer — Worker trägt hier ein, was er gerade anpackt)_
|
|||||||
|
|
||||||
## ⏭️ Als Nächstes
|
## ⏭️ Als Nächstes
|
||||||
|
|
||||||
_(Öffnungen als Boolean-Löcher ist jetzt in 🔧 In Arbeit)_
|
- [ ] **SPIKE — Bild-Texturen in `render3d` (`RenderStyle::Textured` real machen).** Kleinster ehrlicher Durchstich: beweisen, dass der wgpu-3D-Renderer echte Bild-Texturen auf Wandflächen zeigt, sichtbar im `spike3d`-Fenster. **Voller Auftrag/Übergabe: [SPIKE_TEXTUR_render3d.md](SPIKE_TEXTUR_render3d.md)** (Ausgangslage verifiziert, Symbol-Karte, exakter Umfang, harte Randbedingungen, Akzeptanz, Abschlussbericht). Kurz: UVs auf Wandflächen (planar in Metern, Alt-Pfad `[pos,normal,color]` bitgleich unangetastet) · prozedurales 256×256-Schachbrett (kein Asset, kein `image`-Crate) · Textur-Bind-Group group 1 (Globals bleibt group 0) · `MESH_TEXTURED_WGSL` (gleiche Beleuchtung, Albedo aus `textureSample`) · Verdrahtung bei `RenderStyle::Textured` · `spike3d` umschaltbar (`T`). **Nur `render3d`-Crate, keine neuen Deps, Default-Build unverändert.** Akzeptanz: `cargo test` grün (Mesh-Regression + naga-Test für `MESH_TEXTURED_WGSL`), `spike3d` zeigt weltmassstäbliche Textur. Ist der **erste Durchstich der Textur-/PBR-Pipeline** (§3D-REST unten) → am Ende ehrliche Lückenliste + Aufwandsschätzung für „richtig gutes" Texturing.
|
||||||
|
|
||||||
## 📋 Backlog (Priorität grob absteigend)
|
## 📋 Backlog (Priorität grob absteigend)
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ _(Öffnungen als Boolean-Löcher ist jetzt in 🔧 In Arbeit)_
|
|||||||
- [ ] Elemente im Schnitt anwählbar; render3d 2D-Schraffur auf 3D-Flächen.
|
- [ ] Elemente im Schnitt anwählbar; render3d 2D-Schraffur auf 3D-Flächen.
|
||||||
|
|
||||||
### 3D-REST (engine-schwer, bewusst NICHT blind — mit Nutzer angehen)
|
### 3D-REST (engine-schwer, bewusst NICHT blind — mit Nutzer angehen)
|
||||||
- [ ] **Textur-/PBR-Pipeline** (Sampler/Bindings/UV in wgpu; dann `textured`-Style + `Component.texture3d`/Material echt rendern).
|
- [ ] **Textur-/PBR-Pipeline** (Sampler/Bindings/UV in wgpu; dann `textured`-Style + `Component.texture3d`/Material echt rendern). **Erster Durchstich als Spike terminiert → [SPIKE_TEXTUR_render3d.md](SPIKE_TEXTUR_render3d.md) (steht unter ⏭️ Als Nächstes).**
|
||||||
- [x] ~~**Wand-Schicht-Bänder in 3D** Option B~~ — **bereits umgesetzt** in `resolveWallBands(layered=true)` (`src/plan/toWalls3d.ts:236-241`): 3D-Viewer-Pfad liefert je Materiallage ein eigenes `WallBand` (Dicke + Component-Albedo + Normalen-Versatz), `pushSegment` emittiert jede Lage als eigene Voll-Box. `dominantLayerColor` ist nur noch Fallback für den Schnitt-Einkörper-Pfad (`layered=false`). Verifiziert per Code-Lesung.
|
- [x] ~~**Wand-Schicht-Bänder in 3D** Option B~~ — **bereits umgesetzt** in `resolveWallBands(layered=true)` (`src/plan/toWalls3d.ts:236-241`): 3D-Viewer-Pfad liefert je Materiallage ein eigenes `WallBand` (Dicke + Component-Albedo + Normalen-Versatz), `pushSegment` emittiert jede Lage als eigene Voll-Box. `dominantLayerColor` ist nur noch Fallback für den Schnitt-Einkörper-Pfad (`layered=false`). Verifiziert per Code-Lesung.
|
||||||
- [ ] **Ortho-Ray-Picking** (aktuell perspektivischer Pick-Strahl; Front/Top/Side-Presets vor erster Navigation leicht ungenau).
|
- [ ] **Ortho-Ray-Picking** (aktuell perspektivischer Pick-Strahl; Front/Top/Side-Presets vor erster Navigation leicht ungenau).
|
||||||
- [ ] **3D-Griffe/Editieren** (Wand-Endpunkte im 3D ziehen etc. — bisher nur Auswahl + Panel-Edit).
|
- [ ] **3D-Griffe/Editieren** (Wand-Endpunkte im 3D ziehen etc. — bisher nur Auswahl + Panel-Edit).
|
||||||
|
|||||||
@@ -0,0 +1,137 @@
|
|||||||
|
# SPIKE — Bild-Texturen in `render3d` (`RenderStyle::Textured` real machen)
|
||||||
|
|
||||||
|
Stand: 2026-07-05. **Auftrag/Übergabe für einen Agenten. Kleinster ehrlicher
|
||||||
|
Durchstich — kein Produktfeature, keine Integration.**
|
||||||
|
|
||||||
|
Ziel: Beweisen, dass der bestehende wgpu-3D-Renderer echte **Bild-Texturen** auf
|
||||||
|
Wandflächen darstellen kann, sichtbar im `spike3d`-Fenster. Am Ende steht eine
|
||||||
|
belastbare Aussage, wie viel Arbeit „richtig gutes texturiertes 3D" wirklich ist —
|
||||||
|
statt Spekulation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 0. Ausgangslage (verifiziert am 2026-07-05)
|
||||||
|
|
||||||
|
- `render3d` ist **kein** Three.js-Wrapper, sondern ein eigenständiger wgpu-Renderer
|
||||||
|
(~6400 LOC): echte GPU-Pipeline (wgpu 29), Tiefenpuffer, MSAA, WGSL-Shader.
|
||||||
|
Läuft nativ (winit-Spike), headless (naga-validiert) und im Browser (WebGPU).
|
||||||
|
- **`RenderStyle::Textured` existiert bereits als Stub** (`gpu.rs:34` Enum-Variante,
|
||||||
|
`gpu.rs:47` Parse aus `"textured"`) — es gibt aber **kein echtes Texturing**:
|
||||||
|
kein Sampler, keine Textur-Bind-Group, keine Bilddaten.
|
||||||
|
- Die `cap_pipeline` mit Layout `[pos vec3, uv vec2]` + `CAP_WGSL` ist **nicht** für
|
||||||
|
Bildtexturen, sondern für die **Schnittflächen-Kappen** (prozedurale Schraffur);
|
||||||
|
die UVs steuern dort den Schraffur-Abstand. **Nicht damit verwechseln.**
|
||||||
|
- **Günstig für uns:** Die Muster, die der Spike braucht, existieren schon —
|
||||||
|
ein UV-tragendes Vertex-Layout und eine zweite/dritte Pipeline, die sich die
|
||||||
|
`Globals`-Bind-Group teilt (`grid`, `cap`). Der texturierte Mesh-Pfad reiht sich
|
||||||
|
1:1 in dieses Muster ein.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Echte Symbole — vor dem Coding lesen
|
||||||
|
|
||||||
|
| Was | Ort |
|
||||||
|
|---|---|
|
||||||
|
| Vertex heute interleaved `[pos.xyz, normal.xyz, color.rgb]`, `FLOATS_PER_VERTEX`, `Mesh`-Struct | `src-tauri/render3d/src/types.rs:322` ff. |
|
||||||
|
| Quad-Emitter (Normale + Farbe je Vertex, Reihenfolge `(0,1,2)+(0,2,3)`) | `src-tauri/render3d/src/mesh.rs:886` |
|
||||||
|
| Wand-Extrusion / Mesh-Bau | `src-tauri/render3d/src/mesh.rs` — `extrude_wall` (`:91`), `build_walls_mesh` (`:911`) |
|
||||||
|
| Haupt-Pipeline + `Globals`-Bind-Group (group 0) | `src-tauri/render3d/src/gpu.rs:232`–`:320` |
|
||||||
|
| Vorlage „zweite Pipeline teilt sich Globals" — Grid | `src-tauri/render3d/src/gpu.rs:329` |
|
||||||
|
| Vorlage „Pipeline mit UV-Layout `[pos vec3, uv vec2]`" — Cap | `src-tauri/render3d/src/gpu.rs:408` |
|
||||||
|
| `RenderStyle`-Enum + Stub `Textured` | `src-tauri/render3d/src/gpu.rs:34`, `:47` |
|
||||||
|
| Pipeline-Bindung im Render-Pass (Muster für Stil-Umschaltung) | `src-tauri/render3d/src/gpu.rs:847` |
|
||||||
|
| Shader als WGSL-Konstanten (`MESH_WGSL`, `CAP_WGSL`) | `src-tauri/render3d/src/shaders.rs` |
|
||||||
|
| Beleuchtungsmodell (hemisphärisch + Directional + Fill) — Doku | `src-tauri/render3d/src/shaders.rs:1`–`40` |
|
||||||
|
| naga-WGSL-Validierung headless (Test-Vorlage) | `src-tauri/render3d/src/lib.rs:924` (`cap_module`) |
|
||||||
|
| Fenster-Spike mit Orbit-Kamera | `src-tauri/render3d/src/bin/spike3d.rs` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Umfang — exakt das, nicht mehr
|
||||||
|
|
||||||
|
### 2.1 UVs auf Wandflächen
|
||||||
|
- In der Quad-Emitter-Funktion (`mesh.rs:886`) je Vertex eine **UV** berechnen:
|
||||||
|
planare Projektion in **Metern** — `u` = Distanz entlang der Wandachse,
|
||||||
|
`v` = Höhe (z). Textur-Raster damit weltmassstäblich (z. B. 1 Kachel = 1 m).
|
||||||
|
- Den bestehenden `[pos, normal, color]`-Pfad **bitgleich unangetastet** lassen.
|
||||||
|
Zwei zulässige Wege (Agent wählt begründet):
|
||||||
|
1. **Separates additives UV-Array** in `Mesh` (Default leer/None), oder
|
||||||
|
2. **Paralleler `build_walls_mesh_textured`** → interleaved
|
||||||
|
`[pos.xyz, normal.xyz, uv.xy]`.
|
||||||
|
- Regressionstests für den Alt-Pfad müssen grün bleiben (siehe §4).
|
||||||
|
|
||||||
|
### 2.2 Test-Textur prozedural (kein Asset, keine `image`-Crate)
|
||||||
|
- Ein **256×256 RGBA-Schachbrett/Grid im Code** generieren (`Vec<u8>`).
|
||||||
|
- `device.create_texture` + `queue.write_texture` + `Sampler`
|
||||||
|
(`FilterMode::Linear`, `AddressMode::Repeat`). Mipmaps optional (nice-to-have für
|
||||||
|
flache Blickwinkel; kein Muss für den Spike).
|
||||||
|
- Selbstständig, damit der Spike ohne Dateipfade/Asset-Pipeline läuft.
|
||||||
|
|
||||||
|
### 2.3 Textur-Bind-Group (group 1)
|
||||||
|
- Neue Bind-Group-Layout mit `texture_view` (`TextureSampleType::Float`) +
|
||||||
|
`sampler`. **`Globals` bleibt group 0** und unverändert.
|
||||||
|
|
||||||
|
### 2.4 Textured-Pipeline + WGSL (`MESH_TEXTURED_WGSL`)
|
||||||
|
- Vertex-Layout `[pos vec3, normal vec3, uv vec2]`, `TriangleList`.
|
||||||
|
- **Dieselbe Beleuchtung wie `MESH_WGSL`** (hemisphärisches Ambient + Directional +
|
||||||
|
Fill) — nur **Albedo = `textureSample(tex, samp, uv)`** statt Vertex-Farbe.
|
||||||
|
- Depth-Format, MSAA (`SAMPLE_COUNT`) und Color-Target **identisch** zur
|
||||||
|
Haupt-Pipeline (sonst inkompatibler Render-Pass).
|
||||||
|
- Pipeline-Layout bindet group 0 (Globals) **und** group 1 (Textur).
|
||||||
|
|
||||||
|
### 2.5 Verdrahten
|
||||||
|
- Bei `RenderStyle::Textured` im Render-Pass die neue Pipeline + beide Bind-Groups
|
||||||
|
setzen (Muster: `cap_pipeline`-Bindung bei `gpu.rs:847`).
|
||||||
|
|
||||||
|
### 2.6 Spike sichtbar machen
|
||||||
|
- `spike3d.rs` so erweitern, dass der Stil auf `Textured` schaltbar ist
|
||||||
|
(Tastendruck, z. B. `T`, **oder** Startkonstante). Die Demo-Wände sollen
|
||||||
|
texturiert im Orbit erscheinen.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Randbedingungen (hart)
|
||||||
|
|
||||||
|
- **Nur** die `render3d`-Crate. `src/web.rs` und die Tauri-/`native3d`-Oberfläche
|
||||||
|
**nicht** anfassen.
|
||||||
|
- Feature-gegatet unter dem bestehenden `render`/`window`-Feature.
|
||||||
|
**Default-Build und Default-Darstellung bleiben unverändert.**
|
||||||
|
- **Keine neuen Dependencies** (insbesondere **kein `image`-Crate**) für den Spike.
|
||||||
|
- Term-/Reihenfolge-sensible Geometrie (Parität) wird **nicht** berührt — es kommt
|
||||||
|
nur additiv ein UV-Kanal + ein zweiter Render-Pfad dazu.
|
||||||
|
- Kommentar-Stil und Sprache (Deutsch, ausführliche Begründungs-Kommentare) wie im
|
||||||
|
umgebenden Code beibehalten.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Akzeptanz / Verifikation
|
||||||
|
|
||||||
|
1. `cargo test` (im Crate-Verzeichnis `src-tauri/render3d`) **grün**, inklusive:
|
||||||
|
- bestehende Mesh-Regression (Alt-Pfad `[pos,normal,color]` unverändert),
|
||||||
|
- **neuer naga-Validierungstest** für `MESH_TEXTURED_WGSL` (Vorlage:
|
||||||
|
`lib.rs:924`).
|
||||||
|
2. `cargo run --features window --bin spike3d` zeigt die Demo-Wände mit
|
||||||
|
**erkennbarer, korrekt gemappter** Schachbrett-Textur:
|
||||||
|
- Raster weltmassstäblich (in Metern), keine Verzerrung an Gehrungen/Ecken,
|
||||||
|
- beleuchtet wie im Shaded-Modus (Volumen bleibt ablesbar).
|
||||||
|
3. Umschalten Shaded ↔ Textured zur Laufzeit (oder per Startkonstante) funktioniert
|
||||||
|
ohne Re-Meshing-Crash.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Abschlussbericht (vom Agenten am Ende zu liefern)
|
||||||
|
|
||||||
|
- Welche Dateien geändert/hinzugefügt wurden und warum.
|
||||||
|
- Wie die UVs projiziert werden (Achswahl, Massstab, Verhalten an Gehrungen).
|
||||||
|
- Welcher der beiden UV-Wege (§2.1) gewählt wurde und weshalb.
|
||||||
|
- **Ehrliche Lückenliste für „richtig gutes" Texturing:** Asset-/Bild-Datei-Laden,
|
||||||
|
Material→Textur-Zuordnung (Wandtyp/Layer → Material), Normal-/Roughness-Maps
|
||||||
|
(PBR), anisotropes Filtern + Mipmaps, Web-Pfad (`web.rs`/WebGPU), UI zum
|
||||||
|
Zuweisen. Grobschätzung Aufwand je Punkt.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Nicht im Scope
|
||||||
|
|
||||||
|
Asset-/Bild-Datei-Laden · Material-System · mehrere Texturen gleichzeitig ·
|
||||||
|
PBR/Normal-Maps · Web-Pfad (`web.rs`) · jegliche UI · Anbindung unter die Webview.
|
||||||
Reference in New Issue
Block a user