So rendern Sie den Rahmen von Mittelerde: Schatten von Mordor


Mittelerde: Shadow of Mordor wurde 2014 ins Leben gerufen. Das Spiel selbst war eine große Überraschung, und die Tatsache, dass es ein Spin-off der Handlung des Universums Lord of the Ring war, war ziemlich unerwartet. Das Spiel war sehr erfolgreich und zum Zeitpunkt des Schreibens hat Monolith bereits eine Fortsetzung veröffentlicht - Shadow of War. Die Grafiken des Spiels sind sehr schön, besonders wenn man bedenkt, dass es für verschiedene Konsolengenerationen veröffentlicht wurde, einschließlich der Xbox 360 und PS3. Die PC-Version ist ziemlich gut poliert, enthält zusätzliche Grafikoptionen und hochauflösende Texturpakete, die das Potenzial des Spiels voll ausschöpfen.

Das Spiel verwendet den relativ neuen DX11-Renderer. Ich habe Renderdoc verwendet , um die Rendering-Techniken des Spiels gründlich zu lernen. Bei der Arbeit wurden die maximal möglichen Grafikparameter (Ultra) verwendet und alle möglichen „Lotionen“ einbezogen, z. B. Transparenz unabhängig von Reihenfolge, Tessellation, Okklusion im Bildschirmbereich und verschiedene Bewegungsunschärfen.

Rahmen


Hier ist ein Rahmen, den wir analysieren werden. Der Spieler befindet sich auf einer Holzplattform in der Region Udun. Shadow of Mordor verwendet eine ähnliche Mechanik wie Spiele wie Assassin's Creed, bei der Sie Gebäude und Türme besteigen und dann die umgebende digitale Landschaft von den Dächern aus genießen können.

Bild

Tiefenpassage


Die ungefähr 140 ersten Renderaufrufe führen einen kurzen vorläufigen Durchgang durch, um die größten Höhenelemente und Gebäude in den Tiefenpuffer zu rendern. Die meisten Objekte fallen nicht in diesen vorläufigen Durchgang, aber es hilft, wenn das Spiel eine sehr große Anzahl von Draw Calls hat und Sie weit in die Ferne schauen können. Interessanterweise fällt ein Charakter, der sich immer in der Mitte des Bildschirms befindet und einen anständigen Teil des Bildschirmraums einnimmt, nicht in diese Passage. Wie in vielen anderen Open-World-Spielen verwendet die Engine die inversen z-Werte. Diese Technik bindet die nahe Ebene an 1,0 und die ferne Ebene an 0,0, um die Genauigkeit bei großen Entfernungen zu erhöhen und Z-Konflikte zu verhindern. Lesen Sie hier mehr über die Genauigkeit von Z-Puffern.

Bild

G-Puffer


Unmittelbar danach beginnt der G-Puffer-Durchlauf, der in ungefähr 2700 Draw-Aufrufen ausgeführt wird. Wenn Sie meine vorherige Analyse von Castlevania: Lords of Shadow 2 gelesen oder andere ähnliche Artikel studiert haben, sollte Ihnen diese Passage bekannt sein. Die Eigenschaft der Oberflächen wird in einer Reihe von Puffern aufgezeichnet, die dann in den Durchgängen der Beleuchtungsberechnung gelesen werden, um die Reaktionen der Oberflächen auf Licht zu berechnen. Shadow of Mordor verwendet einen klassischen verzögerten Renderer, aber eine relativ kleine Anzahl von Renderzielen des G-Puffers wird verwendet, um dieses Ziel zu erreichen (3). Zum Vergleich: Unreal Engine in dieser Passage verwendet 5-6 Puffer. G-Puffer hat das folgende Schema:

Normaler Puffer

R.G.B.A.
Normal.xNormal.yNormal.zID

Der Normalenpuffer speichert Normalen im Weltraum im Format „8 Bit pro Kanal“. Dies reicht kaum und manchmal gar nicht aus, um glatt variierende flache Oberflächen zu beschreiben. Wenn Sie genau hinschauen, kann dies in einigen Pfützen im Spiel gesehen werden. Der Alphakanal wird als ID verwendet, die verschiedene Objekttypen kennzeichnet. Zum Beispiel fand ich heraus, dass 255 sich auf das Zeichen bezieht, 128 auf den animierten Teil der Flagge, und der Himmel mit der ID 1 markiert ist, da diese Kennungen später verwendet werden, um ihn beim Hinzufügen zu filtern (der Himmel erhält seine eigene radiale Blüte).



Im Originalartikel sind diese und viele andere Bilder zur besseren Übersicht animiert, daher empfehle ich, dort nachzuschauen.

Puffer Albedo

R.G.B.A.
Albedo.rAlbedo.gAlbedo.bHohlraumverschluss

Der Albedopuffer speichert alle drei Komponenten der Albedo und eine kleine Okklusion (manchmal auch als Hohlraumokklusion bezeichnet), mit der kleine Details schattiert werden, die mit einer Schattenkarte oder einer Nachbearbeitung im Bildschirmbereich nicht erreicht werden können. Es wird hauptsächlich zu dekorativen Zwecken verwendet, zum Beispiel für Löcher und Falten an der Kleidung, kleine Risse in einem Baum, kleine Muster an der Kleidung von Talion usw.



Bei der Verarbeitung von Feinden im Shader berücksichtigt die Albedo die Textur des Blutes (interessanterweise bekommt Talion niemals sichtbare Wunden). Die Bluttextur ist die Eingabe für die Rendering-Phase der Kleidung und des Körpers der Feinde, gibt jedoch nicht die Farbe des Blutes an, die die Eingabe im konstanten Puffer ist, sondern bestimmt die Faktoren / Blutspiegel, um die angezeigte Blutmenge zu steuern. Außerdem wird die normale Ausrichtung verwendet, um den Effekt zu skalieren, sodass Sie die Richtung der Blutspritzer steuern können. Dann schattiert die Albedo im Wesentlichen mit der Helligkeit der Wunden, die der Feind von der entsprechenden Stelle auf der Blutkarte erhalten hat, und modifiziert auch andere Eigenschaften, wie z. B. Spiegel, um einen überzeugenden Bluteffekt zu erzielen. Ich konnte den Teil des Rahmens, in dem die Karte gerendert wird, nicht finden, aber ich gehe davon aus, dass sie direkt am Anfang des Rahmens aufgezeichnet werden, wenn das Schwert freigelegt ist, und dann hier verwendet werden.





Spiegelpuffer

R.G.B.A.
RauheitSpiegelintensitätFresnelStreufaktor unter der Oberfläche

Der Spiegelpuffer enthält andere Oberflächeneigenschaften, die in Spielen zu erwarten sind, wie z. B. die Rauheit (dies ist nicht ganz die Rauheit, sondern ein skalierter Spiegelgrad, der jedoch auf diese Weise interpretiert werden kann), die Spiegelintensität (die Helligkeit der Spiegelreflexion), die skaliert Albedo, um den richtigen Farbspiegel, den Reflektivitätsfaktor (in der Literatur allgemein als F0 bezeichnet, weil er die Eingabe für die Fresnel-Spiegelantwort ist) und die Komponente der Streuung unter der Oberfläche (Streuung unter der Oberfläche) zu erhalten. Die letztere Komponente wird verwendet, um durchscheinende Materialien wie dünnes Gewebe, Pflanzen und Haut zu beleuchten. Wenn wir später in das Studium des Licht-Shaders eintauchen, stellen wir fest, dass wir hier die Variation des normalisierten Spiegelmodells nach Blinn-Fong verwenden .





Aufgeschobene Abziehbilder

Wie wir oben gesehen haben, zeigt Shadow of Mordor ziemlich detaillierte Blutspuren an verwundeten Charakteren. Wenn Talion sein Schwert schwenkt, erhält die Umgebung auch ihren Anteil an dunklem Orkblut. Für Umgebungen wird jedoch eine andere Technik verwendet - verzögerte Abziehbilder . Diese Technik besteht darin, einen Satz flacher Texturen auf die Oberfläche des zuvor gerenderten zu projizieren. Auf diese Weise wird der Inhalt des G-Puffers vor dem Durchführen des Beleuchtungsdurchlaufs durch diesen neuen Inhalt ersetzt. Im Falle von Blut reicht nur blutiger Sprühnebel aus, und wenn viele Abziehbilder nacheinander gerendert werden, entsteht schnell eine ziemlich düstere Landschaft.












Das Letzte, was in der G-Puffer-Passage gerendert wird, ist der Himmel. Die Himmelstextur hat eine sehr hohe Auflösung (8192 × 2048) im HDR BC6H-Format. Ich musste eine kleine Tonkorrektur durchführen, da in HDR alle Farben zu dunkel sind.

Bild

Tessellation


Ein sehr interessantes „Feature“ des Spiels (wenn es aktiviert ist) ist die Tessellation. Es wird für viele verschiedene Dinge verwendet, vom Gelände bis zur Charakterwiedergabe (sowie für Requisiten und Charakterobjekte). Hier unterteilt die Tessellation das niedrige Polynetz nicht, sondern erzeugt Polygone aus einer Punktwolke unter Verwendung des erforderlichen Unterteilungsgrades, abhängig von den Kriterien für den Detaillierungsgrad, beispielsweise von der Entfernung zur Kamera. Ein interessantes Beispiel ist der Talion-Umhang, der als Punktwolke (nach der Physiksimulation) an die GPU übertragen wird, und der Tessellations-Shader erstellt die Polygone neu.



Auftragsunabhängige Transparenz



Eines der ersten Dinge, die mich an seiner Seltsamkeit beeindruckt haben, ist der Haarbehandlungspass, da er einen sehr komplexen speziellen Shader ausführt. In den Grafikoptionen wird die Option OIT (Order-Independent Transparency) für Haare erwähnt, das heißt, es sollte so sein. Zunächst wird die Ausgabe in einen separaten Puffer ausgeführt und die Gesamtzahl der überlagerten transparenten Pixel berechnet, während Eigenschaften in einer „tiefen“ Struktur ähnlich einem G-Puffer gespeichert werden. Später sortiert ein anderer Shader einzelne Fragmente nach ihrer Tiefe. Es scheint, dass die Pfeile auch auf diese Weise gerendert werden (wahrscheinlich erfordert ihr Gefieder eine ordnungsgemäße Sortierung). Dies ist ein sehr subtiler Effekt, der keine besonderen grafischen Unterschiede hinzufügt, aber dennoch ein interessantes Detail darstellt. Hier ein einfaches Beispiel: Das Bild oben zeigt die Anzahl der überlappenden Fragmente (je roter, desto mehr Fragmente). Regelmäßige Transparenz wird weiterhin von der CPU sortiert und als traditionelles Alpha gerendert. Nur einzelne Entitäten fallen in den OIT-Pass.

Schatten von Mordor


SoM hat viele Schattenquellen. Zusätzlich zu herkömmlichen Schattenkarten dynamischer Lichtquellen verwendet SoM eine zweikanalige Umgebungsokklusion im Bildschirmbereich, eine für fast alle Objekte im Spiel erstellte Okklusion im Mikromaßstab und eine Okklusionstextur ähnlich einer Höhenkarte mit Draufsicht.

Okklusion im Bildschirmbereich


Der erste Durchgang wird unter Verwendung des Umgebungs-G-Puffers und der Spiegelokklusion im Bildschirmbereich gerendert. Der Shader selbst ist ein riesiger entfalteter Zyklus, der sowohl eine Tiefenkarte in voller Größe als auch eine zuvor reduzierte durchschnittliche Tiefenkarte abtastet und nach benachbarten Abtastwerten in einem bestimmten Muster sucht. Es verwendet eine 4x4-Quadrat-Textur, um Pseudozufallsvektoren auf der Suche nach Okklusionsquellen auszuwählen. Es wird ein verrauschter Okklusionspuffer gerendert, der dann durch eine einfache Unschärfe in zwei Durchgängen geglättet wird. Das interessanteste Merkmal hierbei ist, dass es zwei verschiedene Okklusionskanäle gibt: Einer von ihnen wird als Spiegelokklusion und der andere als diffuse Okklusion verwendet. In Standard-SSAO-Implementierungen wird ein Kanal berechnet, der für alle gebackenen Beleuchtungen gilt. Hier wird die SSAO-Karte auch zur Übertragung an den gerichteten Beleuchtungskanal gelesen, wo sie verwendet wird.



Schattenkarten

Das nächste Ereignis ist das Rendern der Schattenkarte. Da die Aktion des Spiels hauptsächlich in offenen Räumen stattfindet, werden der größte Teil des Lichts und der Schatten vom Hauptrichtungslicht aufgenommen. Hier verwenden wir die Technik der Kaskadierung von Schattenkarten (eine Variation davon sind parallel geteilte Schattenkarten ), eine ziemlich übliche Technik zum Anwenden von Schatten über große Entfernungen, die darin besteht, dieselbe Szene aus einem Blickwinkel der Lichtquelle für verschiedene Bereiche des Raums zu rendern. Normalerweise befinden sich Schattenkarten, die weit vom Abdeckungsbereich der Kamera entfernt sind, entweder in großen Entfernungen oder haben eine niedrigere Auflösung als die vorherigen. Dadurch wird die Auflösung in Bereichen, in denen Details noch nicht benötigt werden, wesentlich verringert, da die Geometrie zu weit entfernt ist. In dieser Szene rendert das Spiel drei Schattenkaskaden 4096 × 4096 (tatsächlich hat das Spiel einen Platz für vier). Die obere Kaskade befindet sich ganz in der Nähe von Talion, und die untere Kaskade enthält Berge und Objekte, die sehr weit von der Kamera entfernt sind. Bei der Arbeit mit Schatten verwendet das Spiel den gleichen Trick mit der inversen z-Koordinate wie in der Tiefenkarte. \


Schattenpuffer

Der nächste Schritt ist das Erstellen eines Schattenpuffers. Dies ist eine einkanalige Textur, die auf Okklusionsinformationen aus früheren Schattenkarten basiert und einen Schattenfaktor im Intervall [0, 1] codiert. Um eine Glätte an den Rändern zu erzielen, wird die Schattenkarte viermal mit dem Status eines speziellen bilinearen Samplers abgetastet, der vier Samples empfängt und diese mit einem bestimmten Wert vergleicht (dies wird als Percentage Close Filtering bezeichnet ). Das Abrufen mehrerer Stichproben und das Mitteln ihrer Ergebnisse wird häufig als prozentuale, engere weiche Schatten bezeichnet . Zusätzlich zum Lesen der Schattenkarte wird auch die letzte Komponente des Spiegelpuffers (dh der Streukoeffizient unter der Oberfläche) abgetastet, die mit dem „Lichtblutungsfaktor“ multipliziert wird. Es scheint notwendig zu sein, um die Schatten dieser Objekte zu beseitigen, damit etwas mehr Licht durch sie hindurchgeht.


Richtungsprojektionstextur

Eine andere Licht- und Schattenquelle ist eine Draufsichttextur, die von einer gerichteten Lichtquelle abgetastet wird. Dies ist der Farbstich, der der Farbe der gerichteten Lichtquelle hinzugefügt wird, sowie der Effekt der globalen Schattierung, der für die gerichtete Beleuchtung gilt. Es scheint, dass einige von ihnen manuell über einer automatisch generierten ebenen Beleuchtungskarte mit einer Draufsicht erstellt wurden. Es scheint, dass die Kanten der Schatten für die statische Geometrie manuell angepasst werden (möglicherweise um Konflikte mit der realen Schattenkarte zu vermeiden), und einige Teile scheinen auch von Hand leicht getönt zu sein. Wahrscheinlich ist die Aufgabe dieser Textur die kostengünstige Hinzufügung von Simulationen der Umgebungsokklusion in großem Maßstab und der globalen Beleuchtung mit Licht zusätzlich zur gerichteten Beleuchtung. Die folgenden Bilder zeigen den Farbton, die Okklusion und das Produkt beider Faktoren, wodurch wir eine Vorstellung davon bekommen, wie die endgültige Farbmaske aussieht.




Das Ergebnis aller Beleuchtungsdurchläufe wird im Renderziel des Formats R11G11B10F gespeichert. So sieht das Ergebnis aus. Ich habe eine tonale Korrektur der Ergebnisse durchgeführt, um den Effekt der gerichteten Beleuchtung auf der Ebene besser sichtbar zu machen.


Alle entfernten Berge (im obigen Bild nicht dargestellt) werden ebenfalls durch gerichtetes Licht beleuchtet, sie werden jedoch als separater Fall hervorgehoben, damit die Beleuchtung besser gesteuert werden kann. Einige sind skaliert, aber die weiter entfernten sind tatsächlich Betrüger mit geschickt erstellten Normal- und Albedokarten. Sie haben spezielle gerichtete Lichtquellen, die nur die Berge betreffen.

Statische Beleuchtung


Shadow of Mordor verwendet eine sehr speicherintensive Implementierung der statischen Beleuchtung, bei der sehr großvolumige Texturen verwendet werden. Das Bild unten zeigt drei statische Texturen für die Beleuchtungsstärke, mit der ein Teil dieses Bereichs diffus beleuchtet wird. Jedes von ihnen ist eine riesige komprimierte Textur 512x512x128 BC6H, dh sie belegen 32 MB pro Textur oder 96 MB im Allgemeinen (wir spielen mit maximalen Qualitätseinstellungen). Die Textur der Farbe gibt die Intensität an, die in das Voxel eintritt. Die anderen beiden geben die Stärke oder Größe dieser Intensität entlang aller sechs Richtungen xyz und -xyz an, und die Normalen werden verwendet, um drei Komponenten auszuwählen (positive oder negative xyz, diejenigen, die am besten mit der Normalen übereinstimmen). Nachdem wir diesen Vektor erstellt haben, nehmen wir sein Vektorprodukt durch das Quadrat der Normalen, und dies wird zum Skalierungsfaktor für die Intensität. Die Formel lautet wie folgt:



Statische Lichtvolumina rendern auch eine kubische Karte für spiegelnde Beleuchtung, die wahrscheinlich in der Mitte des SLV erfasst wird. Interessanterweise speichern Volumentexturen HDR-Werte, die in BC6H komprimiert sind, und kubische Karten werden im BC3-Format (DXT5) gespeichert, in dem keine Gleitkommawerte gespeichert werden können. Um diese Einschränkung auszugleichen, behält der Alphakanal die Helligkeit bei, die dann von 1 bis 10 skaliert. Dies ist eine etwas seltsame Entscheidung, und für mich sieht es eher nach einer Legacy-Implementierung aus. Vergessen Sie nicht, dass das Spiel für Konsolen der vorherigen Generation veröffentlicht wurde, die die neuen HDR-Texturformate nicht unterstützen.


Die folgenden Bilder zeigen die Ergebnisse „vorher und nachher“ unter Berücksichtigung der Auswirkungen des Durchschnittsbilds. Zur Visualisierung habe ich eine Tonwertkorrektur durchgeführt.




Atmosphärischer Nebel



Shadow of Mordor hat ein Wetter- und Zeitsystem, dank dessen die Sonne scheint oder Regen durch das Spiel in Mordor strömt. Dieses System wird durch die Summe der Komponenten gesteuert, und einer der wichtigsten ist Nebel. Shadow of Mordor verwendet ein ziemlich einfaches, aber physikalisch einwandfreies Modell des atmosphärischen Nebels, einschließlich der einzelnen Rayleigh- Streuung sowie der Streuung durch ein kugelförmiges Teilchen (Mie-Streuung).

Zunächst wird die Position der Kamera relativ zum Erdmittelpunkt berechnet. Verschiedene trigonometrische Formeln ermöglichen es zu bestimmen, wo sich die Kamera in der Atmosphäre befindet, wo sich das Pixel befindet und welche Entfernung der Strahl in der Atmosphäre bei einer bestimmten maximalen atmosphärischen Höhe zurücklegt. In unserem Fall befindet sich die Atmosphäre in einer Höhe von 65.000 Metern über der Oberfläche des Planeten. Unter Berücksichtigung dieser Informationen werden Rayleigh- und sphärische Partikelkoeffizienten verwendet, um sowohl die Arten der Dichte der Nebelpartikel als auch ihre Farben zu berechnen. Diese Dichten verdecken die bereits schattierten Pixel, streuen Licht, das von der schattierten Oberfläche in die Kamera eintritt, und tragen zum Nebel bei. Bei der Simulation einer solchen Streuung werden Helligkeit und Richtung der Sonne berücksichtigt.



Verschlusszeit- und Tonkorrektur


Bei der Berechnung der Verschlusszeit wird ein ziemlich standardmäßiger Ansatz verwendet: Reduzieren der Auflösung des aus dem HDR-Hauptfarbpuffer berechneten Helligkeitspuffers nacheinander in eine Kette von Texturen, von denen jede halb so groß wie die vorherige Textur ist, beginnend mit einer Textur 1/3 des Hauptbildpuffers. Mit dieser Verringerung der Auflösung werden 4 Abtastwerte entnommen, wobei die Werte benachbarter Pixel gemittelt werden, dh nachdem alle Durchschnittswerte in ein einzelnes Texel umgewandelt wurden, wird das Endergebnis zur durchschnittlichen Helligkeit. Nachdem die Textur die Größe von 16 × 9 Texeln erreicht hat, wird ein Compute Shader gestartet, der alle verbleibenden Texel zusammenfasst. Dieser Wert wird sofort im Tonkorrekturdurchlauf gelesen, um die Helligkeitswerte zu ändern.







Für die Tonkorrektur wird der Reinhardt-Operator verwendet, dessen optimierte Formel hier und hier zu finden ist . Im hlsl-Code sieht dies folgendermaßen aus:

float3 hdrColor = tex2D(HDRTexture, uv.xy); hdrColor *= exposureValue; // This was calculated by the compute shader in the luminance downsampling pass float3 x = max(0.0, hdrColor - 0.004); float3 finalColor = (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06); 

Wenn wir diese Kurve zeichnen, werden wir sehen, dass dieser Operator 10% der Weißwerte auch bei einem Eingabewert von 2,0 verwirft und gleichzeitig einen kleinen Teil des unteren Intervalls zwangsweise vollständig schwarz lässt. Dies erzeugt ein entsättigtes, dunkles Bild.

Bild

Alpha Stage


Der Alpha-Schritt ist etwas ungewöhnlich, da er Objekte direkt in den LDR-Puffer rendert. Andere Spiele rendern sie ebenfalls im HDR-Puffer, damit sie am Verschluss teilnehmen können. Wie dem auch sei, die zuvor berechnete Helligkeitstextur ist auf alle Alpha-beleuchteten Objekte beschränkt (in einigen Fällen wird beispielsweise bei lichtemittierenden Objekten die Verschlusszeit anhand der Shader-Konstanten und nicht anhand der Textur-Suche berechnet), und daher wird die Verschlusszeit beim Rendern automatisch angewendet nicht in der Nachbearbeitung durchgeführt. Ein sehr spezieller Fall der Verwendung von Alpha in einem Spiel ist der Übergang in den Geistermodus (darin wird der Geist von Celebrimbor über dem Charakter des Spielers gerendert, der in den souveränen Ringen des LOTR-Universums geschmiedet ist. Das Spiel zeigt also, dass er immer in der Nähe ist, obwohl er unsichtbar ist). Das Spiel übergibt mehrere Parameter an die Maschen beider Charaktere, die die Deckkraft steuern und es dem Spiel ermöglichen, Talion teilweise zu verdecken und nach und nach Celebrimore zu zeigen. Andere Objekte im Spiel im Geistermodus rendern ebenfalls Geisterversionen über undurchsichtigen Objekten wie Feinden und Türmen. Hier ist eine weitere Szene mit dem Übergang in die Geisterwelt.





Regen


Im Hauptrahmen, den wir untersucht haben, gibt es keinen Regen, aber das Wetter ist ein so wichtiger Teil des Spiels, dass ich es hier erwähnen möchte. Es wird in der GPU generiert und simuliert und direkt am Ende der Alpha-Phase gerendert. Es wird ein Compute-Shader ausgeführt, der die Simulation ausführt und die Positionen in den Puffer schreibt. Diese Positionen werden von einem anderen Shader eingenommen, der mit Hilfe eines instanziierten indirekten Anrufs so viele Quad-Instanzen rendert, wie die Positionen im vorherigen Durchgang berechnet wurden. Der Vertex-Shader verfügt über ein einfaches Quad, das bei Bedarf verformt wird und sich in Richtung Kamera dreht. Um zu verhindern, dass Regen in die Oberflächen eindringt, liest der Vertex-Shader auch Höhenkarten aus einer Draufsicht, sodass Sie alle Tropfen unter der überlappenden Oberfläche zurückweisen können. Diese Höhenkarte wird direkt am Anfang des Rahmens gerendert. Der gleiche Vertex-Shader teilt dem Pixel-Shader mit, woher das Sample aus der Drop-Textur stammt. Befindet sich der Tropfen nahe an der Oberfläche, wird ein Texturbereich ausgewählt, der eine Begrüßungsanimation enthält. Darüber hinaus führen Regentropfen Nebelberechnungen im Pixel-Shader durch, um sich nahtlos in den Rest der Szene einzufügen. Hier ist ein Screenshot aus derselben Perspektive an einem regnerischen Tag.



Wenn der Regeneffekt aktiviert ist, wird der Spiegelpuffer global geändert, um nasse Oberflächen zu erzeugen, und Regenwellen werden in den normalen Puffer gerendert. Die Animation ist zeitgesteuert, sodass nur ein Frame der geloopten Animation verwendet wird. Der unten gezeigte normale Puffer wird geändert, um in den Puffer gerenderte Wellen anzuzeigen.





Linseneffekte und Blüte


Nach Abschluss des Alpha-Renderings werden darüber Linseneffekte gerendert. Eine Reihe von verschobenen Quads wird ab dem Punkt gerendert, von dem das gerichtete Licht kommt (in unserem Fall die Sonne). Unmittelbar danach wird ein Bloom Pass durchgeführt. Dies ist eine ziemlich Standardtechnik, die aus einer Reihe von verkleinerten und verschwommenen Texturen besteht, die Pixel enthalten, deren Helligkeit einen bestimmten Schwellenwert überschreitet. Es werden zwei Bloom-Durchgänge verwendet, die mit der Gaußschen Unschärfe für die gesamte Szene und einer speziellen radialen Unschärfe, die nur für den Himmel gilt, üblich sind. Radiale Unschärfe ist eine der Operationen, bei denen eine spezielle ID aus dem G-Puffer normaler Karten verwendet wird, da nur Pixel am Himmel berücksichtigt werden. Als Bonus wird durch diese Unschärfe die Tiefenkarte abgetastet und es können kostengünstige Dämmerungsstrahlen erzeugt werden . Da wir zu diesem Zeitpunkt mit einem LDR-Puffer arbeiten, unterscheidet sich der Wert der Blütenschwelle vom Wert des HDR-Teppichs (Werte über der Schwelle, normalerweise 1,0, führen zur Berechnung), und dies bedeutet, dass der Wert der daraus erhaltenen Blüte geringfügig begrenzt ist. In jedem Fall ist dies gut für das Spiel und hier sind die Ergebnisse. In den folgenden Bildern sehen die Farben der Bloom-Mip-Textur etwas seltsam aus, da jedes Pixel durch die im Alphakanal enthaltene Helligkeit skaliert wird. Diese Helligkeit wurde früher im Stadium der Tonwertkorrektur berechnet. Beim endgültigen Zusammensetzen wird Bloom als bloom.rgb · bloom.a · bloomScale berechnet .
















Antialiasing + Schärfentiefe


Zu diesen beiden Operationen gibt es nicht viel zu sagen, es werden branchenübliche Ansätze verwendet. Ein einfacher Durchgang durch das FXAA-Antialiasing wird unmittelbar nach dem Zusammenstellen der Blüte mit dem LDR-Bild durchgeführt, und die Schärfentiefe wird unmittelbar danach durchgeführt. Für die Schärfentiefe rendert das Spiel zwei verminderte verschwommene Versionen des endgültigen Puffers. Dann wird die Pixeltiefe verwendet, um verschwommene und normale Bilder zu mischen, was den Effekt der Defokussierung ergibt. Aus Gründen der Klarheit habe ich in dieser Aufnahme den Effekt der Schärfentiefe übertrieben. Das Spiel verfügt über einen integrierten Screenshot-Modus, mit dem Sie diese Bedingungen einfach konfigurieren können.








Bewegungsunschärfe


Bewegungsunschärfe besteht aus zwei Durchgängen. Zunächst werden Daten aus der vorherigen und der aktuellen Kameraausrichtung in den Vollbild-Geschwindigkeitspuffer übertragen. In diesem Fall werden zwei Kanäle der Textur im Bildschirmbereich mit Geschwindigkeit gefüllt. Nun enthält Kanal r die Größe der Pixeländerung in horizontaler Richtung des Bildschirms, und Kanal g enthält die Größe in vertikaler Richtung. Auf diese Weise werden beim Bewegen der Kamera radiale Streifen erhalten. Der Charakter wird erneut gerendert und füllt diesmal den blauen Kanal basierend auf seinen aktuellen und vorherigen Posen, wie dies bei der Kamera der Fall ist. Der blaue Kanal wird verwendet, um zu markieren, ob das Rendern gerendert werden soll oder nicht. Der Alphakanal ist ebenfalls mit einem konstanten Wert (0,0598) gefüllt, aber ich habe seinen Wert oder seine Ziele nicht untersucht. Die Geschwindigkeitspufferauflösung wird durch Mitteln über einen relativ großen Geschwindigkeitsbereich in der ursprünglichen Textur auf eine sehr kleine Textur reduziert. Im letzten Durchgang gibt dies jedem Pixel eine ungefähre Vorstellung davon, wie der Unschärferadius in einem echten Unschärfedurchgang sein wird.

Dann liest der Unschärfepass beide Geschwindigkeitstexturen, eine Tiefenkarte, den ursprünglichen Farbpuffer und die Rauschtextur. Letzteres wird verwendet, um den Effekt eines Spiegelbildes zu verbergen, der bei dieser Art von Unschärfe mit großem Radius auftreten kann. Dann wird der Bildpuffer mehrmals in der durch den Geschwindigkeitspuffer angegebenen Richtung abgetastet, die Farben werden gemittelt, was zu einer Unschärfe des Bildes in Richtung der Bewegungsvektoren führt. Außerdem wird dieser Effekt entsprechend der Bildrate skaliert, mit der das Spiel arbeitet. Für diese Aufnahme musste ich das Spiel auf 30 fps beschränken, da dies bei 60 fps und darüber kaum spürbar ist.





Farbkorrektur


Der letzte Durchgang der Farbkorrektur wird mit den „Farbwürfeln“ durchgeführt. Ein Farbwürfel ist eine 3D-Textur, deren RGB-Komponenten an den xyz-Koordinaten der Textur ausgerichtet sind. Diese xyz-Koordinaten enthalten die Farbe, durch die die ursprüngliche Farbe ersetzt werden muss. In unserem Fall ist die Nachschlagetabelle (LUT) neutral (d. H. Die Koordinaten und die Farbe enthalten denselben Wert), daher habe ich dieselbe Szene mithilfe der Voreinstellungen geändert, die das Spiel im Kamera-Editor bereitstellt.





Letzter Rahmen


Nach der Erstellung des Hauptrahmens in einem separaten Puffer wird die Benutzeroberfläche gerendert. Dies stellt sicher, dass unabhängig von der für den hinteren Puffer ausgewählten Größe die Benutzeroberfläche in der nativen Fenstergröße immer klar und schön dargestellt wird, während das Spiel die Auflösung bei Bedarf ändern kann, um die Geschwindigkeit sicherzustellen. Am Ende werden beide Texturen basierend auf den Alpha-Kanaldaten der Benutzeroberfläche zusammengemischt und dann in den endgültigen Bildpuffer gerendert, der zur Anzeige auf dem Bildschirm bereit ist.



Ich hoffe, Ihnen hat meine Analyse gefallen. Ich möchte Adrian Correge für die großartige Arbeit danken, die mich zum Studium der Grafik inspiriert hat, sowie den Mitarbeitern des Monolith- Studios für dieses wirklich unvergessliche Spiel.

Source: https://habr.com/ru/post/de430518/


All Articles