2016-04-09 13 views
2

Ich möchte meine eigene MVP-Matrix als Übung erstellen.Die Mathematik hinter der Perspektive Matrix

Die Ansicht Transformation war ziemlich einfach, ich habe es so eingerichtet, dass ich jetzt entlang der negativen Z-Achse sehe.

Aber ich habe ein paar Probleme mit der Perspektive Matrix.

y' = 1/(tan(fov/2) * z 
x' = 1/(ar * tan(fov/2) * z 

Wo x' und y' sind die neuen verzerrten Werte. So kam ich mit dieser Matrix bis

Mat4f projection(float fov, float ar, float near, float far){ 
    import std.math: tan; 
    auto tanHalfAngle = tan(fov/2.0f); 
    return Mat4f(
     Vec4f(1.0f/(ar * tanHalfAngle) , 0, 0, 0), 
     Vec4f(0, 1.0f/tanHalfAngle, 0, 0), 
     Vec4f(0, 0, 1, 0), 
     Vec4f(0, 0, -1, 0)); 
} 

ich es derzeit nur so einrichten, dass der Z Wert ist immer -1. Aber ich habe einen kleinen Fehler gemacht, weil ich jetzt durch -Z dividiere.

Das Ding ist die Matrix oben funktioniert. Ich mache gerade einen rotierenden Würfel und neben den Tiefenwerten sieht alles korrekt aus.

Aber ich wollte wirklich diese Matrix

Mat4f projection(float fov, float ar, float near, float far){ 
    import std.math: tan; 
    auto tanHalfAngle = tan(fov/2.0f); 
    return Mat4f(
     Vec4f(1.0f/(ar * tanHalfAngle) , 0, 0, 0), 
     Vec4f(0, 1.0f/tanHalfAngle, 0, 0), 
     Vec4f(0, 0, -1, 0), 
     Vec4f(0, 0, 1, 0)); 
} 

Aber die Würfel erscheint nicht auf dem Bildschirm nicht mehr, und ich verstehe nicht, warum.

auto view = lookAt(Vec3f(0, 0, -5), Vec3f(0, 0, 0), Vec3f(0, 1, 0)); 
auto proj = projection(PI/2, 4.0f/3.0f, 0.1f, 100); 

I Setup-Prüfwerte

auto v = proj * view * Vec4f(0.5,0.5,0.5,1); 

Dies ist das Ausgangssignal I mit der ersten Matrix, wo ich dividieren durch -Z

Vec(-0.375, 0.5, -5.5, 5.5) 
Vec(-0.0681818, 0.0909091, -1) // divided by w 

Dies ist das Ausgangssignal I mit der zweiten Matrix erhalten wo ich teile durch Z

Vec(-0.375, 0.5, 5.5, -5.5) 
Vec(0.0681818, -0.0909091, -1) //divided by w 

Das einzige, was sich geändert hat, ist das Zeichen.

Aber warum kann ich einen Würfel mit der ersten Matrix aber nichts mit der zweiten Matrix sehen?

-w <= x, y, z <= w 

Hinweis, dass diese trivialerweise alle Punkte mit w < 0 ist, ausgeschlossen ist, da:

Antwort

2

Der Standard clipping Regel OpenGL ist in Clipraum als alle Punkte, der die folgende inequailty innerhalb des Sichtstumpfs liegen formuliert -w wird dann> w, also kann es nicht befriedigt werden.

Der Blick Transformation war ziemlich einfach, ich es so einrichten, dass ich entlang der negativen Z-Achse nun einen Blick.

Das stimmt nicht wirklich. Die View-Matrix nicht definiert die Blickrichtung allein, die Projektionsmatrix hat auch einen Einfluss. Bei Verwendung einer Standardperspektivprojektion kann die letzte Zeile der Projektionsmatrix einfach als der Richtungsvektor der Hauptachse für die Projektion interpretiert werden, so dass sie den Blickrichtungsvektor im Augenraum definiert.Die klassische GL-Projektion verwendet (0 0 -1 0), also wird -z die Blickrichtung sein.

Der Job der Ansichtsmatrix besteht nun darin, die Kamera zu platzieren und die Szene so zu drehen, dass die beabsichtigte Blickrichtung des Weltbereichs auf die Blickrichtung der Augen projiziert wird, die die Projektionsmatrix verwendet.

Wenn Sie Ihre Projektionsmatrix durch z statt -z teilen, bedeutet dies natürlich, dass sie in diese Richtung schaut. Da Sie Ihre Ansichtsmatrix nicht so eingestellt haben, dass sie dieser Konvention folgt, zeigt Ihre Kamera jetzt genau in die entgegengesetzte Richtung, in der sich Ihre Ansichtsmatrix befindet. Die Punkte, die in "Front" Ihrer Kamera bei z_eye < 0 liegen, haben alle eine negative w_clip und werden von der nahen Ebene abgeschnitten.

Verwandte Themen