J'essaie de comprendre le système de coordonnées OpenGL. Cependant, certains tutoriels disent que le système de coordonnées par défaut est gaucher (voir http://www.c-sharpcorner.com/UploadFile/jeradus/OpenGLBasics11172005014307AM/OpenGLBasics.aspx ) et d'autres disent qu'il est droitier (voir http: // www .falloutsoftware.com / tutoriels / gl / gl0.htm ). Qui est correct? Je comprends que nous pouvons transformer l'un en l'autre par mise en miroir mais j'aimerais connaître les coordonnées par défaut.
opengl
coordinates
341008
la source
la source
Réponses:
Il y a une certaine confusion ici.
OpenGL est droitier dans l'espace objet et l'espace mondial.
Mais dans l'espace fenêtre (aka espace écran), nous sommes soudainement gauchers .
Comment est-ce arrivé ?
La façon dont nous passons de droitier à gaucher est une entrée de mise à l'échelle z négative dans les matrices de projection
glOrtho
ouglFrustum
. La mise à l'échelle de z par -1 (tout en laissant x et y tels quels) a pour effet de modifier la sensibilité du système de coordonnées.Pour glFrustum,
loin et proche sont supposés être positifs, avec loin > proche . Dites loin = 1000 et près = 1. Alors C = - (1001) / (999) = -1,002.
Voir ici pour plus de détails et de diagrammes.
D'un point de vue orthographique , glOrtho génère une matrice comme celle-ci:
Ici, à gauche , à droite , en bas et en haut sont seulement les coordonnées de gauche verticale , droite verticale , horizontale inférieure , supérieurs horizontaux plans de délimitation (resp) .
Les plans proche et éloigné , cependant, sont spécifiés différemment . Le paramètre proche est défini comme
et loin:
Ici, nous avons un volume de vue canonique typique
Comme le multiplicateur z est (-2 / (très proche)), le signe moins met effectivement à l'échelle z par -1 . Cela signifie que "z" est tourné à gauche pendant la transformation de visualisation, à l'insu de la plupart des gens car ils travaillent simplement dans OpenGL comme un système de coordonnées "droitier".
Donc, si vous appelez
Alors le PRÈS DE L'AVION a 10 unités devant vous . Où es-tu? Pourquoi, à l'origine, avec l'axe x à votre droite, l'axe y au-dessus de votre tête et votre nez pointant vers le bas l'axe z négatif (c'est la valeur par défaut "Par défaut, la caméra est située à l'origine , pointe vers le bas l'axe z négatif et a un vecteur ascendant de (0, 1, 0). " ). Le plan proche est donc à z = -10. Le plan lointain est à 10 unités derrière vous, à z = + 10 .
la source
gluLookAt
calcul n'a rien à voir avec le changement de la sensibilité de l'espace de coordonnées, c'est juste comme ça que cette matrice est calculée (et en fait + z est en effet "en arrière" dans l'espace droitier).gluLookAt
ne fait rien d'autre que de calculer une transformation de corps rigide ordinaire (rotation + translation) dans un espace droitier. Ce sont les matrices de projection utilisées par le pipeline de fonctions fixes (et généralement par les shaders aussi) qui effectuent le changement de caractère réel dans leur négation du composant z, comme vous l'avez déjà noté dans votre réponse.gluLookAt
, il n'y aurait pas de changement de base alorsgluLookAt
qu'il y en a un? Certainement pas (puisque vous savez probablement que "tout le monde" n'utilise pasgluLookAt
pour le calcul de la matrice de vue), car comme vous devriez le savoirgluLookAt
ne fait rien d'autre qu'un tas d'appels de rotation et de traduction (même déguisés en changement de " terme de haut niveau" base " ) sans aucune réflexion.Par défaut, la coordonnée normalisée de l'appareil est gaucher.
Le glDepthRange est par défaut [0, 1] (proche, loin) faisant pointer l'axe + z dans l'écran et avec + x à droite et + y en haut, c'est un système gaucher.
Changer la plage de profondeur sur [1, 0] rendra le système droitier.
Citant une réponse précédente de Nicol : (le barré est mon travail, expliqué ci-dessous)
J'ai frappé une partie car elle divergeait de mes conclusions.
Le changement de DepthRange ou de DepthFunc et l'utilisation de ClearDepth (0) fonctionnent mais lors de l'utilisation des deux, ils se sont annulés pour revenir à un système gaucher.
la source
UNIQUEMENT NDC
Vous devriez seulement remarquer qu'OpenGL ne connaît que NDC! et c'est un système de coordonnées gaucher.
Quel que soit le système de coordonnées que vous utilisez - système de coordonnées d'axe gauche ou droit - tous doivent être mis en miroir sur NDC. Si vous le souhaitez, vous pouvez totalement gérer l'espace-monde comme un système de coordonnées gaucher.
Pourquoi utilisons-nous généralement un système de coordonnées droitier dans l'espace-monde?
Je pense que c'est conventionnel. C'est juste le cas. Peut-être veut-il simplement faire la distinction avec DirectX.
la source
Le livre "WebGl Programming Guide" de Kouichi Matsuda consacre près de dix pages à "WebGl / OpenGl: Left or Right Handed?"
D'après le livre:
En pratique, la plupart des gens utilisent un système droitier
OpenGl est en fait un système pour gauchers en interne
En interne, plus profondément, ce n'est ni l'un ni l'autre. Tout en bas, OpenGl ne se soucie pas de la valeur z. L'ordre dans lequel vous dessinez les choses détermine ce qui est dessiné en haut (dessinez d'abord un triangle, puis un quad, le quad remplace le triangle).
Je ne suis pas entièrement d'accord avec le «ce n'est ni l'un ni l'autre», mais c'est probablement une question philosophique de toute façon.
la source
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).
C'est vrai, en l'absence de test de profondeur. En présence d'un test de profondeur, la valeur z d'un fragment est comparée à la valeur du tampon de profondeur, et le fragment est rejeté s'il échoue au test de profondeur, de sorte que le quad peut ou non écraser le triangle en fonction de sa profondeur et de la fonction de profondeur utilisée.Opengl est définitivement gaucher. Vous voyez de nombreux didacticiels indiquant le contraire car ils annulent la valeur z dans la matrice de projection. Lorsque les sommets finaux sont calculés à l'intérieur du vertex shader, il convertit les sommets que vous passez du côté client (coordonnée à droite) en gaucher, et les sommets seront ensuite passés au shader geometry et au fragment shader. Si vous utilisez le système de coordonnées de droite côté client, Opengl s'en fiche. Il ne connaît que le système de coordonnées normalisé, qui est gaucher.
Edit: Si vous ne me faites pas confiance, expérimentez simplement votre vertex shader en ajoutant une matrice de traduction, et vous pourrez facilement voir si Opengl est gaucher ou non.
la source
En utilisant les fonctions de projection et de transformation intégrées d'OpenGL, l'observation des mouvements à l'écran suit les règles du système de coordonnées droitier . Par exemple, si un objet devant votre vue est traduit dans la direction z positive, l'objet se déplacera vers vous.
Le tampon de profondeur est tout le contraire, et c'est là que les NDC (Normalized Device Coordinates) entrent en jeu. Si le fait de passer GL_LESS dans glDepthFunc signifie que les pixels seront dessinés lorsqu'ils seront plus proches de vous que ce qui se trouve déjà dans le tampon de profondeur, alors les pixels sont considérés comme vivant dans un système de coordonnées gaucher .
Il y a un autre système de coordonnées, et c'est la fenêtre! Le système de coordonnées de la fenêtre est tel que + x pointe vers la droite et + y pointe vers le bas. Je pense qu'à ce stade, la sensibilité est sans objet puisque nous n'avons affaire qu'à x, y à ce stade.
Enfin, gluLookAt sous le capot doit annuler le vecteur de regard. Étant donné que le calcul suppose qu'un vecteur pointe dans une direction positive vers l'objet qu'il regarde et qu'une caméra regarde vers le bas -z, le vecteur d'observation doit être annulé afin qu'il s'aligne avec la caméra.
Quelque chose à mâcher. Cela n'a pas beaucoup de sens d'appeler la direction z d'un système de coordonnées droitier un vecteur avant :). Je pense que Microsoft a réalisé cela quand ils ont conçu Direct3D.
la source