1 changed files with 136 additions and 0 deletions
@ -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…
Reference in new issue