Multisampling Anti-Aliasing unter der Lupe
22. Mai 2003 / von aths / Seite 5 von 8
Framebuffer-Komprimierung: Dort ansetzen, wo es was bringt
Was ATI mit dem R300 bzw. Nvidia mit der GeForce FX als Komprimierung vermarktet, ist eigentlich gar keine. Denn RAM wird kein bisschen gespart, sondern nur Bandbreite. Im Vergleich zur Z-Komprimierung ist die Framebuffer-Komprimierung höchstwahrscheinlich viel simpler. Man nutzt den Umstand aus, dass beim Multisampling innerhalb eines Pixels alle Subpixel den gleichen Farbwert aufweisen (jedenfalls sofern das Pixel vollständig im Polygon liegt.) Radeon ab 9500 bzw. GeForce FX ab 5600 schreiben diese Farbe dann nur noch ein mal in den Framebuffer, sowie einen Vermerk dass diese Farbe für alle Subpixel gilt. Wird dieses Pixel im Laufe des Renderings von einer sichtbaren Polygon-Kante bedeckt, schreibt der Chip ganz normal die Farbsamples in die zugehörigen Framebuffer.
Unklar ist, wie die Framebuffer-Komprimierung genau realisiert wird. Denkbar sind im wesentlichen zwei Ansätze. Erstens, dass pro Innenpolygon-Pixel vermerkt wird "Die Farbe des Multisample-Buffers Nr. 0 gilt für alle Subpixel", und zweitens, dass eine Kachel- (bzw. Burstline-) basierte Komprimierung eingesetzt wird. Bei "Render to Texture" scheint generell keine Komprimierung stattzufinden. Color Compression ist unseres Wissen sowohl bei ATI als auch bei Nvidia überhaupt nur zusammen mit Multisampling aktiv, und komprimiert maximal um die Anti-Aliasing-Stufe (bei 4x AA also maximal 4:1.)
Wie vorhin gezeigt wurde, steigt beim Multisampling die Framerate deutlich, wenn Z-Compression genutzt wird. Eine Farb-Komprimierung ist der nächste logische Schritt und steigert die Geschwindigkeit gerade ab 4x noch mal deutlich. ATI vermarktet dieses Feature als Teil des HyperZ III-Paketes, also als Teil der Effizienz steigernden Architektur, Nvidia schlägt Color Compression dem bildqualitätverbessernden Maßnahmenpaket zu und nennt es Intellisampling. Die FX 5200 hat Multisampling-Anti-Aliasing, aber keine Color Compression. Inwieweit Intellisample HCT (ab NV35) Geschwindigkeit bringt, ist noch unklar.
Das Feature der "Framebuffer-Komprimierung" ist unbedingt notwendig, um das Multisampling-Potenzial auszunutzen. Ohne die Qualität auch nur im geringsten zu vermindern, steigt die Geschwindigkeit, und zwar vor allem dann, wenn es um viele Subpixel geht, man also jeden Geschwindigkeitsschub dringend brauchen kann. Alle Karten mit Multisampling, aber ohne diese Farb-Pseudo-Komprimierung, weisen eine Anti-Aliasing-Technologie auf, die auf der halben Strecke stehen geblieben ist.
Multisampling alleine spart praktisch nur Füllrate, und dank den Features, die zusätzlich Bandbreite sparen, wird Anti-Aliasing richtig schnell. Welche Besonderheiten müssen dafür in Kauf genommen werden?
Texturen, Pixelshader und Multisampling: Wo Licht ist, ist auch Schatten
Die Pipeline sampelt einen Texturwert, und schreibt ihn für alle vier Subpixel in die jeweiligen Framebuffer. Beim Downfiltering werden alle vier Farben gelesen und gemischt. Logischerweise ändert sich nichts, wenn vier gleiche Farben gemischt werden. Durch Multisampling werden Texturen also komplett "in Ruhe gelassen".
Dieses Pixel gehört vollständig zum Dreieck. Es wird vier mal
der genau gleiche Farbwert in die Multisample-Buffer geschrieben,
und diese vier Farben werden dann beim Downfiltering gemischt.
Ergebnis: Das Texel ist exakt so, als gäbe es kein Anti-Aliasing.
Allerdings wird der Z-Test nach wie vor pro Subpixel vorgenommen. Das ist unbedingt notwendig. Angenommen, zwei Dreiecke durchdringen sich. Damit auch die Schnittkante geglättet wird, muss der Test subpixelweise stattfinden. Wird das nicht getan, gibt es keine Glättung, gut zu sehen bei Parhelia. Parhelia glättet nur Polygon-Außenkanten und keine Schnittkanten.
Da wäre noch zu klären, was denn beim Multisampling an den Außenkanten mit der Textur passiert. Wir erinnern uns - für jedes Dreieck wird pro Pixel eine Farbe gesampelt, welche dann für jedes Subpixel, das zum Polygon gehört, verwendet wird. Das heißt, das Subpixel bekommt nicht seinen "tatsächlichen" Farbwert. Das äußert sich besonders an Kanten. Dort kann es passieren, dass ein Texturwert gesampelt wird, der gar nicht mehr im Polygon liegt. In DirectX 9 gibt es die Möglichkeit, das zu verhindern, allerdings erst ab Pixelshader 3.0: Mit einem Flag ("Centroid") wird die Sampleposition dann soweit korrigiert, dass sie noch im Polygon liegt. Heutige Karten müssen damit leben, dass Pixelfarben für Polygonkanten in Textur-Bereichen gesampelt werden, welche das Polygon gar nicht belegt.
Beim Pixelshader ab Version 1.3 (unterstützt ab GeForce4 Ti, Radeon 8500 und Parhelia) gibt es die Möglichkeit, im Shader nicht nur die Pixel-Farbe, sondern auch einen neuen Z-Wert festzulegen. Dies ist erforderlich, um Z-korrektes Bump Mapping zu rendern. Bump Mapping erzeugt an einem glatten Polygon durch pixelweise Beleuchtungseffekte einen Rauheitseffekt. Diese "Hügeligkeit" ist natürlich nur Schein, das Polygon bleibt glatt. Das führt dann zu unerwarteten Ergebnissen, wenn dieses Polygon von einem anderen durchdrungen wird. Damit die Bedeckungsberechnung mit der simulierten Rauheit übereinstimmt, muss der Pixelshader, welcher ja das Bump Mapping übernimmt, auch den Z-Wert ändern, da dieser zur Bedeckungsprüfung herangezogen wird.
Dieser Z-Wert gilt dann aber für alle Subpixel. Einfach gesagt, ist nun "bedeckungsrichtiges Bump Mapping" pixelgenau möglich, aber nicht subpixelgenau.
Es gibt noch Multisampling-Verfahren, die eigene Besonderheiten haben. Das muss natürlich auch mal angesprochen werden.