Ist das OpenGL-Koordinatensystem linkshändig oder rechtshändig?


84

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.



2
Hängt dies nicht ganz davon ab, wie Sie Ihre Transformationen in die Shader schreiben, und liegt daher ganz bei Ihnen?
Jcoder

Nur meine zwei Cent evl.uic.edu/ralph/508S98/coordinates.html , es hat ein paar selbsterklärende Bilder.
rraallvv

Ich nehme nicht an, dass Sie erwägen würden, Ihre akzeptierte Antwort zu aktualisieren?
Jonathan Mee

Antworten:


129

Hier gibt es einige Verwirrung.

Geben Sie hier die Bildbeschreibung ein

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 glOrthooder glFrustumProjektionsmatrizen. Das Skalieren von z um -1 (wobei x und y unverändert bleiben) bewirkt eine Änderung der Händigkeit des Koordinatensystems.

Für glFrustum,

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

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:

Geben Sie hier die Bildbeschreibung ein

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

  • Nah: Der Abstand zur Clipping-Ebene mit näherer Tiefe. Dieser Abstand ist negativ, wenn sich die Ebene hinter dem Betrachter befinden soll.

und weit:

  • zFar Der Abstand zur weiter entfernten Schnittebene. Dieser Abstand ist negativ, wenn sich die Ebene hinter dem Betrachter befinden soll.

Hier haben wir ein typisches kanonisches Ansichtsvolumen

kanonisch

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

glOrthof(-1, 1, -1, 1, 10, -10) ; // near=10, FAR=-10,

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 .


1
"Der Vorwärtsvektor wird in gluLookAt negiert" - können Sie bestätigen, dass dies der Fall ist? Nicht gluPerspective oder glFrustum oder glOrtho?
Kos

1
Ab dem Clip-Bereich sind wir plötzlich Linkshänder, nicht nur der Fensterbereich.
Legends2k

3
+1 für die gesamte Antwort, -1 (warten, eher -2) für "Die Art und Weise, wie wir von Rechtshänder zu Linkshänder gelangen, liegt darin, dass der Vorwärtsvektor in der Standardimplementierung von gluLookAt (), der Funktion, negiert wird Jeder erstellt die Ansichtsmatrix. Wenn Sie den Vorwärtsvektor negieren, ändert sich dadurch die Händigkeit des Koordinatensystems. " , das ist nur Müll ...
Christian Rau

2
... Das Negieren des Vorwärtsvektors in der gluLookAtBerechnung 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" ). gluLookAttut 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.
Christian Rau

2
@bobobobo Ihr Sprichwort: Wenn Sie Ihre Ansichtsmatrix nur mit Rotations- und Übersetzungsfunktionen berechnen (was Sie wohl nicht beschuldigen würden, die Händigkeit zu ändern), würde es stattdessen gluLookAtkeine Änderung der Basis geben, während gluLookAteine? Auf jeden Fall nicht (da Sie wahrscheinlich nicht wissen „alle“ Anwendungen gluLookAtfür Ansicht Matrixberechnung), da , wie Sie wissen sollten , gluLookAttut nichts anderes , als ein Bündel von Rotation und Translation Anrufe (werden sie auch als verkleidete „high level“ Begriff „Wechsel Basis " ) ohne jegliche Überlegungen.
Christian Rau

26

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 bin überrascht, dass niemand etwas erwähnt hat: OpenGL funktioniert auch in einem linkshändigen Koordinatensystem. Zumindest, wenn Sie mit Shadern arbeiten und den Standardtiefenbereich verwenden.

Sobald Sie die Pipeline mit festen Funktionen verworfen haben, beschäftigen Sie sich direkt mit "Clip-Space". Die OpenGL-Spezifikation definiert den Clip-Raum als ein homogenes 4D-Koordinatensystem. Wenn Sie den Transformationen durch normalisierte Gerätekoordinaten bis hinunter zum Fensterbereich folgen, finden Sie dies.

Der Fensterbereich befindet sich im Bereich der Pixel eines Fensters. Der Ursprung befindet sich in der unteren linken Ecke, wobei + Y nach oben und + X nach rechts geht. Das klingt sehr nach einem rechtshändigen Koordinatensystem. Aber was ist mit Z?

Der Standardtiefenbereich (glDepthRange) setzt den nahen Z-Wert auf 0 und den fernen Z-Wert auf eins . Das + Z entfernt sich also vom Betrachter.

Das ist ein linkshändiges Koordinatensystem. Ja, du kannstÄndern Sie den Tiefentest von GL_LESS in GL_GREATER undÄndern Sie den glDepthRange von [0, 1] in [1, 0]. Der Standardzustand von OpenGL ist jedoch die Arbeit in einem linkshändigen Koordinatensystem. Und keine der Transformationen, die erforderlich sind, um vom Clip-Raum zum Fensterraum zu gelangen, negiert das Z. Der Clip-Raum, die Ausgabe des Scheitelpunkt- (oder Geometrie-) Shaders, ist also ein linkshändiger Raum (irgendwie. Es ist also ein homogener 4D-Raum) Es ist schwer, die Händigkeit zu bestimmen.

Im Festfunktions - Pipeline, die Standard - Projektionsmatrizen (hergestellt von glOrtho, glFrustum und dergleichen) , all - Transformation von einem rechtshändigen Raum zu einem linkshändigen ein. Sie drehen die Bedeutung von Z um; Überprüfen Sie einfach die Matrizen, die sie erzeugen. Im Augenraum bewegt sich + Z auf den Betrachter zu; im Raum nach der Projektion bewegt es sich weg.

Ich vermute, Microsoft (und GLide) haben sich einfach nicht die Mühe gemacht, die Negation in ihren Projektionsmatrizen durchzuführen.

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.


Der Tiefenbereich kann nicht [1, -1] sein. Ich denke du meintest [1, 0]. Auch darauf wurde bereits hingewiesen .
Nicol Bolas

Ihre Antwort ist großartig, schade, dass es sich um eine DirectX-Frage handelt. Sie sollten sie hier erneut veröffentlichen!
Hultqvist

3
@SigTerm warum ist es Ihrer Meinung nach nicht wert, eine falsche Aussage zu korrigieren? Ich habe mehrere Stunden mit der Fehlerbehebung bei Scheitelpunktkoordinaten und der Erzeugung von Matrixrotationen verbracht, um herauszufinden, dass das Standardkoordinatensystem tatsächlich nicht rechtshändig war.
Hultqvist

1
Die Frage war, ob es sich um ein linkshändiges oder ein rechtshändiges System handelte. Diese Antwort enthält mehr Details als diese und erklärt zwei weitere Möglichkeiten, um sie rechtshändig zu machen. Das Hinzufügen eines -1 in einer Matrixtransformation ist eine weitere Möglichkeit, dies zu tun. Aber nichts davon ist wichtig, wenn Sie glauben, dass das System standardmäßig Rechtshänder ist. Sie können etwas nur ändern, wenn Sie wissen, woran Sie sich ändern. Still
hultqvist

1
Ich fand die Antwort sehr aufschlussreich und sie tauchte bei Suchanfragen auf, sodass es sich für mich gelohnt hat.
Lernen Sie OpenGL ES

13

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.


3
Ich denke, das wird nicht genug wiederholt. Alle diese Diagramme, die "Modellierungstransformation", "Ansichtstransformation" und "Perspektiventransformation" zeigen, zeigen nicht, dass sie kein wesentlicher Bestandteil von OpenGL sind. Sie können sogar alle Ihre Transformationen manuell durchführen, mit oder ohne Shader, mit oder ohne Matrizen.
Tom

3
Es könnte jedoch schöner sein, wenn Sie es wiederholen und die Wörter "normalisierte Gerätekoordinaten" einfügen.
Tommy

6
OpenGL ist einige Jahre älter als DirectX, daher hat OpenGL sicherlich nicht versucht, sich von DirectX zu unterscheiden. Der Hauptentwickler von DirectX, Alex St. John, sagte, dass die Entscheidung von Microsoft für ein linkshändiges Koordinatensystem "teilweise aus persönlichen Gründen" und "eine willkürliche Entscheidung" getroffen wurde.
Chris Nolet

Das ist nicht ganz richtig. OpenGL kennt auch das Beschneidungskoordinatensystem, da das Beschneiden darin erfolgt. Das Clip-Koordinatensystem hat die gleiche Händigkeit wie das NDC-Koordinatensystem.
Plasmacel

7

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.


6
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.
Chrisvarnz

3

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.


0

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.