You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

4.6 KiB

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.