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