So funktioniert das Rendern von 3D-Spielen: Licht und Schatten

Die Implementierung der meisten visuellen Effekte in modernen Spielen hängt vom umsichtigen Einsatz von Licht und Schatten ab. Ohne sie wären Spiele langweilig und leblos. Im vierten Teil der Analyse des Renderns von 3D-Spielen konzentrieren wir uns auf das Geschehen in der 3D-Welt sowie auf die Vertex-Verarbeitung und das Textur-Mapping. Wir werden wieder viel Mathematik sowie ein solides Verständnis der Grundlagen der Optik brauchen.

Teil 1: Vertex-Verarbeitung

Teil 2: Rasterisierung und Raytracing

Teil 3: Texturieren und Filtern von Texturen

Erinnern Sie sich an die Vergangenheit


Zuvor haben wir die wichtigsten Aspekte des Verschiebens und Verarbeitens von Objekten in Szenen, ihre Umwandlung vom dreidimensionalen Raum in ein flaches Pixelraster sowie Möglichkeiten zum Überlagern von Texturen auf diesen Objekten untersucht. Seit vielen Jahren sind solche Vorgänge ein wesentlicher Bestandteil des Renderprozesses, und wir können dies sehen, indem wir 1993 zurückkehren und id Software's Doom starten.


Nach modernen Maßstäben war die Verwendung von Licht und Schatten in diesem Spiel sehr primitiv: Die Lichtquellen wurden nicht berücksichtigt, jede Oberfläche, basierend auf ihren Eckpunkten, erhielt einen allgemeinen Farbwert oder den Wert des Umgebungslichts . Alle Zeichen von Schatten wurden dank der gerissenen Verwendung von Texturen und der Wahl der Farbe der Umgebung erzeugt.

Es gab keine Schatten, weil sie nicht die Aufgabe von Programmierern waren: Der damalige PC war ein 66-MHz-Prozessor (dh 0,066 GHz!), Eine 40-MB-Festplatte und eine 512-Kilobyte-Grafikkarte mit minimalen 3D-Fähigkeiten. Schneller Vorlauf 23: Beim berühmten Neustart der Serie sehen wir eine ganz andere Geschichte.


Es wurden viele Technologien verwendet, um diesen Rahmen zu rendern . Er verfügt über Stufen wie die Okklusion des Bildschirmraums, die Tiefenabbildung vor dem Durchgang, Bokeh-Unschärfefilter, Tonkorrekturoperatoren usw. Die Berechnung der Beleuchtung und Schattierung jeder Oberfläche erfolgt dynamisch: Sie ändern sich ständig in Abhängigkeit von den Umgebungsbedingungen und den Aktionen des Spielers.

Da für jede 3D-Rendering-Operation Mathematik erforderlich ist (eine ganze Reihe von Berechnungen!), Beginnen wir besser mit dem, was hinter den Kulissen eines modernen Spiels passiert.

Mathe Beleuchtung


Um alles richtig zu implementieren, müssen wir das Verhalten von Licht bei der Interaktion mit verschiedenen Oberflächen genau simulieren. Es ist merkwürdig, dass dieses Problem zum ersten Mal im 18. Jahrhundert von einem Mann namens Johann Heinrich Lambert gelöst wurde.

1760 veröffentlichte ein Schweizer Wissenschaftler ein Buch namens Photometria . Darin skizzierte er die Grundregeln des Verhaltens von Licht; Das bemerkenswerteste davon war das Folgende: Die Oberfläche emittiert Licht (durch Reflexion oder als Lichtquelle) so, dass sich die Helligkeit des emittierten Lichts in Abhängigkeit vom Kosinus des Winkels zwischen der normalen Oberfläche und dem Betrachter ändert.


Diese einfache Regel legte den Grundstein für die sogenannte diffuse Beleuchtung. Dies ist ein mathematisches Modell, mit dem die Farbe einer Oberfläche in Abhängigkeit von ihren physikalischen Eigenschaften (z. B. ihrer Farbe und dem Grad der Lichtreflexion) und dem Ort der Lichtquelle berechnet wird.

Beim 3D-Rendering sind viele Informationen erforderlich, die sich in Form eines solchen Schemas am einfachsten vorstellen lassen:


Wir sehen viele Pfeile im Bild, dies sind Vektoren , und die folgenden Vektoren sind erforderlich, um die Farbe zu berechnen:

  • 3 Vektoren für Scheitelpunktposition, Lichtquelle und Kamera, die die Szene betrachten
  • 2 Vektoren für die Richtungen der Lichtquelle und der Kamera aus Sicht des Scheitelpunkts
  • 1 normaler Vektor
  • 1 Halbvektor (er befindet sich immer in der Mitte zwischen den Richtungsvektoren der Beleuchtung und der Kamera)

Sie werden in der Phase der Verarbeitung der Eckpunkte des Renderprozesses berechnet, und die Gleichung, die sie alle vereint (Lambert-Modell genannt), hat folgende Form:


Das heißt, die Farbe des Scheitelpunkts unter diffusem Licht wird berechnet, indem die Farbe der Oberfläche, die Farbe der Lichtquelle und das Skalarprodukt der Normalenvektoren des Scheitelpunkts und die Lichtrichtung mit den Dämpfungs- und Projektionsbeleuchtungskoeffizienten multipliziert werden. Diese Operation wird für jede Lichtquelle in der Szene ausgeführt, daher das Summensymbol am Anfang der Gleichung.

Die Vektoren in dieser Gleichung (und alles, was wir unten sehen) werden normalisiert (wie durch die Symbole über jedem Vektor gezeigt). Der normalisierte Vektor behält seine ursprüngliche Richtung bei und seine Länge nimmt auf einen Einheitswert ab (d. H. Gleich 1 Maßeinheit).

Die Farbwerte der Oberfläche und der Lichtquelle sind Standard-RGBA-Zahlen (Rot-, Grün-, Blau- und Alphatransparenz). Sie können ganzzahlig sein (z. B. INT8 für jeden Farbkanal), sind jedoch fast immer Gleitkommazahlen (z. B. FP32). Der Dämpfungskoeffizient bestimmt, wie der Beleuchtungsgrad abnimmt, wenn er sich von der Quelle entfernt, und wird durch eine andere Gleichung berechnet:


Die Begriffe A C , A L und A Q sind verschiedene Koeffizienten (konstant, linear, quadratisch), die beschreiben, wie sich der Abstand auf das Beleuchtungsniveau auswirkt. Alle werden von Programmierern beim Erstellen einer Rendering-Engine festgelegt. In jeder grafischen API wird dies auf ihre eigene Weise implementiert, aber beim Codieren des Lichtquellentyps werden Koeffizienten eingeführt.

Bevor wir den letzten Koeffizienten (Flutlicht) betrachten, ist anzumerken, dass es beim 3D-Rendering im Wesentlichen drei Arten von Lichtquellen gibt: Punkt-, Richtungs- und Scheinwerferlicht.


Punktquellen senden gleichmäßig Licht in alle Richtungen aus, und Richtungsquellen senden Licht nur in eine Richtung aus (aus mathematischer Sicht ist dies nur eine Punktquelle, die in unendlicher Entfernung entfernt ist). Scheinwerfer sind komplexe Richtungsquellen, da sie Licht in Form eines Kegels emittieren. Die Art und Weise, wie Licht im Körper des Kegels variiert, bestimmt die Größe des inneren und äußeren Teils des Kegels.

Und ja, für den Suchscheinwerferkoeffizienten gibt es eine andere Gleichung:


Der Wert des Projektorkoeffizienten ist entweder 1 (d. H. Die Quelle ist kein Projektor) oder 0 (wenn der Scheitelpunkt außerhalb der Kegelrichtung liegt) oder ein berechneter Wert zwischen den beiden. Die Winkel φ (phi) und θ (Theta) geben die Abmessungen des inneren / äußeren Teils des Kegels des Scheinwerfers an.

Zwei Vektoren: L dcs und L dir (umgekehrt zur Kamerarichtung und Scheinwerferrichtung) werden verwendet, um zu bestimmen, ob sich der Kegel des Scheitelpunkts berührt.

Jetzt sollten wir uns daran erinnern, dass all dies notwendig ist, um den Wert der diffusen Beleuchtung zu berechnen, und dass alle diese Operationen für jede ausgeführt werden müssendie Lichtquelle in der Szene oder zumindest für jede Quelle, die der Programmierer berücksichtigen wollte. Viele dieser Gleichungen werden von grafischen APIs ausgeführt, können jedoch auch manuell ausgeführt werden, wenn Encoder mehr Kontrolle über das Bild benötigen.

In der realen Welt gibt es jedoch unendlich viele Lichtquellen: Jede Oberfläche reflektiert die Beleuchtung, sodass sie alle die Gesamtbeleuchtung der Szene beeinflussen. Selbst nachts gibt es Hintergrundbeleuchtung, egal ob es sich um Sterne und Planeten oder um in der Atmosphäre gestreutes Licht handelt.

Um dies zu simulieren, wird ein anderer Beleuchtungswert berechnet: Umgebungsbeleuchtung .


Diese Gleichung ist einfacher als bei diffuser Beleuchtung, da keine Richtungen erforderlich sind. Hier wird eine einfache Multiplikation verschiedener Koeffizienten durchgeführt:

  • C SA - Oberflächenbeleuchtungsfarbe
  • C GA - Markieren Sie die Farbe der globalen 3D-Szene
  • C LA - Beleuchtungsfarbe aller Lichtquellen in der Szene

Es ist anzumerken, dass die Dämpfungs- und Projektorkoeffizienten sowie die Summe aller Lichtquellen erneut verwendet werden.

Wir haben also Hintergrundbeleuchtung und haben die diffuse Beleuchtung von Lichtquellen von verschiedenen Oberflächen der 3D-Welt berücksichtigt. Das Lambert-Modell funktioniert jedoch nur für Materialien, die das Licht von seiner Oberfläche in alle Richtungen reflektieren. Objekte aus Glas oder Metall schafft eine andere Art der Reflexion genannt hergestellt spiegelnde ; Natürlich gibt es auch für ihn eine Gleichung!


Die einzelnen Teile dieser Formel sollten Ihnen bereits bekannt sein: Wir haben zwei Werte für die Spiegelfarbe (einen für die Oberfläche - C S , den anderen für Licht - C LS ) sowie die üblichen Dämpfungs- und Flutfaktoren.

Da die Spiegelreflexion sehr fokussiert und gerichtet ist, werden zwei Vektoren verwendet, um die Helligkeit der Spiegelbeleuchtung zu bestimmen: die Scheitelpunktnormalen und der Halbvektor. Der Koeffizient p wird als Spiegelreflexionskraft bezeichnet . Dies ist eine Zahl, die die Helligkeit der Reflexion in Abhängigkeit von den Eigenschaften des Oberflächenmaterials bestimmt. Mit zunehmendem p wird der Spiegeleffekt heller, aber fokussierter und kleiner.

Das letzte zu berücksichtigende Element ist das einfachste, da es sich nur um eine Zahl handelt. Es wird als emittierende Beleuchtung bezeichnet und auf Objekte angewendet, die eine direkte Lichtquelle darstellen, dh auf eine Flamme, eine Taschenlampe oder die Sonne.

Dies bedeutet, dass wir jetzt eine Zahl und drei Gleichungssysteme zur Berechnung der Farbe des Scheitelpunkts der Oberfläche haben, wobei die Hintergrundbeleuchtung (Umgebung) sowie die Wechselwirkung zwischen verschiedenen Lichtquellen und den Eigenschaften des Oberflächenmaterials (diffus und spiegelnd) berücksichtigt werden. Programmierer können nur eine auswählen oder alle vier kombinieren, indem sie sie einfach falten.


Optisch sieht die Kombination folgendermaßen aus:


Die von uns berücksichtigten Gleichungen werden von grafischen APIs (z. B. Direct3D und OpenGL) unter Verwendung ihrer Standardfunktionen angewendet. Für jede Beleuchtungsart gibt es jedoch alternative Algorithmen. Beispielsweise kann eine diffuse Beleuchtung mit dem Oren-Nayyar-Modell implementiert werden , das für sehr raue Oberflächen besser geeignet ist als das Lambert-Modell.

Die Spiegelreflexionsgleichung kann durch Modelle ersetzt werden, die die Tatsache berücksichtigen, dass sehr glatte Oberflächen wie Glas oder Metall immer noch rau sind, jedoch auf mikroskopischer Ebene. Solche Modelle, sogenannte Mikrofacettenalgorithmen , liefern auf Kosten der mathematischen Komplexität realistischere Bilder.

Unabhängig davon, welches Modell verwendet wird, werden sie alle erheblich verbessert, indem die Häufigkeit ihrer Anwendung auf die 3D-Szene erhöht wird.

Vertex- oder Pixel-für-Pixel-Berechnungen


Bei der Untersuchung der Scheitelpunktverarbeitung und -rasterung haben wir festgestellt , dass die Ergebnisse aller kniffligen Beleuchtungsberechnungen, die für jeden Scheitelpunkt durchgeführt wurden, über die Oberfläche zwischen den Scheitelpunkten interpoliert werden sollten. Dies liegt daran, dass die mit dem Oberflächenmaterial verbundenen Eigenschaften innerhalb der Scheitelpunkte gespeichert werden. Wenn die 3D-Welt in ein 2D-Pixelraster komprimiert wird, bleiben die Pixel nur dort, wo sich der Scheitelpunkt befand.


Die restlichen Pixel müssen Informationen über die Farbe der Scheitelpunkte übertragen, damit sich die Farben auf der Oberfläche korrekt mischen. Im Jahr 1971 schlug Henri Gouraud , damals Doktorand an der Universität von Utah, eine Methode vor, die jetzt Gouraud Shading heißt .

Seine Methode war rechnerisch schnell und wurde viele Jahre lang zum De-facto- Standard, aber er hatte auch Probleme. Er konnte die Spiegelbeleuchtung nicht richtig interpolieren, und wenn das Objekt aus einer kleinen Anzahl von Grundelementen bestand, schien das Mischen zwischen den Grundelementen falsch zu sein.

Eine Lösung für dieses Problem wurde 1973 von Bui Tyong Fong vorgeschlagen, der auch an der Universität von Utah arbeitete. In seinem Forschungsartikel demonstrierte Fong eine Technik zur Interpolation der Normalen von Eckpunkten auf gerasterten Oberflächen. Dies bedeutete, dass die Streu- und Spiegelreflexionsmodelle für jedes Pixel korrekt funktionieren würden, und wir können dies deutlich in David Ecks Online- Computergrafik- und WebGL- Tutorial sehen .

Die unten gezeigten Kohlenstoffkugeln werden mit demselben Beleuchtungsmodell gefärbt, aber für linkshändige Berechnungen werden sie vertikal ausgeführt, gefolgt von einer Gouraud-Schattierung, um sie über die gesamte Oberfläche zu interpolieren. Für die Kugel rechts werden die Berechnungen Pixel für Pixel durchgeführt, und der Unterschied ist offensichtlich.


Standbilder vermitteln nicht alle Verbesserungen, die durch das Schattieren von Phong erzielt wurden , aber Sie können die Online-Demo von Ek unabhängig ausführen und die Animation ansehen.

Fong hörte hier jedoch nicht auf und veröffentlichte einige Jahre später einen weiteren Forschungsartikel, in dem er zeigte, wie getrennte Berechnungen für Umgebungsreflexion, diffuse Reflexion und Spiegelreflexion mit einer einfachen Gleichung durchgeführt werden können:


Hier müssen wir ernsthaft verstehen! Die durch den Buchstaben k angegebenen Werte sind die Reflexionskonstanten für die Umgebungs-, diffusen und Spiegelreflexionen. Jeder von ihnen ist ein Bruchteil der entsprechenden Art des reflektierten Lichts von der Größe des einfallenden Lichts; C- Werte, die wir in den obigen Gleichungen gesehen haben (Farbwerte des Oberflächenmaterials für jede Beleuchtungsart).

Der Vektor R ist der Vektor der „perfekten Reflexion“ - die Richtung, in die sich das reflektierte Licht bewegen würde, wenn die Oberfläche perfekt glatt wäre; Sie wird unter Verwendung der Oberflächennormalen und des einfallenden Lichtvektors berechnet. Vektor C ist der Kamerarichtungsvektor; und R und C sind normalisiert.

Schließlich gibt es die letzte Konstante in der Gleichung: Der Wert von α bestimmt den Grad des Oberflächenglanzes. Je glatter das Material ist (d. H. Je mehr es Glas oder Metall ähnelt), desto höher ist die Anzahl.

Diese Gleichung wird üblicherweise als Phong-Reflexionsmodell bezeichnet . Zum Zeitpunkt seiner Forschung war ein solcher Vorschlag radikal, da er ernsthafte Rechenressourcen erforderte. Eine vereinfachte Version des Modells wurde von Jim Blinn erstellt und ersetzte den Teil der Formel von R und C zu H und N (Halbabstandsvektor und Oberflächennormale). Der Wert von R muss für jede Lichtquelle und für jedes Pixel im Rahmen berechnet werden, undH reicht aus, um für jede Quelle und für die gesamte Szene einmal zu berechnen.

Das Blinn-Fong-Reflexionsmodell ist heute das Standardbeleuchtungssystem und wird standardmäßig in Direct3D, OpenGL, Vulkan usw. verwendet.

Es gibt viele andere mathematische Modelle, insbesondere jetzt, wo GPUs Pixel in langen und komplexen Shadern verarbeiten können. zusammen werden solche Formeln als bidirektionale Reflexions- / Transmissionsverteilungsfunktionen (BRDF / BTFD) bezeichnet; Sie sind die Grundlage für die Färbung jedes Pixels auf dem Monitor, wenn wir moderne 3D-Spiele spielen.

Bisher haben wir jedoch nur Oberflächen betrachtet, die Licht reflektieren : Durchscheinende Materialien lassen Licht durch, während die Lichtstrahlen gebrochen werden. Und einige Oberflächen. Beispielsweise reflektiert und lässt Wasser Licht in unterschiedlichem Maße durch.

Wir bringen die Beleuchtung auf ein neues Niveau


Schauen wir uns das Ubisoft Assassin's Creed: Odyssey- Spiel 2018 an , in dem der Spieler häufig unter Wasser segelt, sowohl in flachen Flüssen als auch in der Tiefsee.


Bemaltes Holz, Metall, Seile, Stoff und Wasser - all dies reflektiert und bricht das Licht mithilfe einer Reihe von Berechnungen.

Für die realistischste Darstellung von Wasser bei gleichbleibender Spielgeschwindigkeit verwendeten Ubisoft-Programmierer eine ganze Reihe von Tricks. Die Wasseroberfläche wird von dem bekannten Trio aus Umgebungslicht, diffusem und spiegelndem Licht beleuchtet, das jedoch durch interessante Merkmale ergänzt wird.

Die erste davon wird häufig verwendet, um die Reflexionseigenschaften von Wasser zu erzeugen - dies sind Screen Space Reflections (SSR). Diese Technik rendert die Szene, aber die Farben der Pixel hängen von der Tiefe jedes Pixels ab, d.h. aus seiner Entfernung zur Kamera. Die Tiefe wird in dem sogenannten gespeicherten Tiefenpuffer. Dann wird der Rahmen erneut mit der üblichen Beleuchtung und Textur gerendert, aber die Szene wird als Rendertextur gespeichert und nicht als fertiger Puffer, der an den Monitor übertragen wird.

Danach wird ein Strahlenmarsch durchgeführt . Dazu werden Strahlen von der Kamera ausgesendet und Entfernungen entlang des Strahlverlaufs eingestellt. Der Code überprüft die Tiefe des Strahls relativ zu den Pixeln im Tiefenpuffer. Wenn sie denselben Wert haben, überprüft der Code das normale Pixel, um festzustellen, ob es auf die Kamera gerichtet ist. In diesem Fall sucht die Engine nach dem entsprechenden Pixel aus der Rendertextur. Dann kehrt ein weiterer Befehlssatz die Position des Pixels um, so dass es korrekt in der Szene reflektiert wird.


Die SSR-Reihenfolge, die in der Frostbite-Engine von EA verwendet wird.

Zusätzlich wird Licht während der Bewegung innerhalb von Materialien gestreut, und für Materialien wie Wasser oder Leder wird ein anderer Trick verwendet, der als Untergrundstreuung (SSS) bezeichnet wird. Wir werden es nicht im Detail erklären, aber Sie können in der Nvidia-Präsentation 2014 lesen, wie es verwendet wird, um so erstaunliche Ergebnisse zu erzielen .


Nvidias FaceWorks-Demo 2013 ( Link ) Kehren

wir zu Assassins Creed Water zurück: Die SSS-Implementierung ist hier kaum erkennbar und wird aus Geschwindigkeitsgründen nicht so häufig verwendet. In früheren Spielen der AC-Serie verwendete Ubisoft gefälschtes SSS , aber im letzten Spiel ist seine Verwendung komplizierter, aber immer noch nicht so groß wie in der Nvidia-Demo.

Um die Beleuchtungswerte auf der Wasseroberfläche zu ändern, werden zusätzliche Verfahren durchgeführt, die die Auswirkungen der Tiefe aufgrund einer Änderung der Transparenz in Abhängigkeit von der Entfernung zur Küste korrekt simulieren. Und wenn die Kamera das küstennahe Wasser betrachtet, werden noch mehr Algorithmen verwendet, um Ätz- und Brechungsfaktoren zu berücksichtigen.

Die Ergebnisse sind beeindruckend:


Assassin's Creed: Odyssey - Wasser in seiner ganzen Pracht wiedergeben.

Wir haben uns Wasser angesehen, aber was ist mit der Bewegung von Licht in der Luft? Staubpartikel, Feuchtigkeit und andere Elemente führen ebenfalls zu Lichtstreuung. Infolgedessen erhalten die Lichtstrahlen Volumen und bleiben nicht nur ein Satz direkter Strahlen.

Das Thema volumetrische Beleuchtung kann auf ein Dutzend Artikel erweitert werden, daher werden wir darüber sprechen, wie das Spiel Rise of the Tomb Raider damit umgeht . Im Video unten gibt es nur eine Hauptlichtquelle - die Sonne scheint durch die Öffnung im Gebäude.


Um ein Lichtvolumen zu erzeugen, nimmt die Spiel-Engine die Sichtbarkeitspyramide der Kamera (siehe unten) und zerlegt sie exponentiell in 64 Teile. Anschließend wird jedes Slice in Raster mit einer Größe von 160 x 94 Elementen gerastert, und alle diese Daten werden in einer dreidimensionalen Rendertextur des FP32-Formats gespeichert. Da Texturen normalerweise zweidimensional sind, werden die "Pixel" des Pyramidenvolumens als Voxel bezeichnet .


Für einen 4 x 4 x 4-Voxelblock bestimmen Computershader , welche aktiven Lichtquellen dieses Volumen beeinflussen, und schreiben diese Informationen dann in eine andere dreidimensionale Rendertextur. Um die Gesamtdichte des Lichts innerhalb des Voxelblocks abzuschätzen , wird eine komplexe Formel verwendet, die als Hengy-Greenstein-Streufunktion bezeichnet wird .

Dann führt der Motor mehrere weitere Shader durch, um die Daten zu verfeinern. Danach wird ein Strahlenmarsch entlang der Scheiben der Pyramide mit der Akkumulation von Lichtdichtewerten durchgeführt. Eidos-Montréal behauptet, dass alle diese Vorgänge auf Xbox One ungefähr 0,8 Millisekunden dauern!

Obwohl diese Technik nicht in allen Spielen verwendet wird, erwarten die Spieler eine volumetrische Abdeckung in fast allen heute veröffentlichten 3D-Spielen, insbesondere in Ego-Shootern und Action-Adventure-Spielen.


Die volumetrische Beleuchtung im Rise of the Tomb Raider Fortsetzung von 2018. verwendet

Anfangs wurde diese Lichttechnik „göttlichen Strahlen“ genannt, oder, wie sie wissenschaftlich genannt werden, „Dämmerung Strahlen . Eines der ersten Spiele, in denen es verwendet wurde, war Cryteks erste Crysis , die 2007 veröffentlicht wurde.

Dies war jedoch keine echte volumetrische Beleuchtung - der Prozess umfasste das anfängliche Rendern der Szene in Form eines Tiefenpuffers, der als Maske verwendet wurde - ein weiterer Puffer, in dem die Pixelfarben dunkler wurden, je näher sie an der Kamera waren.

Dieser Maskenpuffer wurde mehrmals abgetastet, und der Shader nahm Proben und mischte sie durch Verwischen zusammen. Das Ergebnis dieser Operation wurde mit der fertigen Szene gemischt:


Der Fortschritt der Grafikkarten in den letzten 12 Jahren war enorm. Die leistungsstärksten GPUs zum Zeitpunkt der Veröffentlichung von Crysis waren die Nvidia GeForce 8800 Ultra . Die schnellste moderne GPU - die GeForce RTX 2080 Ti verfügt über mehr als 30-mal mehr Rechenleistung, 14-mal mehr Speicher und 6-mal mehr Bandbreite.

Mit all dieser Rechenleistung können moderne Spiele trotz der zunehmenden Komplexität des Renderns eine viel größere Grafikgenauigkeit und Gesamtgeschwindigkeit bieten.


„Göttliche Strahlen“ in Ubisofts The Division 2

Tatsächlich zeigt dieser Effekt jedoch, dass trotz der Bedeutung einer korrekten Beleuchtung für die visuelle Genauigkeit die Abwesenheit von Licht sogar noch wichtiger ist .

Essenz des Schattens


Beginnen wir einen neuen Abschnitt des Artikels mit dem Spiel Shadow of the Tomb Raider . In der Abbildung unten sind alle Grafikoptionen für Schatten deaktiviert. rechts sind sie enthalten. Der Unterschied ist riesig, oder?


Da sich in der realen Welt natürlich Schatten bilden, werden Spiele, in denen sie falsch implementiert sind, niemals richtig aussehen. Unser Gehirn ist es gewohnt, Schatten als visuelle Unterstützung zu verwenden, um ein Gefühl von relativer Tiefe, Position und Bewegung zu erzeugen. Aber es in einem 3D-Spiel zu machen, ist überraschend schwierig oder zumindest schwierig, es richtig zu machen.

Beginnen wir mit der Ente. Hier bewegt sie sich auf dem Feld, und die Sonnenstrahlen erreichen sie und werden korrekt blockiert.


Eine der ersten Möglichkeiten, den Schatten in der Szene zu implementieren, bestand darin, einen „Schattenpunkt“ unter dem Modell hinzuzufügen. Dies ist völlig unrealistisch, da die Form des Schattens nicht mit der Form des Objekts übereinstimmt, das den Schatten wirft. Dieser Ansatz ist jedoch schnell und einfach zu erstellen.

Die ersten 3D-Spiele, zum Beispiel der erste Tomb Raider von 1996, verwendeten diese Methode, weil die Hardware dieser Zeit, zum Beispiel Sega Saturn und Sony PlayStation, nichts Besseres bieten konnte. Diese Methode malte einen einfachen Satz von Grundelementen direkt über die Oberfläche, auf der sich das Modell bewegt, und schattierte sie dann. Es wurde auch das Zeichnen am unteren Rand einer einfachen Textur verwendet.


Eine andere der ersten Methoden war das Projizieren von Schatten . In diesem Fall wurde das einen Schatten emittierende Grundelement auf eine Ebene projiziert, die den Boden enthielt. Ein Teil der dafür notwendigen mathematischen Berechnungen wurde Ende der 80er Jahre von Jim Blinn erstellt. Nach modernen Maßstäben ist dies ein einfacher Prozess, der am besten für einfache statische Objekte geeignet ist.


Dank der Optimierung wurden durch die Schattenprojektion die ersten würdigen Beispiele für dynamische Schatten geschaffen, beispielsweise im Spiel Kingpin: Life of Crime von Interplay aus dem Jahr 1999 . Wie wir im Bild unten sehen, haben nur animierte Charaktere (sogar Ratten!) Schatten, aber dies ist besser als einfache Punkte.


Die schwerwiegendsten Probleme bei diesem Ansatz sind: (a) die perfekte Opazität des Schattens und (b) die Projektionsmethode emittiert den Schatten auf einer ebenen Fläche (z. B. auf dem Boden).

Diese Probleme können gelöst werden, indem beim Färben des projizierten Grundelements und beim Ausführen mehrerer Projektionen für jedes Zeichen ein Teil der Transparenz angewendet wird. Die PC-Hardwarefunktionen der späten 90er Jahre konnten das zusätzliche Rendering jedoch nicht bewältigen.

Moderne Technologie zur Erzeugung von Schatten


Eine genauere Methode zur Implementierung von Schatten wurde bereits 1977 viel früher vorgeschlagen. Während an der Universität von Austin (Texas) arbeitet, schrieb Franklin Crowe einen Forschungs - Artikel , in dem er mehrere Techniken vorgeschlagen Schattenvolumen .

Im Allgemeinen können sie wie folgt beschrieben werden: Der Prozess bestimmt, welche Grundelemente auf die Lichtquelle gerichtet sind; Ihre Rippen sind zu einer Ebene gespannt. Während dies der Projektion von Schatten sehr ähnlich ist, besteht der wichtige Unterschied darin, dass das erzeugte Schattenvolumen dann verwendet wird, um zu überprüfen, ob sich das Pixel innerhalb / außerhalb des Volumens befindet. Dank dieser Informationen können Schatten auf alle Oberflächen und nicht nur auf den Boden abgegeben werden.

Diese Technik wurde 1991 von Tim Heidmann verbessert, der daran arbeiteteSiliziumgrafiken . Mark Kilgard war 1999 an seiner Weiterentwicklung beteiligt , und die Methode, die wir in Betracht ziehen werden, wurde im Jahr 2000 von John Carmack von id Software entwickelt (obwohl Carmacks Methode zwei Jahre zuvor von Bilodo und Songa von Creative Labs unabhängig eröffnet wurde; dass Carmack gezwungen war, seinen Code zu ändern , um rechtliche Probleme zu vermeiden).

Dieser Ansatz erfordert das Rendern mehrerer Frames ( Multipass- Rendering genannt - ein sehr teurer Prozess in den frühen 90er Jahren, der heute überall verwendet wird) und ein Konzept namens Schablonenpuffer .

Im Gegensatz zu Bildpuffern und Tiefen wird es nicht von der 3D-Szene selbst erstellt. Dieser Puffer ist ein Array von Werten, die in allen Dimensionen (d. H. Auflösung in x und y ) in Form eines Rasters gleich sind. Die darin gespeicherten Werte werden verwendet, um der Rendering-Engine mitzuteilen, was mit jedem Pixel im Bildpuffer zu tun ist.

Das einfachste Beispiel für die Verwendung dieses Puffers ist die Verwendung als Maske:


Die Methode mit dem Schattenvolumen wird ungefähr so ​​ausgeführt:

  • Wir rendern die Szene in den Bildspeicher, verwenden jedoch nur die Umgebungsbeleuchtung (wir enthalten auch alle Emissionswerte, wenn das Pixel eine Lichtquelle enthält).
  • , , ( (back-face culling)). (, ) . (.. «») - .
  • , (front-face culling) -, .
  • , , -.

Diese Schablonenpuffer und Schattenvolumina (allgemein als Schablonenschatten bezeichnet) wurden im 2004 Doom 3 id Software-Spiel verwendet :


Beachten Sie, dass die Oberfläche, auf der der Charakter läuft, immer noch durch den Schatten sichtbar ist? Dies ist der erste Vorteil gegenüber der Schattenprojektion. Darüber hinaus können Sie mit diesem Ansatz den Abstand zur Lichtquelle berücksichtigen (wodurch schwächere Schatten erhalten werden) und Schatten auf jede Oberfläche (einschließlich des Zeichens selbst) werfen.

Diese Technik weist jedoch schwerwiegende Nachteile auf, von denen der auffälligste darin besteht, dass die Kanten des Schattens vollständig von der Anzahl der Grundelemente abhängen, die zum Erstellen des Objekts verwendet werden, das den Schatten wirft. Darüber hinaus ist Multipassing mit vielen Lese- / Schreibvorgängen in den lokalen Speicher verbunden, weshalb die Verwendung von Schablonenschatten im Hinblick auf die Leistung recht kostspielig ist.

Darüber hinaus gibt es eine Begrenzung für die Anzahl der Schattenvolumes, die mit dem Schablonenpuffer überprüft werden können, da alle Grafik-APIs eine relativ kleine Anzahl von Bits darauf zuweisen (normalerweise nur 8). Aufgrund des Rechenaufwands von Schablonenschatten tritt dieses Problem jedoch normalerweise nicht auf.

Es gibt noch ein anderes Problem - die Schatten selbst sind alles andere als realistisch. Warum? Weil alle Lichtquellen - Lampen, offene Flammen, Laternen und die Sonne - keine einzelnen Punkte im Raum sind, d.h. Sie strahlen Licht in einem bestimmten Bereich aus. Selbst im einfachsten Fall, der unten gezeigt wird, haben echte Schatten selten scharf definierte Kanten.


Die dunkelste Schattenregion wird als Vollschatten (Umbra) bezeichnet. Halbschatten ist immer ein hellerer Schatten, und die Grenze zwischen den beiden ist oft unscharf (weil es normalerweise viele Lichtquellen gibt). Es ist schwierig, dies mit Schablonenpuffern und Volumes zu modellieren, da die erstellten Schatten in einer falschen Form gespeichert werden, damit sie verarbeitet werden können. Shadow Mapping kommt zur Rettung !

Das grundlegende Verfahren wurde 1978 von Lance Williams entwickelt . Es ist ziemlich einfach:

  • Für jede Lichtquelle rendern wir die Szene aus der Sicht dieser Quelle und erstellen eine spezielle Textur der Tiefen (dh ohne Farbe, Beleuchtung, Texturierung usw.). Die Auflösung dieses Puffers muss nicht der Größe des fertigen Rahmens entsprechen, aber je höher desto besser.
  • , ( x,y z) , .
  • : , .

Dies ist natürlich ein weiteres Verfahren mit mehreren Durchgängen, aber der letzte Schritt kann mithilfe von Pixel-Shadern ausgeführt werden, sodass die Tiefenprüfung und die nachfolgenden Beleuchtungsberechnungen in einem Durchgang kombiniert werden. Und da der gesamte Prozess der Schattenerstellung nicht von der Anzahl der verwendeten Grundelemente abhängt, ist er viel schneller als die Verwendung des Schablonenpuffers und des Schattenvolumens.

Leider erzeugt die oben beschriebene grundlegende Technik alle Arten von visuellen Artefakten (z. B. perspektivisches Aliasing , „Schattenakne“ , „Peter Panning“), von denen die meisten mit der Auflösung und Bitgröße der Tiefenstruktur zusammenhängen. Alle GPUs und Grafik-APIs weisen ähnliche Einschränkungen wie Texturen auf. Daher wurde eine ganze Reihe zusätzlicher Techniken entwickelt, um diese Probleme zu lösen.

Einer der Vorteile der Verwendung von Texturen für Tiefeninformationen besteht darin, dass GPUs sie sehr schnell und auf viele verschiedene Arten abtasten und filtern können. Im Jahr 2005 demonstrierte Nvidia eine Texturabtastmethode, mit der einige der visuellen Probleme gelöst werden können, die durch Standardschatten verursacht werden. Außerdem sorgte er für ein gewisses Maß an Glätte der Schattenkanten; Diese Technik wird als prozentuale Nahfilterung bezeichnet .


Etwa zur gleichen Zeit demonstrierte Futuremark die Verwendung von kaskadierten Schattenkarten (CSM) in 3DMark06 . Dies ist eine Technik, bei der für jede Lichtquelle mehrere Tiefenstrukturen mit unterschiedlichen Auflösungen erstellt werden. Hochauflösende Texturen werden in der Nähe der Quelle und niedriger verwendet - in einem Abstand von der Quelle. Das Ergebnis sind glattere Schattenübergänge in der Szene ohne Verzerrung.

Diese Technik wurde 2006 von Donnelly und Loritzen in ihrem Varianzschatten-Mapping- Verfahren (VSM) sowie von Intel im Jahr 2010 in ihrem Sample Distribution Algorithmus (SDSM) verbessert .


Verwenden von SDSM in Shadow of the Tomb Raider

Um das Bild zu verbessern, verwenden Spieleentwickler häufig ein ganzes Arsenal an Schattierungstechniken, die wichtigste bleibt jedoch die Schattenzuordnung. Es kann jedoch nur auf eine kleine Anzahl aktiver Lichtquellen angewendet werden. Wenn Sie versuchen, es für jede Oberfläche zu modellieren, die Licht reflektiert oder emittiert, sinkt die Bildrate katastrophal.

Glücklicherweise gibt es eine praktische Technik, die mit jedem Objekt funktioniert. Es entsteht der Eindruck einer Abnahme der Helligkeit der Beleuchtung, die das Objekt erreicht (aufgrund der Tatsache, dass er oder andere Objekte das Licht ein wenig blockieren). Diese Funktion wird als Umgebungsokklusion bezeichnet.und sie hat viele Versionen. Einige von ihnen wurden speziell von Hardwareherstellern entwickelt, z. B. von AMD entwickelte HDAO ( High Definition Ambient Occlusion ) und Nvidia HBAO + ( Horizon Based Ambient Occlusion ).

Unabhängig davon, welche Version verwendet wird, wird sie angewendet, nachdem die Szene vollständig gerendert wurde, und wird daher als Nachbearbeitungseffekt klassifiziert . Tatsächlich wird für jedes Pixel berechnet, wie viel wir in der Szene sehen (mehr dazu hier und hier ), indem der Wert der Pixeltiefe mit den Pixeln verglichen wird, die ihn an dem entsprechenden Punkt im Tiefenpuffer umgeben (der wiederum als Textur gespeichert ist).

Das Abtasten des Tiefenpuffers und das anschließende Berechnen der endgültigen Pixelfarbe spielt eine wichtige Rolle bei der Sicherstellung der Qualität der Umgebungsokklusion. Wie im Fall von Shadowing muss der Programmierer bei allen Versionen der Umgebungsokklusion für den ordnungsgemäßen Betrieb den Code je nach Situation sorgfältig konfigurieren und anpassen.


Shadow of the Tomb Raider ohne AO ​​(links) und mit HBAO + (rechts)

Bei richtiger Implementierung hinterlässt dieser visuelle Effekt jedoch einen tiefen Eindruck. Achten Sie im obigen Bild auf die Hände, Ananas und Bananen der Person sowie auf das umgebende Gras und die Vegetation. Die Farbänderungen bei HBAO + -Pixeln sind recht gering, aber alle Objekte sehen jetzt besser in die Umgebung eingebaut aus (links scheint es, dass eine Person über dem Boden hängt).

Wenn Sie eines der letzten in diesem Artikel beschriebenen Spiele auswählen, entspricht die Liste der Rendering-Techniken, die bei der Verarbeitung von Licht und Schatten verwendet werden, der Länge des Artikels. Obwohl nicht jedes neue 3D-Spiel über all diese Technologien verfügt, können Sie sie mit universellen Spiel-Engines wie Unreal optional aktivieren, und Toolkits (z. B. Nvidia-Unternehmen) bieten einen Code, der zum Einfügen in das Spiel bereit ist. Dies beweist, dass es sich nicht um hochspezialisierte hochmoderne Methoden handelt, die einst den besten Programmierern gehörten und jetzt jedem zur Verfügung stehen.

Wir können diesen Artikel über Licht und Schatten nicht vervollständigen, ohne Raytracing zu erwähnen. Wir haben bereits in dieser Artikelserie über diesen Prozess gesprochen , aber über den aktuellen Stand der Technologieentwicklungerfordert eine niedrige Bildrate und einen erheblichen Geldaufwand.

Die Technologie wird jedoch von Konsolen der nächsten Generation, Microsoft und Sony, unterstützt. Dies bedeutet, dass ihre Verwendung in den nächsten Jahren zu einem weiteren Standardwerkzeug für Entwickler auf der ganzen Welt werden wird, die die visuelle Qualität von Spielen verbessern möchten. Schauen Sie sich an, was Remedy in ihrem neuesten Control- Spiel erreicht hat :


Wir sind weit von falschen Schatten in Texturen und einfacher Umgebungsbeleuchtung entfernt!

Das ist nicht alles


In dem Artikel haben wir versucht, über die grundlegenden mathematischen Berechnungen und Techniken zu sprechen, die in 3D-Spielen verwendet werden, um sie so realistisch wie möglich zu gestalten. Wir haben auch die Technologien untersucht, die der Modellierung der Wechselwirkung von Licht mit Objekten und Materialien zugrunde liegen. Aber das alles war nur die Spitze des Eisbergs.

Zum Beispiel haben wir Themen wie energiesparende Beleuchtung, Linseneffekt, Blüte, hochdynamisches Rendering, Strahlungsübertragung, Tonkorrektur, Nebel, chromatische Aberration, Photonenkartierung, Kaustik und Radiosität übersprungen - diese Liste geht weiter. Eine kurze Studie würde 3-4 weitere Artikel erfordern.

All Articles