Ich versuche kaskadierte Shadow-Mapping in meinem OpenGL / C ++ - Renderer zu implementieren. Es ist mir gelungen, das Directional Shadow Mapping zu implementieren, wenn die Ortho-Matrix aus beliebigen Zahlen besteht und am Ursprung der Szene bleibt. Von allem, was ich sehen kann, ist das Problem, das ich habe, die Grenzen der ortho-Matrizen basierend auf der Scheibe des View-Frustrums zu bestimmen.
Ich habe zwei Wege gefunden, es zu berechnen, beide sind verwandt; Der erste Weg erzeugt eine Projektionsmatrix unter Verwendung der nahen / fernen Ebenen für die aktuelle Schicht und invertiert sie dann. Dann nehme ich die Ecken eines Würfels im NDC-Raum (jede Achse reicht von [-1: +1]), multipliziere es durch die invertierte Projektionsmatrix, die invertierte Ansichtsmatrix, dann die Lichtraummatrix; dann teile das Ganze durch das "w" der Ecke.
%Vor%Der zweite Weg ist ähnlich, er beginnt mit einer Reihe von Ecken im Betrachtungsraum, wodurch die Notwendigkeit, durch w zu teilen und einige Matrixinversionen zu sparen, verringert wird.
%Vor%Beide ergeben falsche, aber irgendwie-sorta-fast-korrekte Ergebnisse. Die zweite Methode scheint eine engere Box zu erzeugen.
Interessanterweise funktionieren beide meistens, wenn sich die Kamera im Lichtraum entlang der x-Achse bewegt. Wenn sich die Kamera im hellen Raum entlang der y / z-Achse bewegt, erhalten Sie sehr falsche Ergebnisse.
Hier sind einige Bilder von dem, worüber ich rede. Der erste von jedem Paar ist die Szene gemäß der normalen Kameraperspektive, der zweite ist von der Sicht des Lichts (erste Kaskade, ich werde nicht einmal versuchen, die zweite Kaskade zu versuchen, bis die erste richtig funktioniert). Die rote Region sollte in der ersten Kaskade enthalten sein, die grüne Region ist später Kaskade und die nicht schattierte Region befindet sich außerhalb des View-Frustrums.
(Diese Screenshots wurden mit Methode # 1 erstellt)
So weit, so gut, oder? gut ...
Eine Weile dachte ich, dass das Problem in meiner Funktion mat4::inverted()
sein könnte, aber ich habe 2 verschiedene Implementierungen ausprobiert, und beide ergeben die gleichen Ergebnisse. Die eine, die ich momentan verwende, ist:
Was zum Teufel mache ich falsch?