Warum sind 3D-Modelle so schwer?
Dein Modell wird heimlich dicker
Du hast eine GLB-Datei exportiert, 10MB, fühlt sich okay an. Du öffnest sie auf dem Handy: weißer Bildschirm, Ruckeln oder sogar ein direkter Absturz.
Am Computer kein Problem, am Handy explodiert es. Das ist nicht die Schuld des Codes. Es ist eine wenig intuitive Eigenschaft von 3D-Modellen: auf der Festplatte und im Videospeicher sind sie völlig unterschiedlich groß.
Ein JPG-Bild ist auf der Festplatte vielleicht nur 200KB. Aber die GPU versteht kein JPG; sie versteht nur rohe Pixel. Also wird das Bild vor dem Hochladen in den Videospeicher vollständig dekomprimiert. Eine 2048x2048-Textur verbraucht nach der Dekomprimierung etwa 22MB Videospeicher. Wenn du 6 Texturen verwendest (albedo, normal, roughness, metallic, AO, emissive), kostet ein einziges Material 132MB.
Ein Handy hat vielleicht insgesamt nur 2-4GB Videospeicher, und die Texturen eines einzigen Modells fressen 3-6% davon. Und jetzt stell dir 10 Modelle in der Szene vor.
Mach's auf: Wo die Bytes bleiben
Ein typisches GLB-Modell besteht aus drei Hauptteilen: Vertex-Daten, Texturen und Metadaten plus Animationen.
Nimm ein echtes PBR-Modell:
| Bestandteil | Was es ist | Typischer Anteil | Hinweis |
|---|---|---|---|
| Texturen | albedo, normal, roughness, metallic, AO usw. | 70-85% | Fast immer der Großteil |
| Vertex-Daten | position, normal, UV, tangent, color | 10-20% | Hängt von der Komplexität ab |
| Animationsdaten | Skelette, Skinning, Keyframes | 0-15% | Nur wenn animiert |
| Sonstiges | Materialdefinitionen, Szenenstruktur, Kameras | < 2% | Vernachlässigbar |
Texturen machen etwa 80% aus. Oft denkt man, die Vertices müssten optimiert werden, aber was wirklich Platz frißt, sind die Texturen.
"Auf der Platte klein" bedeutet nicht "im Videospeicher klein"
Das ist vielleicht der wichtigste Punkt, um 3D-Leistung zu verstehen.
PNG und JPG sind für die Netzwerkübertragung gemacht——klein auf der Platte, schnell heruntergeladen. Aber die GPU kann sie nicht direkt verwenden; sie müssen erst vollständig in rohe Pixel dekomprimiert werden. Die Formel:
VRAM = Breite * Höhe * 4 Byte (RGBA) * 1.333 (mit Mipmaps)
Eine 4096x4096 RGBA-Textur:
| Metrik | Wert |
|---|---|
| PNG-Dateigröße | ~8MB |
| JPG-Dateigröße | ~1.5MB |
| VRAM-Verbrauch (mit Mipmaps) | ~87MB |
Ein 1.5MB JPG wird im Videospeicher zu 87MB.
Was sind Mipmaps? Die GPU erzeugt eine Reihe immer kleinerer Versionen einer Textur, von der Originalgröße bis zu 1x1 Pixel, wobei jede Stufe halb so groß ist wie die vorherige. Das lässt ferne Objekte schneller und schärfer rendern, kostet aber etwa 33% mehr Videospeicher. Nahezu jede 3D-App verwendet Mipmaps, also ist dieser Overhead im Wesentlichen Standard.
PNG und JPG sind also wie Vakuum-Aufbewahrungsbeutel——für die Reise klein komprimiert, aber am Zielort musst du sie komplett ausbreiten. Der Download wurde schneller, aber beim Videospeicher sparst du nichts.
Was passiert, wenn der Videospeicher ausgeht
Du bekommst keinen netten "zu wenig Speicher"-Dialog. Die Realität ist schlimmer:
- Mobil: weißer Bildschirm, oder das Betriebssystem beendet den Tab direkt
- VR-Headsets: Frame-Drops. Ein verlorener Frame in VR ist kein "bisschen Lag"——er verursacht Übelkeit
- Desktop: Texturflackern, Degradierung, langsameres Rendering
Auf Reddit baute ein Entwickler eine WebXR-Galerie und stopfte 60 stereoskopische Bilder auf ein Quest. Anfangs lief es, dann wurde es immer instabiler, bis es abstürzte. Er verbrachte Tage damit, seinen Code zu debuggen, bevor er erkannte, dass er nie ernsthaft über VRAM nachgedacht hatte——er hatte einfach immer weiter JPGs in die GPU gestopft.
Zwei Wege der Komprimierung
3D-Modell-Komprimierung teilt sich in zwei Richtungen:
Vertex-Komprimierung——speichert Geometriedaten (Vertex-Koordinaten, Normalen, UVs) kompakter. Zum Beispiel 32-Bit-Floats gegen 16-Bit-Integer tauschen (das nennt man Quantisierung). Repräsentative Lösungen: Draco, MeshOpt, KHR_mesh_quantization.
Textur-Komprimierung——hält Texturen auch im Videospeicher komprimiert. Die GPU dekodiert einzelne Pixel beim Sampling on the fly, fast ohne Leistungskosten. Repräsentative Lösung: KTX2 + Basis Universal.
| Vertex-Komprimierung | Textur-Komprimierung | |
|---|---|---|
| Was reduziert wird | Geometriedaten | Texturen |
| Typische Wirkung | 50-90% kleiner | 50-70% kleiner auf der Platte, 75% weniger VRAM |
| Verlustbehaftet? | Ja, Präzisionsverlust | Ja, Qualitätsverlust |
| Ideal für | Vertex-dichte Modelle | Fast jedes PBR-Modell |
| Siehe | Teil 2 | Teile 3 und 4 |
Ein häufiger Irrtum: Vertices mit Draco komprimieren und fertig. Aber Texturen sind 80% der Modellgröße——halbiere die Vertices und das Ganze schrumpft vielleicht nur um 10%. Du musst beide Seiten anpacken.
Keine einzige Methode gewinnt überall
Das ist die Kernthese der ganzen Serie:
Verschiedene Plattformen, Geräte und Anwendungsfälle brauchen verschiedene Komprimierungsstrategien.
| Szenario | Haupt-Flaschenhals | Fokus |
|---|---|---|
| Desktop-Web-Showcase | Download-Geschwindigkeit | Dateigröße |
| Mobil-Browser | Videospeicher | Textur-Komprimierung |
| VR-Headset | Videospeicher + Framerate | Textur-Komprimierung + Vertex-Vereinfachung |
| WeChat Mini Program | Paketgröße + Kompatibilität | Leichte Optionen (MeshOpt) |
| Große Szenen | Videospeicher + Draw Calls | Vollständige Komprimierung + LOD |
Jeder kommende Artikel wird nicht nur sagen "nimm X und fertig". Er wird erklären: wo X glänzt, wann es nach hinten losgeht, und wann du stattdessen zu Y greifen solltest.
Nächste Schritte
Dieser Artikel hat das Problem eingekreist. Der nächste wird praktisch——lerne die drei Werkzeuge der Vertex-Komprimierung kennen: Quantisierung, MeshOpt und Draco.