Schattenvolumen - Shadow volume

Beispiel für Carmacks Stencil Shadowing in Doom 3 .

Schattenvolumen ist eine Technik, die in der 3D-Computergrafik verwendet wird , um einer gerenderten Szene Schatten hinzuzufügen. Sie wurden erstmals 1977 von Frank Crow als Geometrie vorgeschlagen, die die 3D-Form der von einer Lichtquelle verdeckten Region beschreibt. Ein Schattenvolumen teilt die virtuelle Welt in zwei Bereiche: Bereiche, die im Schatten liegen, und Bereiche, die es nicht sind.

Die Schablonenpufferimplementierung von Schattenvolumen wird allgemein als eine der praktischsten Allzweck-Echtzeit-Schattentechniken zur Verwendung auf moderner 3D-Grafikhardware angesehen. Es wurde durch das Videospiel Doom 3 populär gemacht , und eine besondere Variation der in diesem Spiel verwendeten Technik wurde als Carmack's Reverse bekannt .

Shadow-Volumes sind neben dem ehrwürdigeren Shadow-Mapping zu einem beliebten Werkzeug für das Echtzeit-Shadowing geworden . Der Hauptvorteil von Shadow-Volumes besteht darin, dass sie pixelgenau sind (obwohl viele Implementierungen ein kleines Problem der Selbstschatten entlang der Silhouettenkante haben, siehe Konstruktion unten), während die Genauigkeit einer Shadow-Map vom zugewiesenen Texturspeicher abhängt sowie der Winkel, in dem die Schatten geworfen werden (bei einigen Winkeln leidet unvermeidlich die Genauigkeit einer Schattenkarte). Die Technik erfordert jedoch die Erstellung einer Schattengeometrie, die CPU-intensiv sein kann (je nach Implementierung). Der Vorteil von Shadow Mapping ist, dass es oft schneller ist, da Schattenvolumenpolygone oft sehr groß in Bezug auf den Bildschirmplatz sind und viel Füllzeit benötigen (insbesondere bei konvexen Objekten), während Shadow Maps diese Einschränkung nicht haben.

Konstruktion

Um ein Schattenvolumen zu konstruieren, projizieren Sie einen Strahl von der Lichtquelle durch jeden Scheitelpunkt im Schattenwurfobjekt bis zu einem bestimmten Punkt (im Allgemeinen im Unendlichen). Diese Projektionen bilden zusammen ein Volumen; Jeder Punkt innerhalb dieses Volumens liegt im Schatten, alles außerhalb wird vom Licht beleuchtet.

Bei einem polygonalen Modell wird das Volumen normalerweise gebildet, indem jede Fläche in dem Modell entweder als der Lichtquelle zugewandt oder von der Lichtquelle abgewandt klassifiziert wird. Die Menge aller Kanten, die eine zugewandte Seite mit einer abgewandten Seite verbinden, bilden die Silhouette in Bezug auf die Lichtquelle. Die die Silhouette bildenden Kanten werden vom Licht weg extrudiert, um die Gesichter des Schattenvolumens zu konstruieren. Dieses Volumen muss sich über den Bereich der gesamten sichtbaren Szene erstrecken; oft werden die Abmessungen des Schattenvolumens bis ins Unendliche erweitert, um dies zu erreichen (siehe Optimierung unten). Um ein geschlossenes Volumen zu bilden, müssen das vordere und hintere Ende dieser Extrusion abgedeckt werden. Diese Abdeckungen werden "Kappen" genannt. Je nach verwendeter Methode für das Schattenvolumen kann das vordere Ende durch das Objekt selbst bedeckt sein und das hintere Ende kann manchmal weggelassen werden (siehe Tiefenpass unten).

Es gibt auch ein Problem mit dem Schatten, wo die Gesichter entlang der Silhouettenkante relativ flach sind. In diesem Fall ist der Schatten, den ein Objekt auf sich selbst wirft, scharf und zeigt seine polygonalen Facetten, während das übliche Beleuchtungsmodell eine allmähliche Änderung der Beleuchtung entlang der Facette aufweist. Dies hinterlässt ein grobes Schattenartefakt nahe der Silhouettenkante, das schwer zu korrigieren ist. Durch Erhöhen der Polygondichte wird das Problem minimiert, aber nicht beseitigt. Wenn die Vorderseite des Schattenvolumens begrenzt ist, kann das gesamte Schattenvolumen leicht vom Licht weg versetzt werden, um alle Schattenselbstschnittpunkte innerhalb des Versatzabstands der Silhouettenkante zu entfernen (diese Lösung wird häufiger beim Schatten-Mapping verwendet ).

Die grundlegenden Schritte zum Bilden eines Schattenvolumens sind:

  1. Finden Sie alle Silhouettenkanten (Kanten, die nach vorne gerichtete Flächen von nach hinten zeigenden Flächen trennen)
  2. Erweitern Sie alle Silhouettenkanten in Richtung von der Lichtquelle weg
  3. Fügen Sie jeder Oberfläche eine Front-Cap und/oder Back-Cap hinzu , um ein geschlossenes Volumen zu bilden (kann je nach verwendeter Implementierung nicht erforderlich sein)
Illustration von Schattenvolumen. Das Bild oben links zeigt eine Szene, die mit Schattenvolumen schattiert wird. Rechts sind die Schattenvolumina in Drahtmodell dargestellt. Beachten Sie, wie die Schatten einen großen konischen Bereich bilden, der von der Lichtquelle weg zeigt (der helle weiße Punkt).

Schablonenpufferimplementierungen

Nach Crow zeigte 1991 Tim Heidmann , wie man den Stencil Buffer verwendet , um Schatten mit Schattenvolumen schnell genug für den Einsatz in Echtzeitanwendungen zu rendern. Es gibt drei gängige Variationen dieser Technik, Depth Pass , Depth Fail und Exclusive-Oder , aber alle verwenden den gleichen Prozess:

  1. Rendern Sie die Szene, als ob sie vollständig im Schatten wäre.
  2. Für jede Lichtquelle:
    1. Erstellen Sie mit den Tiefeninformationen dieser Szene eine Maske im Schablonenpuffer, die nur dort Löcher hat, wo die sichtbare Oberfläche nicht im Schatten liegt.
    2. Rendern Sie die Szene erneut, als ob sie vollständig beleuchtet wäre, und verwenden Sie den Schablonenpuffer, um die schattierten Bereiche zu maskieren. Verwenden Sie die additive Mischung, um dieses Rendering der Szene hinzuzufügen.

Der Unterschied zwischen diesen drei Verfahren liegt in der Erzeugung der Maske im zweiten Schritt. Einige beinhalten zwei Durchgänge, andere nur einen; einige erfordern weniger Präzision im Schablonenpuffer.

Schattenvolumina neigen dazu, große Teile der sichtbaren Szene abzudecken und verbrauchen daher wertvolle Rasterisierungszeit (Füllzeit) auf 3D-Grafikhardware. Dieses Problem wird durch die Komplexität der Schattenwurfobjekte verschlimmert, da jedes Objekt sein eigenes Schattenvolumen jeder möglichen Größe auf den Bildschirm werfen kann. Siehe Optimierung unten für eine Diskussion der Techniken, die verwendet werden, um das Füllzeitproblem zu bekämpfen.

Tiefenpass

Heidmann schlug vor, dass, wenn die Vorder- und Rückseiten der Schatten in getrennten Durchgängen gerendert werden, die Anzahl der Vorder- und Rückseiten vor einem Objekt mit Hilfe des Schablonenpuffers gezählt werden kann. Wenn die Oberfläche eines Objekts im Schatten liegt, gibt es mehr nach vorne gerichtete Schattenflächen zwischen ihm und dem Auge als nach hinten gerichtete Schattenflächen. Bei gleicher Anzahl liegt die Objektoberfläche jedoch nicht im Schatten. Die Generierung der Schablonenmaske funktioniert wie folgt:

  1. Schreibvorgänge in die Tiefen- und Farbpuffer deaktivieren.
  2. Verwenden Sie Back-Face-Culling .
  3. Stellen Sie die Schablonenoperation so ein, dass sie beim Tiefendurchlauf inkrementiert wird (zählen Sie nur Schatten vor dem Objekt).
  4. Rendern Sie die Schattenvolumen (wegen des Cullings werden nur ihre Vorderseiten gerendert).
  5. Verwenden Sie Front-Face-Culling.
  6. Stellen Sie die Schablonenoperation auf Dekrementieren beim Tiefendurchlauf ein.
  7. Rendern Sie die Schattenvolumen (nur ihre Rückseiten werden gerendert).

Nachdem dies erreicht ist, entsprechen alle beleuchteten Oberflächen einer 0 im Schablonenpuffer, wobei die Anzahl der Vorder- und Rückseiten aller Schattenvolumina zwischen dem Auge und dieser Oberfläche gleich ist.

Dieser Ansatz hat Probleme, wenn sich das Auge selbst in einem Schattenvolumen befindet (beispielsweise wenn sich die Lichtquelle hinter einem Objekt bewegt). Aus dieser Sicht sieht das Auge die Rückseite dieses Schattenvolumens vor allem anderen, und dies fügt dem gesamten Schablonenpuffer eine Vorspannung von -1 hinzu, wodurch die Schatten effektiv invertiert werden. Dies kann behoben werden, indem eine "Kappen"-Fläche an der dem Auge zugewandten Vorderseite des Schattenvolumens hinzugefügt wird, beispielsweise an der vorderen Schnittebene . Es gibt eine andere Situation, in der sich das Auge im Schatten eines Volumens befinden kann, das von einem Objekt hinter der Kamera geworfen wird, das ebenfalls irgendwie abgedeckt werden muss, um ein ähnliches Problem zu vermeiden. In den meisten gängigen Implementierungen kann die Tiefen-Fehler-Methode (siehe unten) für diese speziellen Situationen lizenziert werden, da es schwierig sein kann, eine korrekte Begrenzung für den Tiefendurchgang zu erreichen. Alternativ kann man dem Schablonenpuffer einen Bias von +1 für jedes Schattenvolumen geben, in dem sich die Kamera befindet, obwohl die Erkennung langsam sein kann.

Es gibt ein weiteres potenzielles Problem, wenn der Schablonenpuffer nicht über genügend Bits verfügt, um die Anzahl der zwischen dem Auge und der Objektoberfläche sichtbaren Schatten aufzunehmen, da er Sättigungsarithmetik verwendet . (Wenn stattdessen der arithmetische Überlauf verwendet würde, wäre das Problem unbedeutend.)

Tiefendurchlauf - Tests sind auch bekannt als z-Pass - Tests, wie die Tiefenpuffer oft als Z-Puffer bezeichnet wird.

Tiefe fehlgeschlagen

Um das Jahr 2000 herum entdeckten mehrere Leute, dass man Heidmanns Methode durch Umkehren der Tiefe für alle Kamerapositionen zum Laufen bringen kann. Anstatt die Schattenflächen vor der Objektoberfläche zu zählen, können die dahinter liegenden Flächen genauso einfach gezählt werden, mit dem gleichen Endergebnis. Dies löst das Problem, dass das Auge im Schatten liegt, da die Schattenvolumina zwischen dem Auge und dem Objekt nicht gezählt werden, führt jedoch die Bedingung ein, dass das hintere Ende des Schattenvolumens abgedeckt werden muss, oder Schatten fehlen am Ende, wo das Volumen zeigt rückwärts bis unendlich.

  1. Schreibvorgänge in die Tiefen- und Farbpuffer deaktivieren.
  2. Verwenden Sie Front-Face-Culling.
  3. Stellen Sie den Schablonenvorgang so ein, dass er bei Tiefenfehler erhöht wird (zählen Sie nur Schatten hinter dem Objekt).
  4. Rendern Sie die Schattenvolumen.
  5. Verwenden Sie Back-Face-Culling.
  6. Setzen Sie die Schablonenoperation auf Dekrementieren bei fehlgeschlagener Tiefe.
  7. Rendern Sie die Schattenvolumen.

Die Tiefenfehlermethode hat die gleichen Überlegungen bezüglich der Genauigkeit des Schablonenpuffers wie die Tiefenpassmethode. Ähnlich wie beim Tiefendurchgang wird es manchmal auch als Z-Fail- Methode bezeichnet.

William Bilodeau und Michael Songy entdeckten diese Technik im Oktober 1998 und präsentierten sie 1999 auf der Creativity, einer Entwicklerkonferenz von Creative Labs. Sim Dietrich präsentierte diese Technik sowohl auf der GDC im März 1999 als auch auf der Creativity Ende 1999. Ein paar Monate später reichten William Bilodeau und Michael Songy im selben Jahr eine US-Patentanmeldung für die Technik ein, US 6384822  , mit dem Titel "Method for render shadows using a shadow volume and a stencil buffer", die 2002 ausgestellt wurde und im Oktober 2019 auslief. John Carmack of id Software hat den Algorithmus im Jahr 2000 während der Entwicklung von Doom 3 unabhängig entdeckt .

Exklusiv oder

Jeder der oben genannten Typen kann mit einer Exklusiv-Oder- Variation angenähert werden , die nicht richtig mit sich überschneidenden Schattenvolumen umgeht, aber einen Rendering-Durchgang (wenn keine Füllzeit) spart und nur einen 1-Bit-Schablonenpuffer erfordert. Die folgenden Schritte gelten für die Tiefenpass-Version:

  1. Schreibvorgänge in die Tiefen- und Farbpuffer deaktivieren.
  2. Setzen Sie die Schablonenoperation beim Tiefendurchlauf auf XOR (auf einer beliebigen Schattenoberfläche spiegeln).
  3. Rendern Sie die Schattenvolumen.

Optimierung

  • Ein Verfahren zum Beschleunigen der Schattenvolumengeometrieberechnungen besteht darin, vorhandene Teile der Rendering-Pipeline zu verwenden, um einen Teil der Berechnung durchzuführen. Unter Verwendung homogener Koordinaten kann beispielsweise die w- Koordinate auf Null gesetzt werden, um einen Punkt ins Unendliche zu verlängern. Dies sollte von einem Betrachtungsstumpf begleitet werden , der eine weit entfernte Clipping-Ebene hat, die sich bis ins Unendliche erstreckt, um diese Punkte unterzubringen, was durch die Verwendung einer speziellen Projektionsmatrix erreicht wird. Diese Technik reduziert die Genauigkeit des Tiefenpuffers geringfügig, aber der Unterschied ist normalerweise vernachlässigbar. Siehe 2002 Papier "Practical and Robust Stenciled Shadow Volumes for Hardware-Accelerated Rendering" , C. Everitt und M. Kilgard , für eine detaillierte Implementierung.
  • Die Rasterisierungszeit der Schattenvolumina kann reduziert werden, indem ein hardwareinterner Scherentest verwendet wird, um die Schatten auf ein bestimmtes Rechteck auf dem Bildschirm zu begrenzen.
  • NVIDIA hat eine Hardwarefunktion namens Depth Bounds Test implementiert , mit der Teile von Schattenvolumen entfernt werden sollen, die die sichtbare Szene nicht beeinflussen. (Dies ist seit dem GeForce FX 5900-Modell verfügbar .) Eine Diskussion über diese Funktion und ihre Verwendung mit Shadow-Volumes wurde auf der Game Developers Conference im Jahr 2005 präsentiert.
  • Da das Tiefen-Ausfall-Verfahren nur in dem speziellen Fall, in dem sich das Auge innerhalb eines Schattenvolumens befindet, einen Vorteil gegenüber dem Tiefen-Pass bietet, ist es vorzuziehen, diesen Fall zu überprüfen und wo immer möglich den Tiefen-Pass zu verwenden. Dies vermeidet sowohl das unnötige Back-Capping (und die damit verbundene Rasterung) für Fälle, in denen ein Tiefenfehler unnötig ist, als auch das Problem eines geeigneten Front-Capping für spezielle Fälle des Tiefenpasses.
  • In neueren GPU-Pipelines können Geometrie-Shader verwendet werden, um die Schattenvolumen zu generieren.
  • Auf Systemen, die keine Geometrie-Shader unterstützen, können Vertex-Shader auch verwendet werden, um Schattenvolumen zu erzeugen, indem selektiv Vertices extrudiert werden, die sich bereits im GPU-Speicher befinden.

Siehe auch

Verweise

Externe Links

In Bezug auf Depth-Fail-Patente