Plan für spätere Renderer-Implementierung
This commit is contained in:
@@ -0,0 +1,110 @@
|
|||||||
|
# wds — Renderer-Plan
|
||||||
|
|
||||||
|
Stand: 2026-06-12. Entscheidungen aus der irl3d-Analyse, festgehalten bevor
|
||||||
|
der Projekt-Einstieg über die Kern-Systeme (Signals/KV, CLI-Phase) läuft.
|
||||||
|
|
||||||
|
## Ziel
|
||||||
|
|
||||||
|
PS1-artiger Look, von vornherein nativ und simpel implementiert statt
|
||||||
|
emuliert: affines Texture-Mapping, Integer-Vertex-Koordinaten, 16-Bit-Farbe.
|
||||||
|
Niedrige interne Auflösung (320×240), hochskaliert aufs Fenster.
|
||||||
|
|
||||||
|
Referenz ist `../irl3d`: gleiche Engine-Idee (datengetrieben, eine
|
||||||
|
OBJ-Szene, Signals/KV/Ink), aber dort als 8-Bit-Palette-CPU-Softwarerenderer
|
||||||
|
in Q16.16. wds ersetzt den Grafikpfad durch echtes GPU-Rastern.
|
||||||
|
|
||||||
|
## Hardware-Target
|
||||||
|
|
||||||
|
Mittelklasse-Laptop von 2015 (Klasse: i5-5200U + Intel HD 5500).
|
||||||
|
Konsequenzen:
|
||||||
|
|
||||||
|
- Zwei schwache CPU-Kerne → Transformation gehört auf die GPU, die CPU
|
||||||
|
bleibt für Physik und Spiellogik frei.
|
||||||
|
- Per-Frame-Vertex-Streaming (CPU-Transform, GTE-Stil) wäre auf alten
|
||||||
|
iGPU-Treibern der riskante Pfad (Buffer-Upload-Stalls) → statische
|
||||||
|
Vertex-Buffer, einmal hochgeladen.
|
||||||
|
- wgpu-Backend: Vulkan primär (ANV unterstützt Gen8+), GL als Fallback
|
||||||
|
einplanen. Keine Features jenseits von Baseline-WebGPU benutzen.
|
||||||
|
|
||||||
|
## Entscheidungen
|
||||||
|
|
||||||
|
1. **wgpu direkt, kein pbio.** pbio ist eine Abstraktion für
|
||||||
|
Software-Renderer (8-Bit-Framebuffer + Palette-Blit) — für echtes
|
||||||
|
GPU-Rastern Verschwendung. winit + wgpu direkt im Projekt.
|
||||||
|
|
||||||
|
2. **Vertex-Shader-Transform mit Pixel-Snapping.** Model→View→Projektion im
|
||||||
|
Vertex-Shader. Danach `xy/w` auf das Pixelraster der internen Auflösung
|
||||||
|
runden und wieder mit `w` multiplizieren → Vertex-Jitter wie auf der PS1,
|
||||||
|
authentisch gerechnet, nicht nachgestellt.
|
||||||
|
|
||||||
|
3. **Affines Texture-Mapping via `@interpolate(linear)`.** WGSL kann die
|
||||||
|
perspektivische Korrektur pro Varying abschalten. UVs (und ggf.
|
||||||
|
Vertex-Colors) linear interpolieren → das Textur-Wobbeln kommt gratis.
|
||||||
|
Gegenmittel bleibt wie auf der PS1 das Unterteilen großer Flächen im
|
||||||
|
Asset, nicht Shader-Tricks.
|
||||||
|
|
||||||
|
4. **RGB555 + Ordered Dithering im Fragment-Shader.** wgpu hat kein
|
||||||
|
555-Render-Target-Format; Render-Target bleibt RGBA8 bei 320×240, aber
|
||||||
|
der Fragment-Shader quantisiert auf 5 Bit pro Kanal mit 4×4-Bayer-Dither.
|
||||||
|
Die Farbreduktion ist echt, nur das Speicherformat ist modern.
|
||||||
|
Das 16. Bit entspricht dem PS1-Maskbit → bei uns **1-Bit-Alpha**
|
||||||
|
(Alpha-Test, kein Blending) — Fortführung der Index-0-Transparenz
|
||||||
|
aus irl3d.
|
||||||
|
|
||||||
|
5. **Z-Buffer: ja.** Ordering-Tables wären nur eine technische Hürde, kein
|
||||||
|
ästhetischer Gewinn. Standard-Depth-Buffer auf dem internen Target.
|
||||||
|
|
||||||
|
6. **UVs aus dem OBJ (`vt`).** irl3d ignoriert `vt` und mappt planar über
|
||||||
|
Welt-Koordinaten; wds liest echte UVs. PS1-Spiele hatten handgemachte
|
||||||
|
UVs — das gehört zum Look.
|
||||||
|
|
||||||
|
7. **Licht: gebacken zuerst.** Nur Gouraud-Shading wäre zu einseitig.
|
||||||
|
Plan: Lichteffekte in die Szene backen (Blender → Vertex-Colors),
|
||||||
|
im Shader mit der Textur multiplizieren und mitquantisieren. Dynamische
|
||||||
|
per-Vertex-Punktlichter (im Vertex-Shader, additiv auf die gebackene
|
||||||
|
Farbe) als spätere Stufe. Kein Per-Pixel-Lighting.
|
||||||
|
|
||||||
|
## Pipeline-Skizze
|
||||||
|
|
||||||
|
```
|
||||||
|
statische VBOs (Pos i16/f32, UV, Vertex-Color)
|
||||||
|
→ Vertex-Shader: Model·View·Proj, dann Snap auf 320×240-Raster
|
||||||
|
→ Raster (Hardware), UV/Color @interpolate(linear)
|
||||||
|
→ Fragment: Texel-Fetch (nearest), × Vertex-Color,
|
||||||
|
Alpha-Test (1 Bit), RGB555-Quantisierung + 4×4-Bayer
|
||||||
|
→ RGBA8-Offscreen 320×240 + Depth
|
||||||
|
→ Blit-Pass: Nearest-Upscale mit Letterbox (4:3) aufs Fenster
|
||||||
|
```
|
||||||
|
|
||||||
|
Draw-Granularität wie irl3d: pro Instance ein Draw (Uniform: Pos + Yaw),
|
||||||
|
Material-Batching später, wenn es weh tut.
|
||||||
|
|
||||||
|
## Offene Punkte
|
||||||
|
|
||||||
|
- **Asset-Pipeline:** Texture-Painting in Blender ist mühsam. Kandidaten
|
||||||
|
für Textur-pro-Fläche-Workflows: TrenchBroom (Map-Format-Import nötig),
|
||||||
|
Crocotile 3D, Blockbench. Entscheidung wenn der Szenen-Loader ansteht.
|
||||||
|
- **Texturformat:** 8-Bit-CLUT-TGA weiterverwenden (PS1-authentisch,
|
||||||
|
Paletten-Swaps bleiben möglich) vs. direkte 16/24-Bit-Texturen.
|
||||||
|
- **Fog / Distance-Fade:** irl3d hat hartes Pop-In bei `CULL_DIST` —
|
||||||
|
in wds von Anfang an als Fade Richtung Sky-Farbe einplanen (im Shader
|
||||||
|
trivial, passt zur PS1).
|
||||||
|
- **Skybox:** Cubemap wie irl3d oder schlicht Far-Plane-Farbe + Fog.
|
||||||
|
- Interne Auflösung umschaltbar lassen (QVGA/VGA wie irl3d).
|
||||||
|
|
||||||
|
## Aus irl3d portierbar (renderer-unabhängig)
|
||||||
|
|
||||||
|
signals, kv, ink, story_ctrl, game (ActionCtx-Idee), physics, pick,
|
||||||
|
camera, obj-Loader (um `vt` erweitern), tga, wav, audio, assets,
|
||||||
|
fix/math (Q16.16 bleibt für Spiellogik/Physik sinnvoll; der Renderer
|
||||||
|
selbst rechnet f32 — die GPU kennt ohnehin nur Floats).
|
||||||
|
|
||||||
|
## Projektphasen
|
||||||
|
|
||||||
|
1. **CLI-Phase (läuft):** KV-Store, Signal/Action-Dispatcher,
|
||||||
|
Ink-Integration, Konsolen-REPL als erstes Frontend. Effects als Daten
|
||||||
|
(`hide_object`, `play_sound`, `load_palette`), damit spätere Subsysteme
|
||||||
|
sie konsumieren, ohne dass der Kern sie kennt.
|
||||||
|
2. Datenmodell (Mesh/Instance/Material/Scene + TOML-Formate) headless.
|
||||||
|
3. Renderer nach diesem Plan, gegen das stehende Datenmodell.
|
||||||
|
4. Physik, Audio, Panel-UI andocken (Ports aus irl3d).
|
||||||
Reference in New Issue
Block a user