Schatten beim verzögerten Rendern

12

Ich habe Material über verzögertes Rendern gelesen und denke, ich verstehe das Wesentliche. Was ich aber nicht verstehe, ist, wie es Schatten erzeugt. Soweit mir bekannt ist, beinhaltet der G-Puffer nicht das Erstellen einer Schattenkarte für jedes Licht. Daher bin ich verwirrt darüber, wie der Beleuchtungsdurchlauf erkennt, ob jedes Pixel verdeckt ist oder nicht. Schließlich ist ein bestimmtes Pixel, das aus der Perspektive der Kamera sichtbar ist, möglicherweise aus der Perspektive eines bestimmten Lichts nicht sichtbar - und diese okkludierende Geometrie ist möglicherweise aus der Perspektive der Kamera nicht sichtbar und hat daher nichts darüber in den G-Puffer geschrieben .

Wenn Sie mit dem Rendern von Schattenkarten beginnen, entspricht dies in etwa dem Vorwärtsrendern. Sie rendern die gesamte Geometrie in der Szene für jedes Licht, um die Schattenkarten zu rendern.

Wie erzielt das verzögerte Rendern Schatten, die dem Vorwärtsrendern entsprechen?

DeadMG
quelle

Antworten:

14

Die verzögerte Schattierung ist für Schatten nichts Besonderes. Sie müssen die Schattenkarten weiterhin normal rendern und dann jedes Licht mit der entsprechenden Schattenkarte rendern, die als Textur gebunden ist.

Es ist immer noch besser als das Vorwärtsrendern, da Sie die Szene in der Hauptansicht nicht neu zeichnen müssen, um die Beleuchtung anzuwenden. Das Zeichnen der Schattenkarte ist oft viel billiger als das Zeichnen von mehr Durchgängen in der Hauptansicht, da Sie keine Pixelschattierung vornehmen müssen und Schattenkarten oft weniger Szenen enthalten (Sie können viel mehr Material ausmerzen).

Menschen machen manchmal "verzögerte Schatten" für ein Licht, typischerweise das Hauptrichtungslicht. Der Hauptgrund dafür ist die Verwendung von kaskadierten Schattenkarten oder eines anderen Ansatzes, bei dem mehrere Schattenkarten für dasselbe Licht verwendet werden. Sie können einen Kanal im G-Puffer für eine Schattenmaske reservieren (weiß, wo beleuchtet, dunkel, wo schattiert) und alle kaskadierten Schattenkarten auf diesen G-Puffer-Kanal anwenden. dann liest der Shader für das Licht nur die Schattenmaske und multipliziert sie mit der Lichtfarbe. Dies ist schön, da es Schatten von Schattierungen entkoppelt, aber Sie zeichnen immer noch dieselben Schattenkarten.

Nathan Reed
quelle
1
Wenn Sie äußerst clever sind, können Sie versuchen, während der Erstellung des GBuffers einen Geometrie-Shader zu verwenden, um die Erstellung der Schattenkarte zu "inline" (wie es das DX10-Beispiel für die Würfelkarte tut). Ich bin mir nicht sicher, ob es getan wurde, ob es überhaupt möglich ist oder ob es am Ende langsamer sein würde - aber es würde die Erstellung von Schattenkarten näher an die verzögerte Schattierung oder in die Definition bringen, abhängig von Ihrer Religion.
Jonathan Dickinson
6

Was ist eine Schattenkarte? Eine Schattenkarte ist eine Textur, deren Texel eine einfache Frage beantworten: In welcher Entfernung vom Licht, entlang der durch das Texel dargestellten Richtung, ist das Licht verdeckt? Texturkoordinaten werden unter Verwendung verschiedener projektiver Texturierungsmittel erzeugt, abhängig von dem speziellen Schattenabbildungsalgorithmus.

Projektive Texturierung ist einfach eine Möglichkeit, ein Objekt in den Raum der Textur zu verwandeln (und ja, ich weiß, das klingt rückwärts. Aber so funktioniert es). Shadow-Mapping-Algorithmen verwenden verschiedene Arten von Transformationen. Aber letztendlich sind dies nur Transformationen von einem Raum in einen anderen.

Beim Rendern der Schattenkarte nehmen Sie die Scheitelpunkte Ihrer Geometrie und transformieren sie durch eine Standard-Rendering-Pipeline. Die Kamera- und Projektionsmatrizen sind jedoch für Ihre Lichtposition und -richtung ausgelegt, nicht für die Ansichtsposition und -ausrichtung.

Wenn Sie mit einer Schattenkarte vorwärts rendern, rendern Sie das Objekt wie gewohnt und transformieren die Scheitelpunkte in den Ansichtskameraraum und durch die Betrachtungsprojektionsmatrix. Sie transformieren die Scheitelpunkte jedoch auch durch Ihre Lichtkamera- und Projektionsmatrizen und übergeben sie als Scheitelpunktdaten an den Fragment-Shader. Sie werden über eine projektive Texturierung verwendet, um auf die Schattentextur zuzugreifen.

Hier ist der wichtige Punkt. Der projektive Texturzugriff ist so konzipiert, dass die Position, auf die auf die Textur zugegriffen wird, die Richtung zwischen diesem Punkt auf der Oberfläche (dem Punkt, den Sie im Fragment-Shader rendern) und dem Licht darstellt. Daher wird das Texel abgerufen, das die Tiefe darstellt, in der die Okklusion für das gerenderte Fragment erfolgt.

Aber diese Pipeline hat nichts Besonderes . Sie müssen die Scheitelpunktpositionen nicht in die Schattentextur umwandeln und diese an den Fragment-Shader übergeben. Sie können die Scheitelpunktpositionen des Weltraums an den Fragment-Shader übergeben und dann vom Fragment-Shader in den projektiven Raum der Schattentextur umwandeln lassen. Zugegeben, Sie würden viel Leistung wegwerfen, da Sie genau die gleichen Texturkoordinaten erhalten. Aber es ist mathematisch machbar.

In der Tat können Sie die Scheitelpunktpositionen des Ansichtskameraraums an den Fragment-Shader übergeben. Es könnte sie dann in eine Welt verwandeln, dann in einen hellen Kameraraum, dann in den projektiven Schattentexturraum. Sie können all diese Transformationen in einer Matrix zusammenfassen (abhängig von Ihrem Schattenprojektionsalgorithmus). Auch dies gibt Ihnen genau das, was Sie zuvor hatten. Wenn Sie also vorwärts rendern, gibt es keinen Grund, dies zu tun.

Beim verzögerten Rendern haben Sie jedoch bereits die Scheitelpunktpositionen des Ansichtskameraraums. Sie müssen, sonst können Sie nicht beleuchten. Sie haben entweder viel Speicher und Bandbreite verschwendet, indem Sie sie in einen Puffer geschrieben haben, oder Sie waren schlau und haben sie mithilfe des Tiefenpuffers und verschiedener mathematischer Berechnungen neu berechnet (auf die ich hier nicht näher eingehen werde, die aber online behandelt werden).

In beiden Fällen können Sie die Positionen des Kameraraums anzeigen. Und wie oben erwähnt, können wir eine Matrix anwenden, um sie vom Ansichtskameraraum in einen schattenprojektiven Texturraum umzuwandeln. Also ... mach das. Greifen Sie dann auf Ihre Schattenkarte zu.

Problem gelöst.

Nicol Bolas
quelle
Ist es möglich, Geometrie pro Licht beim verzögerten Rendern aus Gründen der Optimierung auszuschließen?
Samaursa
@ Samasursa: "Geometrie pro Licht ausschließen" von was? Vom Betreten der Schattenkarte? Vom Anzünden?
Nicol Bolas
Ich sehe, Sie haben die Frage dazu beantwortet, danke. Für andere wollen , wenn sie die Frage / Antwort folgen: gamedev.stackexchange.com/q/178755/2287
Samaursa