Game Engines machen die meisten ihrer Shading-Arbeiten pro Pixel oder pro Fragment. Aber es gibt noch eine andere Alternative, die im Film seit Jahrzehnten beliebt ist: das Object Space Shading. Pixar`s Renderman, der bekannteste Renderer für Computergrafik, verwendet die Reyes-Rendering-Methode, die eine Object Space Shading Methode ist.
Dieser Blog befasst sich mit einer Object Space Shading Methode, die auf Hardware der Direct3D 11-Klasse funktioniert. Insbesondere werden wir uns mit dem Shading des Texturraums beschäftigen, die die Texturparametrisierung des Modells nutzt. Shading im Object Space bedeutet, dass wir die Shading-Rate bereits von den Pixeln entkoppelt haben und es ist auch einfach, sie zeitlich zu entkoppeln. Wir haben diese Entkopplungen genutzt, um Wege zur Leistungssteigerung zu finden, aber wir werden auch einige zukünftige Möglichkeiten in diesem Bereich diskutieren.
Textur Space Shading.
Wenn die meisten Menschen den Begriff „Texture Space Shading“ hören, denken sie im Allgemeinen an eine Rasterung der Geometrie im Texturraum. Bei diesem Ansatz gibt es zwei Schwierigkeiten: die Sichtbarkeit und die Wahl der richtigen Auflösung. Rasterung im Texturbereich bedeutet, dass Sie keine Sichtbarkeitsinformationen aus der Kameraansicht haben und am Ende Texte schattieren, die nicht sichtbar sind. Außerdem sind ihre Auflösungsoptionen begrenzt, da Sie nur bei einer Auflösung gleichzeitig rastern können.
Die Wahl der Auflösung ist wichtig, da sie ihre gesamten Shadingkosten erhöht. Jede Midmap-Ebene kostet zusätzlich 4 x Shading-Kosten. Wenn Sie also 512×512 benötigen, um die Pixelrate für einen Teil eines Objekts und 1024×1024 für einen anderen Teil anzupassen, aber Sie können nur einen auswählen, welchen wählen Sie? Wenn Sie 512 x 512 wählen, wird ein Teil des Objektes unter dem Sample liegen. Wenn Sie 1024×1024 wählen, kostet ein Teil ihres Objekts 4x so viel wie nötig. Das steigt mit jedem Level, das du überbrückst. Wenn Sie z.B. ein Objekt haben, das sich über 4 Mipmap-Ebenen erstreckt, können Sie die Shading-Kosten um bis zu 64x erhöhen, um ein bestimmtes Auflösungsziel für das gesamte Objekt zu erreichen.
Also versuchen wir einen anderen Ansatz. Stattdessen rastern wir im Bildschirmbereich und statt des Shadings nehmen wir nur die Texte auf, die wir als Shadingarbeit benötigen. Deshalb haben wir den Begriff „Texel Shading“ gewählt. Da wir aus der Kameraperspektive rastern, erhalten wir die beiden Informationen, die normalerweise in Textur Space Methoden nicht verfügbar sind – Sichtbarkeit nach einem frühen Depth-Test und die Ableitung des Bildschirmbereichs zur Auswahl der Mipmap-Ebene. Das Werk selbst sind die Texte.
Wie Texel Shading funktioniert.
Auf hohem Niveau läuft der Prozess wie folgt ab:
- Rendern Sie das Modell und nehmen Sie die gewünschten Texte auf.
- Schattieren Sie die Texte und schreiben Sie sie in eine Texturmap der Ergebnisse.
- Lookup-Ergebnisse beim zweiten Rendern des Modells.
Beachten Sie, dass das Texel Shading wahlweise pro Objekt oder sogar pro Fragment angewendet werden kann. Die Auswahl auf Fragment-Ebene erfolgt zum Zeitpunkt des ersten Geometrie-Durchlaufs, so dass immer noch zusätzliche Kosten für andere Stufen anfallen, aber es ermöglicht den Rückgriff auf das Standard-Forward-Rendering. Außerdem können Sie die Shadingarbeit zwischen Texel Shading und Pixel Shading aufteilen.
Eine Information, die man wissen sollte, ist, dass wir tatsächlich 8×8 Kacheln von Textilien beschatten. Wir haben eine Art Cache, der einen Eintrag pro Kachel hat, den wir verwenden, um redundante Kabelschattierungen zu eliminieren, sowie eine Altersverfolgung für Techniken, die Shadings aus früheren Frames verwenden.
Das zweite ist, dass wir Vertex-Attribute im Compute-Shader interpolieren müssen. Dazu haben wir eine Map, die wir „Triangle Index Textur“ nennen, mit der wir bestimmen, welches Triangle wir für das Shading eines bestimmten Texels benötigen.
Die Nachteile.
Das allein bringt ihnen keinen Nutzen. Tatsächlich entstehen zusätzliche Kosten auf verschiedene Weise:
- Fügt einen zusätzlichen Geometriepass hinzu, obwohl er mit einem anderen Geomtriepass oder mit dem letzten Durchgang des vorherigen Frames kombiniert werden kann.
- Die Anzahl der Schatten beginnt höher. In unseren Experimenten sind es je nach Modell 20% bis 100% mehr Farbtöne. Eine Ursache ist, dass wir die Auflösung konservativ wählen, um mindestens die Pixelrate zu erreichen. Dies liegt auch daran, dass wir tatsächlich mit 8×8 Kacheln arbeiten, so dass einige Texte schattiert sind, wenn nur eine Teilmenge der 8×8 Texte in der richtigen Auflösung sichtbar ist. Hinweis: Ich habe den Begriff „Start“ verwendet. Das liegt daran, dass wir im nächsten Abschnitt nach Möglichkeiten suchen werden, dies zu reduzieren.
- Der Overhead des Shadings bei der Berechnung. Vertex-Operationen werden auf Per-Texel-Operationen verschoben. Aus diesem Grund ist es wichtig, die Verwendung von Preskinned Vertices in Betracht zu ziehen. Auch Baryzentrik und Interpolation im Shader-Code müssen Sie selbst berechnen. Auch hier gibt es noch ungenutztes Potenzial – mit Compute haben Sie expliziten Zugriff auf Nachbarinformationen und die Möglichkeit, die Shadingkosten über die Texel-Kachel zu verteilen.
- Speicherkosten. Unsere Methode erfordert eine Zuweisung von genügend Texturspeicher, um schattierte Ergebnisse und die Triangle Index Textur in einer ausreichend hohen Auflösung zu speichern.
- Probleme beim Filtern. Wir haben nur mit Bilinear-Punkt-Filterung experimentiert. Das ist nicht unbedingt gut genug für einen endgültigen Farbton. In der Tat ist es möglich, eine viel intelligentere Filterung durchzuführen, die dies zu einem Vorteil macht. Am Ende aber muss alles, was im Textur Space gemacht wird, durch die Texturfilterung gehen, was alles andere als ideal ist.
Vorteile und Potenzial.
Sobald Sie jedoch einen solchen Object Space gerendert haben, eröffnen sich neue Möglichkeiten. Wir werden einige von ihnen in diesem Abschnitt auflisten. Die ersten Beiden und ein wenig von dem Dritten, sind das, was wir bisher ausprobiert haben. Den Rest werden wir in Zukunft ausprobieren.
- Frames überspringen. Da das Shading im Object Space erfolgt, ist es einfacher, die zeitliche Shadingrate zu ändern. Unsere Implementierung verwendet einen Cache, der angibt, wie alt die Shadings sind und verwendet die Shadings von früheren Bildern wieder, wenn sie nicht zu alt sind.
- Variable und mehrstufige Shadings. Es gibt keinen Grund, warum die Auswahl der Mipmap-Ebene an die Pixelrate angepasst werden muss – Sie können für ein besseres Shader-Antialiasing höher oder für Regionen mit niedriger Varianz für eine stark reduzierte Shadingrate niedriger wählen und diese Wahl kann für jedes Fragment getroffen werden. Wir experimentierten mit der Vorspannung der Mipmap-Ebene pro Dreieck, indem wir die normale Varianz und die Vorspannung der Mipmap-Ebene für Beleuchtungsberechnungen prüften, wenn das Dreieck relativ flach war. Es ist auch möglich, für das gleiche Fragment tatsächlich mit unterschiedlichen Geschwindigkeiten zu schattieren – in gewisser Weise haben wir dies getan, indem wir nur die Beleuchtung im Texture Space berechnet und eine Textursuche mit Fragmentgeschwindigkeit durchgeführt haben – aber die Arbeit hätte weiter aufgeteilt werden können, um verschiedene Teile mit unterschiedlichen Auflösungen zur gleichen Zeit zu berechnen.
- Entkoppelte Geometrie. In einem Vorwärts-Renderer sinkt die Shadingseffizienz bei kleinen Dreicken schnell und wird mit Multisampling Anti-Aliasing (MSAA) schlechter, wenn Samples in einem Pixel von mehr als einem Dreieck bedeckt sind. Das Texel-Shading leidet an keinem dieser Probleme, da die Shadingrate an die Texelshadingrate gebunden ist. Wir haben Fälle gefunden, in denen Texel-Shading das Standard-Forward-Rendering übertrifft, bevor wir sogar Frames überspringen oder die Shadingrate ändern konnten. Aber hier gibt es eigentlich mehr Möglichkeiten. Die für das Shading verwendete Geometrie kann sogar völlig anders sein als die Dreiecke, die im Bildschirmbereich gerastert sind. Sie können auch auf verschiedenen Mipmap-Ebenen unterschiedlich sein. Dies bietet zusätzliche Möglichkeiten für geometrisches Anti-Aliasing, die wir noch nicht erforscht haben.
- Object Space, zeitliches Anti-Aliasing. Anstatt Frames zu überspringen, um Shadingkosten zu sparen, könnte man stattdessen jeden Frame schattieren und in Shadings von vorherigen Frames mitteln, wie es beim temporären Screen Space Anti-Aliasing gemacht wird. Die Durchführung dieser Operation im Object Space vermeidet einige Artefakte und Workarounds, die für das temporäre Anti-Aliasing im Screen Space notwendig sind.
- Stochastische Effekte. Ein attraktives Feature des Object Space Shading ist, dass Sie Shadings wiederverwenden können, während Sie Schärfentiefe oder Motion Blur anwenden, ohne sich Gedanken über die Artefakte des Bildschirms machen zu müssen. Tatsächlich war dies eine wichtige Motivation für das Reyes-Rendering-System. Es gibt auch Methoden, um die richtige Mipmap-Vorspannung zu finden, um Shadings beim Rendern eines verschwommenen Objekts zu speichern. Diesen Punkt haben wir noch nicht untersucht.
- Bessere Filterung. Shadings im Object Space, im Compute, wo wir Zugriff auf benachbarte Texte haben und in einer Art Multi-Resolution-Space, eröffnen sich weitere Möglichkeiten der Shader-Filterung. Wir haben das nicht so sehr erforscht, wie wir es und wünschen.
- Asynchrones Shading und Lighting. Das war eigentlich die ursprüngliche Motivation für diese Forschung. Das Überspringen von Frames ist ein einfacherer erster Schritt. Wenn Sie jedoch ein Rückfallsystem für Shadings haben, die nicht rechtzeitig fertig sind, können Sie die Shadings möglicherweise vollständig asynchron berechnen, während Sie die Projektion des Modells auf dem Bildschirm immer noch mit voller Geschwindigkeit aktualisieren, unabhängig vom letzten Shadingwert. Dies ist ein weiterer Bereich, den wir erforschen möchten.
- Stereo- und andere Multiview-Szenarien. Es ist auch möglich, Shadingberechnungen über die Augen für VR wiederzuverwenden, mit dem Vorbehalt, dass viele Spiegeleffekte möglicherweise nicht gut funktionieren. Mit asynchronem Shading oder Lighting können Sie das Shading sogar über ein Netzwerk von einzelnen Benutzern, die dieselben Szenen betrachten, wie z.B. ein Multiplayer-Spiel, gemeinsam nutzen.
Integration in bestehende Engines.
Wir sind nicht die Ersten, die so etwas versuchen. Die Nitrous-Engine verwendet zum Beispiel eine Textur-Space-Shading-Technik, die für die von ihnen angepeilten Real Time Strategy (RTS)-Spiele geeignet ist. Sie müssen sich nicht so sehr um Objekte kümmern, die sich über Mipmap-Ebenen oder verdeckte Texte erstrecken und so haben sie einen anderen Ansatz gewählt.
Texel Shading passt natürlicher in einen Forward Rendering Pass als in einen Deferred (soweit ich darüber nachgedacht habe – obwohl man auch Deferred Texture Space Shading machen könnte). Es erfordert, dass das Objekt eine eindeutige Texturparametrierung hat, wie es oft bei einer Lightmap der Fall ist. Es benötigt auch Platz für die Textur der schattierten Ergebnisse und die Wahl, wie hoch die Auflösung sein soll. Dies hängt davon ab, wie die Textur verwendet werden soll – nicht alle Shadings müssen im Textur Space vorgenommen werden.
Wenn es Texturen gibt, die die eindeutige Parametrisierung nicht verwenden, werden zusätzliche Ableitungen für die Suche auf Mipmap-Ebene benötigt. Dies füllt im Grunde genommen die Funktion der Screenspace-Derivate im Standard-Midmapping aus, versucht aber stattdessen, die Rate der zweiten Textur mit der ersten zu vergleichen. Da die Abbildung von einem UV-Satz auf den anderen jedoch tendenziell fest bleibt, kann sie möglicherweise vorberechnet werden.
Was die Engineintegration angeht, würde es die Fähigkeit erfordern, den Index und den Vertex-Puffer des Objekts während eines Compute-Shader-Passes zu binden, vorzugsweise einen Vertex-Puffer, der aus Performance-Gründen bereits gehäutet ist. Alternativ können Sie auch alles vorinterpolieren, was sich nicht dynamisch ändert, aber mehr Speicher kostet und nicht von uns ausprobiert wurde.
Die Übernahme von Texel Shading erfordert keine Alles-oder-nichts-Wahl. Sie können es auf ein einzelnes Objekt anwenden. Sie können sogar eine Auswahl pro Fragment innerhalb dieses Objekts treffen.
Schlußfolgerungen.
Wir haben einen Weg beschrieben, wie man mit Direct3D 11-Hardware Object Space Shadings durchführen kann. Es ist ein Textur Space Ansatz, verwendet aber eine Kamera-Rasterung, um bei der Okklusion und der Auswahl der richtigen Mipmap-Ebene für eine bestimmte Ansicht zu helfen. Wir haben einige Möglichkeiten erforscht, die Shaderlast durch räumliche und zeitliche Entkopplung der Shading-Rate zu reduzieren, aber es gibt noch viel mehr zu erforschen.