Ich versuche das OpenGL-Koordinatensystem zu verstehen. In einigen Tutorials wird jedoch angegeben, dass das Standardkoordinatensystem Linkshänder ist (siehe http://www.c-sharpcorner.com/UploadFile/jeradus/OpenGLBasics11172005014307AM/OpenGLBasics.aspx ), in anderen wird angegeben, dass es Rechtshänder ist (siehe http: // www .falloutsoftware.com / tutorials / gl / gl0.htm ). Welches ist richtig? Ich verstehe, dass wir durch Spiegeln eins in das andere transformieren können, aber ich würde gerne die Standardkoordinaten kennen.
opengl
coordinates
341008
quelle
quelle
Antworten:
Hier gibt es einige Verwirrung.
OpenGL ist im Objekt- und Weltraum rechtshändig .
Aber im Fensterbereich (auch bekannt als Bildschirmbereich) sind wir plötzlich Linkshänder .
Wie ist das passiert ?
Die Art und Weise, wie wir von Rechtshänder zu Linkshänder gelangen, ist ein negativer Z-Skalierungseintrag in den
glOrtho
oderglFrustum
Projektionsmatrizen. Das Skalieren von z um -1 (wobei x und y unverändert bleiben) bewirkt eine Änderung der Händigkeit des Koordinatensystems.Für glFrustum,
weit und in der Nähe sollen positiv sein, mit weit > in der Nähe . Sagen Sie fern = 1000 und nah = 1. Dann ist C = - (1001) / (999) = -1,002.
Sehen Sie hier , um weitere Informationen und Diagramme.
Aus orthographischer Sicht generiert glOrtho eine Matrix wie folgt:
Hier sind links , rechts , unten und oben nur die Koordinaten für die linke vertikale , rechte vertikale , untere horizontale und obere horizontale Schnittebene (bzw.) .
Die nahen und fernen Ebenen sind jedoch unterschiedlich spezifiziert . Der in der Nähe Parameter ist definiert als
und weit:
Hier haben wir ein typisches kanonisches Ansichtsvolumen
Da der z-Multiplikator (-2 / (nah-nah)) ist, skaliert das Minuszeichen z effektiv um -1 . Dies bedeutet, dass "z" während der Betrachtungstransformation nach links gedreht wird , ohne dass dies den meisten Menschen bekannt ist, da sie in OpenGL einfach als "rechtshändiges" Koordinatensystem arbeiten.
Also, wenn Sie anrufen
Dann ist das NEAR PLANE 10 Einheiten vor Ihnen . Wo bist du? Warum am Ursprung mit der x-Achse rechts von Ihnen, der y-Achse oben auf Ihrem Kopf und Ihrer Nase nach unten auf der negativen z-Achse (das ist die Standardeinstellung "Standardmäßig befindet sich die Kamera am Ursprung zeigt auf die negative z-Achse und hat einen Aufwärtsvektor von (0, 1, 0). " ). Die nahe Ebene liegt also bei z = -10. Die entfernte Ebene liegt 10 Einheiten hinter Ihnen, bei z = + 10 .
quelle
gluLookAt
Berechnung hat nichts mit dem Ändern der Händigkeit des Koordinatenraums zu tun. Genau so wird diese Matrix berechnet (und tatsächlich ist + z im rechtshändigen Raum tatsächlich "rückwärts" ).gluLookAt
tut nichts anderes als eine gewöhnliche Starrkörper-Transformation (Rotation + Translation) im rechtshändigen Raum zu berechnen. Es sind die Projektionsmatrizen, die von der Pipeline mit festen Funktionen (und normalerweise auch von Shadern) verwendet werden, die die tatsächliche Änderung der Händigkeit bei der Negation der Z-Komponente durchführen, wie Sie bereits in Ihrer Antwort festgestellt haben.gluLookAt
keine Änderung der Basis geben, währendgluLookAt
eine? Auf jeden Fall nicht (da Sie wahrscheinlich nicht wissen „alle“ AnwendungengluLookAt
für Ansicht Matrixberechnung), da , wie Sie wissen sollten ,gluLookAt
tut nichts anderes , als ein Bündel von Rotation und Translation Anrufe (werden sie auch als verkleidete „high level“ Begriff „Wechsel Basis " ) ohne jegliche Überlegungen.Standardmäßig ist die normalisierte Gerätekoordinate Linkshänder.
Der glDepthRange ist standardmäßig [0, 1] (nah, fern), sodass die + z-Achse in den Bildschirm zeigt und mit + x nach rechts und + y nach oben ein linkshändiges System ist.
Durch Ändern des Tiefenbereichs auf [1, 0] wird das System rechtshändig.
Ich zitiere eine frühere Antwort von Nicol : (Der Durchschlag ist meine Arbeit, die unten erklärt wird.)
Ich habe einen Teil geschlagen, da er von meinen Erkenntnissen abwich.
Entweder das Ändern des DepthRange oder des DepthFunc und das Verwenden von ClearDepth (0) funktioniert, aber wenn beide verwendet werden, heben sie sich gegenseitig auf ein linkshändiges System auf.
quelle
NUR NDC
Sie sollten nur beachten, dass OpenGL nur NDC kennt! und das ist ein linkshändiges Koordinatensystem.
Unabhängig davon, welches Koordinatensystem Sie verwenden - linkshändiges oder rechtshändiges Achsenkoordinatensystem - müssen alle in NDC gespiegelt werden. Wenn Sie möchten, können Sie den Weltraum vollständig als linkshändiges Koordinatensystem behandeln.
Warum verwenden wir normalerweise ein rechtshändiges Koordinatensystem im Weltraum?
Ich denke es ist konventionell. Es tut es einfach. Vielleicht möchte es nur von DirectX unterscheiden.
quelle
Das Buch "WebGl Programming Guide" von Kouichi Matsuda widmet fast zehn Seiten "WebGl / OpenGl: Links- oder Rechtshänder?"
Nach dem Buch:
In der Praxis verwenden die meisten Menschen ein rechtshändiges System
OpenGl ist intern ein linkshändiges System
Intern ist es eigentlich keines von beiden. Ganz unten kümmert sich OpenGl nicht um den Z-Wert. Die Reihenfolge, in der Sie Dinge zeichnen, bestimmt, was oben gezeichnet wird (zeichnen Sie zuerst ein Dreieck, dann ein Quad, das Quad überschreibt das Dreieck).
Ich stimme dem "es ist auch nicht" nicht ganz zu, aber das ist wahrscheinlich sowieso eine philosophische Frage.
quelle
The order in which you draw things determines what is drawn on top (draw a triangle first, then a quad, the quad overrides the triangle).
Dies gilt auch ohne Tiefenprüfung. Bei Tiefenprüfungen wird der z-Wert eines Fragments mit dem Wert im Tiefenpuffer verglichen und das Fragment verworfen, wenn es die Tiefenprüfung nicht besteht, sodass das Quad das Dreieck je nach Tiefe und Tiefe überschreiben kann oder nicht Tiefenfunktion verwendet.Opengl ist definitiv Linkshänder. Sie sehen viele Tutorials, die das Gegenteil angeben, weil sie den Z-Wert in der Projektionsmatrix negieren. Wenn die endgültigen Scheitelpunkte im Scheitelpunkt-Shader berechnet werden, werden die Scheitelpunkte, die Sie von der Clientseite (rechte Koordinate) übergeben, in Linkshänder konvertiert. Die Scheitelpunkte werden dann an den Geometrie-Shader und den Fragment-Shader übergeben. Wenn Sie auf der Clientseite das rechte Koordinatensystem verwenden, ist Opengl das egal. Es kennt nur das normalisierte Koordinatensystem, das Linkshänder ist.
Bearbeiten: Wenn Sie mir nicht vertrauen, experimentieren Sie einfach in Ihrem Vertex-Shader, indem Sie eine Übersetzungsmatrix hinzufügen, und Sie können leicht erkennen, ob Opengl Linkshänder ist oder nicht.
quelle
Durch die Verwendung der in OpenGL integrierten Projektions- und Transformationsfunktionen folgt die Beobachtung der Bewegungen auf dem Bildschirm den Regeln des rechtshändigen Koordinatensystems. Wenn beispielsweise ein Objekt vor Ihrer Ansicht in die positive z-Richtung verschoben wird, bewegt sich das Objekt auf Sie zu.
Der Tiefenpuffer ist genau das Gegenteil, und hier kommen die NDC (Normalized Device Coordinates) ins Spiel. Wenn die Übergabe von GL_LESS an glDepthFunc bedeutet, dass Pixel gezeichnet werden, wenn sie näher an Ihnen sind als das, was sich bereits im Tiefenpuffer befindet, werden Pixel als in einem linkshändigen Koordinatensystem lebend betrachtet.
Es gibt noch ein Koordinatensystem, und das ist das Ansichtsfenster! Das Koordinatensystem des Ansichtsfensters ist so, dass + x nach rechts und + y nach unten zeigt. Ich denke zu diesem Zeitpunkt ist die Händigkeit umstritten, da wir uns an dieser Stelle nur mit x, y befassen.
Schließlich muss gluLookAt unter der Haube den Betrachtungsvektor negieren. Da die Mathematik davon ausgeht, dass ein Vektor in eine positive Richtung auf das Objekt zeigt, auf das er schaut, und eine Kamera nach unten -z schaut, muss der Betrachtungsvektor negiert werden, damit er mit der Kamera ausgerichtet ist.
Etwas zum Kauen. Es macht wenig Sinn, die z-Richtung eines rechtshändigen Koordinatensystems als Vorwärtsvektor zu bezeichnen :). Ich denke, Microsoft hat dies erkannt, als sie Direct3D entwickelten.
quelle