Versuch, die Mathematik hinter der Perspektivenmatrix in WebGL zu verstehen

8

Alle Matrix-Bibliotheken für WebGL haben irgendeine Art von perspective -Funktion, die Sie aufrufen, um die perspektivische Matrix für die Szene zu erhalten.
Zum Beispiel die perspective -Methode innerhalb der mat4.js -Datei, die Teil ist of gl-matrix ist wie folgt codiert:

%Vor%

Ich versuche wirklich zu verstehen, was die ganze Mathematik in dieser Methode eigentlich macht, aber ich stolpere über mehrere Punkte.

Wenn wir zum Beispiel eine Leinwand wie folgt mit einem Seitenverhältnis von 4: 3 haben, dann wäre der aspect -Parameter der Methode tatsächlich 4 / 3 , korrekt?

Ich habe auch bemerkt, dass 45 ° wie ein gemeinsames Sichtfeld erscheint. Wenn das der Fall ist, dann wäre der Parameter fovy π / 4 radians, korrekt?

Mit all dem, was ist die f Variable in der Methode kurz für und was ist der Zweck davon?
Ich versuchte mir das tatsächliche Szenario vorzustellen, und ich stellte mir etwas wie das folgende vor:

Wenn Sie so denken, kann ich verstehen, warum Sie fovy by 2 teilen und auch warum Sie den Tangens dieses Verhältnisses verwenden, aber warum ist das inverse des in f gespeicherten? Auch hier habe ich große Schwierigkeiten zu verstehen, was f wirklich repräsentiert.

Als nächstes bekomme ich das Konzept von near und far als Beschneidungspunkte entlang der z-Achse, also ist das in Ordnung, aber wenn ich die Zahlen im Bild oben verwende (zB π / 4 , 4 / 3 , 10 und 100 ) und stecke sie in die perspective Methode, dann habe ich am Ende eine Matrix wie die folgende:

Wo f gleich ist:

Ich habe also noch folgende Fragen:

  1. Was ist f ?
  2. Was bedeutet der Wert, der out[10] (d. h. 110 / -90 ) zugewiesen wurde?
  3. Was bewirkt die -1 , die out[11] zugewiesen wurde?
  4. Was bedeutet der Wert, der out[14] (d. h. 2000 / -90 ) zugewiesen wurde?

Zu guter Letzt sollte ich noch erwähnen, dass ich bereits Gregg Tavares 'Erklärung zur perspektivischen Matrix gelesen habe , aber nach all dem bleibt mir die gleiche Verwirrung.

    
HartleySan 02.02.2015, 20:21
quelle

2 Antworten

12

Mal sehen, ob ich das erklären kann, oder vielleicht können Sie nach dem Lesen einen besseren Weg finden, es zu erklären.

Als erstes müssen Sie wissen, dass WebGL Clipspace-Koordinaten benötigt. Sie gehen -1 & lt; - & gt; +1 in x, y und z. Eine perspektivische Matrix ist also im Grunde genommen dafür gedacht, den Raum innerhalb des kegelstumpfes zu nehmen und ihn in den Clipspace zu konvertieren.

Wenn Sie sich dieses Diagramm ansehen

Wir wissen, dass tangential = entgegengesetzt (y) über benachbart (z) ist. Wenn wir also z kennen, können wir y berechnen, das für einen gegebenen fovY am Rand des Kegelstumpfs sitzen würde.

%Vor%

multiplizieren Sie beide Seiten mit -z

%Vor%

wenn wir

definieren %Vor%

wir bekommen

%Vor%

Beachten Sie, dass wir keine Umwandlung von Kameraspace in den Clipspace vorgenommen haben. Alles, was wir getan haben, ist y am Rand des Sichtfeldes für ein gegebenes z im Kameraspace zu berechnen. Die Kante des Sichtfelds ist auch die Kante von Clipspace. Da der Clipspace nur +1 bis -1 ist, können wir den Kameraraum y einfach durch -z / f teilen, um den Clipspace zu erhalten.

Macht das Sinn? Schau dir das Diagramm noch einmal an. Angenommen, das blaue z war -5 und für ein bestimmtes Sichtfeld% y kam auf +2.34 . Wir müssen +2.34 in +1 Clipspace konvertieren. Die generische Version davon ist

clipY = KameraY * f / -z

Blick auf "makePerspective"

%Vor%

können wir in diesem Fall f sehen

%Vor%

ist eigentlich das Gleiche wie

%Vor%

Warum ist es so geschrieben? Ich schätze, denn wenn du den ersten Stil hättest und die Bräune auf 0 hinausgezählt hast, würdest du durch 0 dividieren. Dein Programm würde abstürzen. Wenn du es tust, gibt es keine Teilung, also keine Chance für eine Division durch Null.

Wenn -1 in matrix[11] spot steht, bedeutet dies, dass wir fertig sind

%Vor%

Für clipX machen wir grundsätzlich genau die gleiche Berechnung außer skaliert für das Seitenverhältnis.

%Vor%

Schließlich müssen wir cameraZ in der -zNear & lt; - & gt; -zFar Bereich zu ClipZ in der -1 & lt; - & gt; + 1 Bereich.

Die Standardperspektivenmatrix tut dies mit einer reziproken Funktion , so dass z-Werte schließen, wenn die Kamera mehr Auflösung erhält als z Werte weit von der Kamera entfernt. Diese Formel ist

%Vor%

Verwenden wir s für something und c für Konstante.

%Vor%

und lösen für s und c . In unserem Fall wissen wir

%Vor%

Also, bewege das 'c' auf die andere Seite

%Vor%

Multiplizieren Sie mit -zXXX

%Vor%

Diese 2 Dinge sind jetzt so gleich.

%Vor%

erweitern Sie die Mengen

%Vor%

vereinfachen

%Vor%

verschiebe zNear nach rechts

%Vor%

verschiebe c * zFar nach links

%Vor%

vereinfachen

%Vor%

dividiere durch (zNear - zFar)

%Vor%

löse für s

%Vor%

vereinfachen

%Vor%

ändere 1 in (zNear - zFar)

%Vor%

vereinfachen

%Vor%

vereinfachen Sie etwas mehr

%Vor%

dang Ich wünsche stackexchange unterstützte Mathe wie ihre Matheseite: (

Also zurück nach oben. Unser Forum war

%Vor%

Und wir kennen jetzt s und c .

%Vor%

Lassen Sie uns das -Z nach draußen bewegen

%Vor%

wir können / (zNear - zFar) zu * 1 / (zNear - zFar) so ändern

%Vor%

Wenn wir auf makeFrustum zurückblicken, sehen wir, dass es am Ende

enden wird %Vor%

Mit Blick auf die obige Formel passt

%Vor%

Ich hoffe, das ergab einen Sinn. Hinweis: Das meiste ist nur meine Neufassung von Dieser Artikel .

    
gman 03.02.2015, 14:23
quelle
0

f ist ein Faktor, der die Y-Achse skaliert, so dass alle Punkte entlang der oberen Ebene Ihres Sichtkegelstumpfes, Post-Perspektive-Teilung, eine y-Koordinate von 1 haben, und jene auf der unteren Ebene eine y-Koordinate von -1. Versuchen Sie, Punkte entlang einer dieser Ebenen einzubauen (Beispiele: 0, 2.41, 1 , 2, 7.24, 3 ) und Sie können sehen, warum dies passiert: weil es mit der Vorteilung y gleich dem homogenen w endet.

    
Sneftel 02.02.2015 20:30
quelle