Mehr als nur ein Texturpatch? (Teil 2)


Mehr als nur ein Texturpatch? (Teil 2)

Feb 6, 2021

Im zweiten Teil dieser Serie widmen wir uns den Problemen, welche bei der Darstellung von Texturen im dreidimensionalen Raum auftreten, und ihren Lösungen.

Zur Darstellung eines mit einer Textur belegten Körpers müssen für jeden Bildpunkt des Monitors die relevanten Pixel der Textur bestimmt und daraus ein Mittelwert errechnet werden. Nehmen wir als Beispiel einmal die Erde. Aus weiter Entfernung erscheint sie blau wie die Weltmeere und nimmt auf dem Bildschirm wenig Fläche ein, besteht also aus wenigen Bildpunkten. Dafür tragen zur Darstellung eines Bildpunktes jedoch viele Pixel der Textur bei. Wenn wir den Abstand nun auf ein übliches Maß verringern, können wir die Kontinente und ihre Beschaffenheit erkennen. Die Erde nimmt jetzt bereits die ganze Fläche unseres gedanklichen, quadratischen Bildschirms ein. Zu jedem Bildpunkt tragen nun jedoch weniger Pixel bei als noch eine Stufe zuvor. Als nächstes gehen wir noch etwas näher heran und versuchen die Stadt zu erkennen, in der wir wohnen. Einzelne Pixel werden so langsam erkennbar, pro Bildpunkt ist also nur noch etwa ein Pixel übrig. Schließlich gehen wir ganz nah heran und suchen unser Haus, können es jedoch aufgrund der begrenzten Auflösung der Textur nicht erkennen. Wir haben den minimalen Betrachtungsabstand erreicht, jedes Pixel wird bereits in mehreren Bildpunkten dargestellt. Den damit verbundenen optischen Eindruck bezeichnet man landläufig auch als "verpixelt".

Vom Betrachtungsabstand hängt also ab, wie viele Pixel für einen Bildpunkt relevant sind. Große Distanzen führen demnach zu einem hohen Rechenaufwand. Das ist jedoch nicht das einzige Problem. Durch die Anzahl der Pixel und die damit einhergehende Streuung wird es zunehmend schwierig, einen repräsentativen Mittelwert für die Pixel zu errechnen. Daher tritt insbesondere bei abgeflachten Ebenen der Alias-Effekt auf, welcher sich im oberen Bereich des folgenden Beispiels als so genanntes Moiré-Muster äußert. Es ist deutlich zu erkennen, dass die schwarzen und weißen Felder sich in der Entfernung nicht mehr abwechseln.

Wenn die Farben der relevanten Pixel nahe beieinander liegen, dann ist auch der Mittelwert nahe an den einzelnen Pixeln und damit repräsentativ. Anders sieht es jedoch aus, wenn die Farben weit auseinander liegen. Dann unterscheiden sich auch die gebildeten Mittelwerte stärker, was zu "Farbsprüngen" führt. Um diesem Effekt entgegen zu wirken, wird in der Computergrafik eine Technik namens Mip-Mapping verwendet. Dazu werden Kopien einer Textur erzeugt, wobei jede Kopie nur halb so groß ist wie die vorherige. Wenn die originale Textur also 1024*1024 Pixel groß ist, ist die erste Mip-Map 512*512 Pixel groß, die darauf 256*256 Pixel und so weiter bis zur letzten, welche schließlich eine Größe von 1*1 Pixel hat. Bei diesem einmaligen Arbeitsschritt errechnen wir sozusagen im Voraus die Mittelwerte. Dabei können wir zudem qualitativ hochwertigere und teurere Algorithmen verwenden, als dies zur Laufzeit des Spiels machbar wäre.

Nun wird also nicht mehr ausschließlich die Original-Textur zur Darstellung verwendet, sondern je nach Entfernung eine ihrer kleineren Kopien, welche eine angemessenere Anzahl an relevanten Pixeln aufweist. Dadurch sinkt der Rechenaufwand pro Bildpunkt erheblich und der Alias-Effekt tritt nicht mehr auf. Als Nebeneffekt kommt es allerdings zu einer Unschärfe, die umso größer ist, je weiter der betrachtete Punkt entfernt ist.

Um sehen zu können, welche Mip-Map bei welcher Distanz von Gothic genutzt wird, habe ich die Mip-Maps der Grastextur unterschiedlich gefärbt. Dieses Experiment fiel übrigens in die Zeit eines der Moddertreffen, weshalb einige der Anwesenden nicht umher kamen, dieses "Regenbogengras" zu bestaunen. Zugegeben, es hat eine psychedelische Note.

Jedenfalls war die ernüchternde Erkenntnis, dass die originale Textur kaum zur Darstellung genutzt wurde, sondern fast immer eine der Mip-Maps. Dies erkennt man daran, dass das Gras auf dem Screenshot nur am untersten Rand eine normale Farbe hat. Der Grund dafür war bald gefunden: Gothic verzichtet auf die Verwendung von anisotropischer Filterung (AF). Dabei handelt es sich um eine Technik zur Reduzierung der Unschärfe, welche neben dem Betrachtungsabstand auch den Winkel zwischen der Kamera und der jeweiligen Fläche berücksichtigt.

Dazu muss man sagen, dass die Grafik-Engine von Gothic auf DirectX 7 basiert und diese Technik damals eigentlich bereits verfügbar war. In Gothic gab es jedoch keine Möglichkeit sie zu aktivieren und dies ließ sich mit den Mitteln des traditionellen Gothic-Moddings auch nicht ändern. Darum habe ich die anisotropische Filterung damals über den Treiber der Grafikkarte erzwungen. Wie man sieht, wurde die Original-Textur anschließend in einem größeren Radius verwendet, die einzelnen Mip-Maps werden besser überblendet und die Schärfe bleibt auch in der Tiefe erhalten.

Degenerated, der ursprüngliche Autor des D3D11 Renderers, hatte einige Zeit später ein Plugin für Gothic geschrieben, welches ein für uns gravierendes Vertex-Limit aushebelte. Dieses Plugin habe ich sodann erweitert und unter anderem die anisotropischen Filterung aktiviert. Zwar steigt damit der Rechenaufwand wieder, bei modernen Grafikkarten merkt man jedoch keinen Unterschied in der Performance.

Der folgende – zugegeben schon etwas ältere – Screenshot vergleicht zum Abschluss noch einmal das Standard-Gothic mit unserer optimierten Version. Ich möchte nochmal betonen, dass es sich dabei um dieselben Texturen handelt, welche bloß unterschiedlich dargestellt werden.

Übrigens erschienen einige Zeit später das SystemPack, welches neben vielen Bugfixes auch die anisotropische Filterung beinhaltet, und Union, welches die Plugin-Architektur übernommen und die Entwicklung neuer Plugins vereinfacht hat. Im nächsten Teil dieser Serie geht es übrigens um das RGB-Farbmodell und die Darstellung von transparenten Pixeln.