Zum 3DCenter Forum
Inhalt




Wie stark komprimiert 3Dc?

15. Juni 2005 / von aths / Seite 6 von 7


   Wie stark komprimiert nun 3Dc?

Wir haben es eben schon angesprochen: Farbtexturen sind problematisch, weil man für die RGB-Darstellung nur drei Komponenten braucht, das Speichermanagment aber auf "glatte" Zahlen, also Zweierpotenzen optimiert ist. Normalmaps, die ja keine Farben sondern Winkel speichern, brauchen ebenfalls nur drei Komponenten, nämlich die Winkel je für X, Y und Z. In der Praxis wird man bei 8 Bit pro Winkel-Komponente also wieder die Füllbits haben, um auf 32 Bit pro Wert zu gelangen.

ATI rechnet nun so: Wir lassen von den 32 Bit die 8 Füllbits weg, außerdem die Z-Komponente, die später aus X und Y rekonstruiert werden kann, und speichern 16 Winkel-Vektoren in 128 Bit. Statt 16 Winkel * 32 Bit = 512 Bit hat man nun, mit nur noch 128 Bit, eine 4:1-Komprimierung.

Die ungenutzten Füllbits, sowie die Z-Komponente wegzulassen (dies nicht mit dem Z-Buffer verwechseln, das ist etwas ganz anderes!!) ist natürlich auch ohne 3Dc möglich. Dann wäre man bei 16 Bit pro Winkel. Gibt es solche Texturformate denn? Ja, praktisch alle Grafikkarten unterstützen das. 16 Bit pro Wert sind, wie auch bei normalen 16-Bit-Farbtexturen, speicherzugriffstechnisch kein Problem. ATI rechnet bei 3Dc die Füllbits mit, was sie bei DXTC berechtigterweise nicht tun.

Außerdem zählt ATI zur unkomprimierten Textur den Z-Wert mit, obwohl man den auch ohne 3Dc weglassen kann. Die Z-Rekonstruktion funktioniert in jedem Fall nur dann, wenn folgende Bedingung stimmt:



Diese Beziehung drückt aus, dass die Länge des Vektors = 1 ist.

Die "1" ist die dritte Information, die für alle Normalenwinkel gilt und daher nicht mitgespeichert wird. Nur deshalb kann man überhaupt eine Vektor-Komponente weglassen, und anschließend trotzdem noch einen 3D-Winkel rekonstruieren. Stellt man oben genannte Formel nach z um, ergibt sich:



Der mathematische Ausdruck, um Z wiederherzustellen. Von den Lösungen der Wurzel wird nur die positive berücksichtigt, da die gewählte Normalmap-Darstellung keine negativen Z-Werte kennt.


   Nachteile einer Zweikanal-Darstellung

Die Frage ist nun: Kann man einfach so, ohne "Strafe", eine Komponente weglassen, da sie sich ja rekonstruieren lässt? Dies funktioniert erstens nur im so genannten "Tangent Space". Das heißt für uns, dass die Z-Komponenten immer positive Werte annimmt (X und Y können nach dem Bias im Shader auch negativ werden). Mit der Bedingung Z≥0 ist die Lösung der Wurzel also eindeutig.

Doch zweitens nun folgende Überlegung: Mit 3 Komponenten à 8 Bit sind 23*8 = 224 = 16777216 unterschiedliche Werte möglich. Davon repräsentieren allerdings einige Bitkombinationen den genau gleichen Winkel und sind insofern "verschenkt" (alle Vektoren, die untereinander linear abhängig sind, stellen den gleichen Winkel dar).

Speichert man nur zwei Komponenten à 8 Bit, sind nur noch 22*8 = 216 = 65536 unterschiedliche Werte möglich. Zwar hat man jetzt keine "verschenkten" Bitkombinationen mehr, aber trotzdem lassen sich insgesamt viel weniger Winkel-Werte darstellen.

Konkret vergröbert man die Quantisierung: Wo bei Normalmaps mit drei Kanälen noch feine Winkel-Unterschiede darstellbar sind, wird die Winkelauflösung bei der Reduktion auf zwei Kanäle gröber. Allerdings erfordert diese Nutzung von drei-kanaligen Normalmaps, dass die Vektoren vor der Bumpmapping-Verrechnung renormalisiert (also auf Länge 1) gebracht werden. Die Z-Rekonstruktion gibt es aus Performance-Sicht jedoch auch nicht umsonst.

ATI wirbt lautstark mit der 4:1-Komprimierung, und schreibt in einem White Paper (PPT), das der Öffentlichkeit nicht so bekannt ist, auf Seite 20 folgendes: "Compression: 4:1 for 32 bit textures, 2:1 for 16 bit textures".

Von 32-Bit-Texturen darf man jedoch nicht ausgehen, weil man dann Füllbits mitzählt. Von 24-Bit-Texturen darf man auch nicht ausgehen, weil die Reduktion auf die Speicherung von zwei Kanälen eben einen Qualitätsverlust mit sich bringt, der aber nichts mit der eigentlichen 3Dc-Komprimierung zu tun hat. Der 3Dc-Dekodierer in der Hardware dekomprimiert einfach zwei Kanäle, die Z-Rekonstruktion ist "Handarbeit" des Entwicklers in seinem Pixelshader-Programm. Die Möglichkeit der Z-Rekonstruktion war ja auch schon vor der 3Dc-Entwicklung bekannt, worauf wir gleich kommen (Stichwort CxU8V8). Man muss also von 16-Bit-Texturen ausgehen und hat dann eine 2:1-Komprimierung - auch wenn ATI in den Werbeunterlagen 4:1 schreibt.

Leider vergleicht ATI in den Werbeunterlagen die Qualität mit einer für Normalmaps missbrauchten DXT-Komprimierung ohne Renormalierung. Klar kostet die Renormalisierung extra Pixelshader-Leistung (Ausnahme: NV40), aber die Z-Rekonstruktion im Pixelshader kostet ja auch Leistung. Bevor ATI 3Dc vorstellte, wurde eine bestimmte Methode mit DXT5 und Kanal-Swizzling empfohlen – und natürlich mit Renormalisierung. Dass dies die mit DXT5 mögliche Qualität erheblich erhöht, haben die Macher aktueller 3Dc-Werbeunterlagen vergessen.

Bei allen DXT-Verfahren werden die Zwischenwerte, wie weiter oben gezeigt, durch lineare Interpolation gewonnen. Wir zeigten auch was passiert, wenn man Normalen einfach linear interpoliert: Die so gewonnenen Zwischenwerte sind von der Länge her zu kurz. Es ist ganz selbsverständlich, deswegen die Normalisierung auszuführen, bei 3Dc wird dies ja implizit über den Umweg der Z-Rekonstruktion bedacht. Ein White Paper, welches bei DXT5 die Renormalisierung vergisst, zeugt entweder von mangelndem Sachverstand oder es liegt eine bewusste Handlung vor, um den Leser über die Qualitätsvorteile von 3Dc zu täuschen.


   Wie 3Dc zu bewerten ist

Nun ist eine 2:1-Komprimierung ja besser als nichts. Nvidia hat mit dem NV40 gar keine spezielle Normalmap-Komprimerung anzubieten, lediglich unkomprimierte Zweikanal-Texturen werden unterstützt. Und da nützt auch Shader Model 3 nichts. Wird der Speicher knapp, muss der Entwickler mit DXT5 arbeiten, was qualitätsmäßig in der Regel nicht an 3Dc herankommt.

GeForce3 bis FX boten noch ein besonderes Zweikanal-Format namens CxV8U8 mit automatischer Z-Rekonstruktion. Bei der Radeon muss man hierfür den Pixelshader bemühen. Nun ist es prinzipiell sinnvoll, dem Shader solche Aufgaben zu überlassen, aber die Verwendung von 3Dc kostet wegen der erforderlichen Z-Rekonstruktion eben zusätzliche Shader-Power, was bedacht werden muss. Die Renormalisierung zur guten Ausnutzung von 3-Kanal-Normalmaps kostet den NV40 hingegen nichts, solange im FP16-Format gerechnet wird. Da einzelnen Kanäle eh nur mit FX8-Genauigkeit gespeichert werden, ist FP16-Verrechnung hierfür vollkommen ausreichend.

Die Radeon ab R420 kann mit 3Dc Speicherplatz und -Bandbreite sparen wenn dafür im Gegenzug mehr arithmetische Rechenpower zur Verfügung gestellt wird. Der NV40 kann besonders hochwertige, jedoch leider auch speicherintensive Normalmaps einsetzen, und die Renormalisierung ausführen, ohne die FP32-Pixelpipeline zu belasten. Beide Ansätze haben spezielle Vor- und Nachteile.

Im Gegensatz zu CxV8U8 (GeForce3 - FX, im NV40 nicht mehr unterstützt) muss allerdings der Pixelshader-Code angepasst werden, ehe 3Dc oder ein anderes Zweikanal-Format für Normalmaps verwendet werden kann. Das sehen wir als Hürde, entgegen den vollmundigen Ankündigungen ist 3Dc-Support heute noch sehr rar. Außerdem ist der 2:1-Komprimierungsvorteil nicht so gewaltig, als dass ohne 3Dc nichts mehr ginge. Man kann eben nicht, wie ATI suggeriert, mit 3Dc bei gleichem Speicherbedarf Texturen mit verdoppelter Auflösung pro Achse verwenden.

Und: Für sehr hochwertige Bumpmaps können 8 Bit pro Komponente knapp werden. Wenn man sich schon um ein FP16-Format drücken möchte, kann man mit der Speicherung von allen drei Winkelkomponenten wie schon beschrieben genauer arbeiten. 3Dc eignet sich also wegen dem Auflösungsverlust bei der Beschränkung auf zwei Kanäle nur für Allerwelts-Bumpmapping.






Kommentare, Meinungen, Kritiken können ins Forum geschrieben werden - Registrierung ist nicht notwendig Zurück / Back Weiter / Next

Shortcuts
nach oben