Browse Source

Added some thoughts for texture compression, will use these to create optimization scripts when we actually have the textures

master
TimV-BREX\TimVoelker 1 month ago
parent
commit
38fea04c04
  1. 136
      Texture Compression/texturen-codec-vorueberlegungen.md

136
Texture Compression/texturen-codec-vorueberlegungen.md

@ -0,0 +1,136 @@
# Texturoptimierung für den Web-Avatar: Codec- und Algorithmus-Vorüberlegungen
Stand: 08.09.2026 · Vorbereitung, noch ohne Dateien
Anschluss an: `uebergabe-animationspipeline.md`
---
## Kontext
Die Animationspipeline ist abgeschlossen (88 KB pro Clip, kein Engpass mehr).
Der Fokus liegt jetzt auf den Texturen des Avatars. Die Dateien liegen noch
nicht vor — dieses Dokument hält nur die Vorüberlegungen zu Codec und
Verfahren fest, damit sie nicht verloren gehen.
Packing und Scaling sind bereits auf dem Schirm und hier bewusst nur
gestreift.
---
## Virtual Textures: nicht praktikabel
Frage war, ob sich etwas wie Unreals Virtual Textures in three.js abbilden
lässt.
**Kurz: nein — und für einen Avatar auch nicht das passende Werkzeug.**
- Unreals VT setzt auf Sparse/Tiled Resources auf GPU-Ebene. WebGL2 kennt das
nicht, WebGPU exponiert es derzeit ebenfalls nicht.
- Ein Nachbau wäre möglich (Atlas + Indirection-Textur + Feedback-Pass), aber
der Feedback-Readback ist im Browser latenzbehaftet. Aufwand und Nutzen
stehen in keinem Verhältnis.
- VT lohnt sich, wenn *unique* Texturdaten das VRAM um ein Vielfaches
übersteigen — Open-World-Terrain, große Umgebungen. Ein Avatar hat 5–15 Maps.
Das Problem existiert hier nicht.
### Was den eigentlichen Zweck erfüllt
**Progressives Nachladen.** Erst eine 512er-Fassung zeigen, dann auf volle
Auflösung tauschen. Umsetzbar entweder über zwei separate Dateien oder, bei
KTX2, durch gezieltes Laden nur der oberen Mip-Level.
---
## Mipmaps: nicht verzichtbar
Verzicht wäre kontraproduktiv.
- Mips kosten +33 % Speicher, machen das Sampling aber **schneller**, weil der
Texture-Cache trifft.
- Ohne Mips shimmert das Bild sichtbar, sobald die Textur verkleinert
dargestellt wird.
- Bei KTX2 sind die Mips mitkomprimiert — der Download-Aufschlag beträgt 33 %
auf die *komprimierte* Größe, nicht auf die Rohgröße.
### Falle
three.js kann für GPU-komprimierte Texturen **keine Mips zur Laufzeit
generieren**. Sie müssen beim Encoding in die Datei geschrieben werden.
gltfpack und `toktx` tun das per Default, aber wer sich auf
`generateMipmaps` verlässt, bekommt bei KTX2 stillschweigend keine.
### Wo Verzicht vertretbar ist
Nur bei Maps, die nie verkleinert dargestellt werden: LUTs, UI-Elemente,
Screen-Space-Texturen.
### Ergänzend statt Verzicht
`anisotropy` auf 4–8 setzen. Kostet wenig und bringt bei streifenden
Blickwinkeln deutlich mehr als jede Mip-Diskussion.
---
## Codec-Optionen
Der entscheidende Unterschied ist nicht die Dateigröße, sondern was im
**VRAM** landet.
| Format (4K, RGBA) | Download | VRAM inkl. Mips |
|---|---|---|
| PNG | groß | ~85 MB |
| WebP / AVIF | klein | ~85 MB (dekodiert zu RGBA8) |
| KTX2 UASTC → BC7/ASTC | mittel | ~21 MB |
| KTX2 ETC1S → BC1/ETC | sehr klein | ~11 MB |
WebP spart ausschließlich Bandbreite. KTX2 spart Bandbreite, Speicher und
Sampling-Bandbreite. Für einen Avatar mit mehreren Maps der klare Gewinner.
### Die zwei Basis-Modi
**ETC1S** — starke Kompression, sichtbare Artefakte an harten Kanten.
Geeignet für AO, Roughness, Metallic, Masken, oft auch Albedo.
**UASTC** — deutlich höhere Qualität, größere Datei (mit RDO + Zstd aber
vertretbar). **Pflicht für Normal Maps.** ETC1S auf einer Normal Map erzeugt
Banding im Shading, das auf Haut sofort auffällt.
Zusätzlich: Normal Maps als Zwei-Kanal speichern und Z im Shader
rekonstruieren. Entfernt einen kompletten Kanal als Fehlerquelle.
---
## Werkzeuge
**gltfpack** wendet Textureinstellungen global an (`-tc`, `-tu`, `-tw`).
Sobald Normal Map und ORM unterschiedlich behandelt werden sollen, reicht das
nicht mehr.
**glTF-Transform** ist dann das bessere Werkzeug: kennt `--slots` und erlaubt
Codec, Qualität und Auflösung getrennt pro Map-Typ.
**Alternativ:** `toktx` / `basisu` direkt auf die Einzeldateien anwenden und
das Ergebnis anschließend im glTF referenzieren.
### three.js-Seite
`KTX2Loader` mit `setTranscoderPath()` und `detectSupport(renderer)`. Ohne
`detectSupport` weiß der Loader nicht, ob nach BC7 oder ASTC transcodiert
werden soll.
---
## Erster Schritt, sobald die Dateien da sind
**Vor allen Codec-Feinheiten: wie viele Maps werden überhaupt gebraucht?**
- Roughness ggf. als konstanter Faktor statt als Textur
- Metallic bei Haut ohnehin 0
- AO teilweise verzichtbar
Jede eingesparte Map schlägt jede Codec-Entscheidung.
Danach dasselbe Vorgehen wie bei den Animationen: **erst messen, dann
optimieren.** Ein Inventar mit Auflösung, Kanalbelegung und tatsächlichem
Informationsgehalt pro Map. Erfahrungsgemäß sind halbleere Kanäle und
überdimensionierte Masken der häufigste Fund.
Loading…
Cancel
Save