glsl sampler2DShadow und shadow2D Klärung

7

Schneller Hintergrund dessen, wo ich bin (um sicherzustellen, dass wir auf der gleichen Seite sind, und Vernunft, ob ich etwas Dummes vermisse / nehme):

  • Ziel: Ich möchte meine Szene mit Schatten darstellen, indem ich eine verzögerte Beleuchtung benutze und Shadowmaps.
  • Kampf: eine klare und konsistente Dokumentation bezüglich der Verwendung von shadow2D und sampler2DShadow finden.

Folgendes mache ich gerade:

Im Fragment-Shader meines finalen Rendering-Passes (der, der tatsächlich die finalen Frag-Werte berechnet), habe ich die MVP-Matrizen vom Pass aus der Sicht des Lichts, die Tiefenstruktur von diesem Pass (aka die "shadow map") "), und die Position / normal / Farbe Texturen aus meinem Geometrie-Puffer.

Nach dem was ich verstehe, muss ich herausfinden, welchem ​​UV der Shadowmap die Position des aktuellen Fragments entspricht. Ich mache das mit folgendem:

%Vor%

Nun, da ich diese UV-Strahlung habe, kann ich die wahrgenommene "Tiefe" von der Lichtquelle mit

erreichen %Vor%

und vergleiche das mit dem Abstand zwischen der Position am aktuellen Fragment und dem Licht:

%Vor%

Das Problem kommt daher, dass "Tiefe" in den Werten 0-1 gespeichert wird und der tatsächliche Abstand in Weltkoordinaten liegt. Ich habe versucht, diese Konvertierung manuell durchzuführen, konnte sie aber nicht ausführen. Und bei der Online-Suche sieht es so aus, als würde ich dies mit einem sampler2DShadow machen ...

Hier ist meine Frage (n):

Welche Änderungen muss ich vornehmen, um stattdessen shadow2D zu verwenden? Was macht shadow2D überhaupt? Ist es mehr oder weniger eine automatische Umwandlung von Tiefe in Welt Textur? Kann ich die gleiche Tiefenstruktur verwenden? Oder muss ich die Tiefenstruktur anders darstellen? Was gebe ich an shadow2D weiter? Die Weltraumposition des Fragments, das ich überprüfen möchte? Oder die gleiche UV wie vorher?

Wenn all diese Fragen auf einer einfachen Dokumentationsseite beantwortet werden können, würde ich mich freuen, wenn jemand das einfach posten könnte. Aber ich schwöre, ich habe stundenlang gesucht und kann nichts finden, was einfach sagt, was zum Teufel mit shadow2D los ist!

Danke!

    
Phildo 15.03.2014, 04:49
quelle

1 Antwort

35

Zuallererst, welche Version von GLSL benutzen Sie?

Ab GLSL 1.30 gibt es keine spezielle Textur-Lookup-Funktion (Name sowieso) zur Verwendung mit sampler2DShadow . GLSL 1.30+ verwendet eine Reihe von Überladungen von texture (...) , die basierend auf dem Typ von sampler passed und den Dimensionen der Koordinaten ausgewählt werden.

Zweitens, wenn Sie sampler2DShadow verwenden, müssen Sie zwei Dinge anders machen:

  1. Der Texturvergleich muss aktiviert sein oder Sie erhalten undefinierte Ergebnisse

    • GL_TEXTURE_COMPARE_MODE = GL_COMPARE_REF_TO_TEXTURE​

  2. Die Koordinaten, die Sie an texture (...) übergeben, sind 3D statt 2D. Die neue 3. Koordinate ist der Tiefenwert, den Sie vergleichen werden.

Zuletzt sollten Sie verstehen, was texture (...) zurückgibt, wenn sampler2DShadow :

verwendet wird

Wenn dieser Vergleich erfolgreich ist, gibt texture (...) den Wert 1.0 zurück. Wenn dies fehlschlägt, wird 0.0 zurückgegeben. Wenn Sie einen GL_LINEAR Texturfilter für Ihre Tiefenstruktur verwenden, führt texture (...) 4 Tiefenvergleiche mit den 4 engsten Tiefenwerten in Ihrer Tiefenstruktur durch und gibt einen Wert irgendwo dazwischen 1.0 und 0.0 , um eine Vorstellung von der Anzahl der bestandenen / fehlgeschlagenen Stichproben zu erhalten.

Dies ist der richtige Weg, um Hardware-Anti-Aliasing von Shadow Maps durchzuführen. Wenn Sie versuchen, einen regulären sampler2D mit GL_LINEAR zu verwenden und den Tiefen-Test selbst durchzuführen, erhalten Sie statt des oben für sampler2DShadow beschriebenen Verhaltens eine einzelne gemittelte Tiefe zurück und ein boolesches Bestehen / Nicht-Bestehen.

Um einen Tiefenwert von einer Welt-Weltraum-Position aus zu testen, waren Sie auf dem richtigen Weg (obwohl Sie die perspektivische Teilung vergessen haben).

Es gibt drei Dinge, die Sie tun müssen, um aus einer Welt-Raum-Position eine Tiefe zu erzeugen:

  1. Multiplizieren Sie die Welt-Raum-Position mit Ihrer (Licht-) Projektions- und Ansichtsmatrix
  2. Teilen Sie die resultierende Koordinate durch ihre W -Komponente
  3. Skaliere und sortiere das Ergebnis (das im Bereich [-1,1] liegt) in den Bereich [0,1]

Der letzte Schritt setzt voraus, dass Sie den Standardtiefenbereich verwenden ... Wenn Sie glDepthRange (...) nicht aufgerufen haben, funktioniert das.

Das Endergebnis von Schritt 3 dient als beide Wert <%> Tiefe ( R ) und Texturkoordinaten ( ST ) zum Nachschlagen in Ihre Tiefenkarte. Dies ermöglicht es, diesen Wert direkt an texture (...) zu übergeben. Erinnern Sie sich daran, dass die ersten beiden Komponenten der Texturkoordinaten die gleichen sind wie immer und dass der dritte ein zu testender Tiefenwert ist.

    
Andon M. Coleman 15.03.2014, 16:28
quelle

Tags und Links