From ecefe6161142adaccbd1c9e2ed9559cbb306633d Mon Sep 17 00:00:00 2001 From: Karim Date: Sun, 5 Jul 2026 00:12:06 +0200 Subject: [PATCH] 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. --- PENDENZEN.md | 4 +- SPIKE_TEXTUR_render3d.md | 137 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 SPIKE_TEXTUR_render3d.md diff --git a/PENDENZEN.md b/PENDENZEN.md index 5d60eb0..1078741 100644 --- a/PENDENZEN.md +++ b/PENDENZEN.md @@ -32,7 +32,7 @@ _(leer — Worker trägt hier ein, was er gerade anpackt)_ ## ⏭️ 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) @@ -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. ### 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. - [ ] **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). diff --git a/SPIKE_TEXTUR_render3d.md b/SPIKE_TEXTUR_render3d.md new file mode 100644 index 0000000..a830b84 --- /dev/null +++ b/SPIKE_TEXTUR_render3d.md @@ -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`). +- `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.