web-dev-qa-db-fra.com

Calculer une matrice LookAt

Je suis en train d'écrire un moteur 3D et je suis tombé sur l'algorithme LookAt décrit dans la documentation DirectX:

zaxis = normal(At - Eye)
xaxis = normal(cross(Up, zaxis))
yaxis = cross(zaxis, xaxis)

 xaxis.x           yaxis.x           zaxis.x          0
 xaxis.y           yaxis.y           zaxis.y          0
 xaxis.z           yaxis.z           zaxis.z          0
-dot(xaxis, eye)  -dot(yaxis, eye)  -dot(zaxis, eye)  l

Je comprends maintenant comment cela fonctionne du côté de la rotation, mais ce que je ne comprends pas très bien, c’est la raison pour laquelle la composante de traduction de la matrice est transformée en produit scalaire. En l'examinant un peu, il semble que la position de la caméra est légèrement modifiée en fonction d'une projection des nouveaux vecteurs de base sur la position de l'œil/de la caméra.

La question est pourquoi faut-il faire cela? Qu'est-ce que cela accomplit?

32
Daemin

Je construis une matrice de référence en créant une matrice de rotation 3x3 comme vous l'avez fait ici, puis en l'élargissant à un 4x4 avec des zéros et le simple 1 dans le coin inférieur droit. Ensuite, je construis une matrice de traduction 4x4 en utilisant les coordonnées du point de l'œil négatif (pas de produit scalaire), puis je multiplie les deux matrices. Mon hypothèse est que cette multiplication donne l'équivalent des produits scalaires dans la dernière ligne de votre exemple, mais il faudrait que je travaille sur papier pour en être sûr.

La rotation 3D transforme vos axes. Par conséquent, vous ne pouvez pas utiliser directement le point de vision sans le transformer également en ce nouveau système de coordonnées. C'est ce que les multiplications matricielles - ou dans ce cas, les 3 valeurs du produit scalaire - accomplissent.

16
Judge Maygarden

Notez que l'exemple donné est une matrice principale pour gauchers, rangée .

L’opération est donc la suivante: Traduisez d’abord l’origine (déplacez de -œil), puis faites-le pivoter de sorte que le vecteur de œil à At soit aligné avec + z :

Fondamentalement, vous obtenez le même résultat si vous pré-multipliez la matrice de rotation par une traduction -eye:

 [1 0 0 0] [xaxis.x yaxis.x zaxis.x 0] 
 [0 1 0 0] * [xaxis.y yaxis.y zaxis.y 0] 
 [0 0 1 0] [xaxis.z yaxis.z zaxis.z 0] 
 [-Eye.x -eye.y -eye.z 1] [0 0 0 1] .______. [xaxis.x yaxis.x zaxis.x 0] 
 = [xaxis.y yaxis.y zaxis.y 0] 
 [xaxis.z yaxis.z zaxis.z 0] 
 [dot (xaxis, -eye) dot (yaxis, -eye) dot (zaxis, -eye) 1] 

Notes complémentaires:

Notez qu'une transformation de visualisation est (intentionnellement) inversée : vous multipliez chaque sommet par cette matrice pour "déplacer le monde" de sorte que la partie que vous souhaitez voir se retrouve dans le volume de la vue canonique.

Notez également que le composant de matrice de rotation (appelez-le R) de la matrice LookAt est une matrice changement de base inversé} où les lignes de R sont les nouveaux vecteurs de base en fonction des anciens vecteurs de base (d'où les noms de variables xaxis.x, .. xaxis étant l'axe nouveau x après le changement de base). En raison de l'inversion, toutefois, les lignes et les colonnes sont transposées.

46
bobobobo

Ce composant de traduction vous aide en créant une base orthonormale avec votre "œil" à l'origine et tout le reste exprimé en termes d'origine (votre "œil") et des trois axes.

Le concept n'est pas tellement que la matrice ajuste la position de la caméra. Il s'agit plutôt d'essayer de simplifier les calculs: lorsque vous voulez rendre une image de tout ce que vous pouvez voir depuis votre position "œil", il est plus facile de prétendre que votre œil est le centre de l'univers. 

Donc, la réponse courte est que cela rend les calculs beaucoup plus faciles. 

Répondre à la question dans le commentaire: la raison pour laquelle vous ne soustrayez pas simplement la position "œil" de tout est liée à l'ordre des opérations. Pensez-y de la manière suivante: une fois que vous êtes dans le nouveau cadre de référence (c’est-à-dire la position de la tête représentée par xaxis, yaxis et zaxis), vous souhaitez maintenant exprimer les distances en fonction de ce nouveau cadre de référence (pivoté). C'est pourquoi vous utilisez le produit scalaire des nouveaux axes avec la position de l'œil: cela représente la même distance que celle que les choses doivent parcourir, mais le nouveau système de coordonnées est utilisé.

3
Bob Cross

Quelques informations générales:

La matrice lookat est une matrice qui positionne/fait pivoter quelque chose vers (regarder) un point dans l'espace, à partir d'un autre point dans l'espace.

La méthode prend un "centre" souhaité de la vue caméras, un vecteur "haut", qui représente la direction "haut" de la caméra (haut est presque toujours (0,1,0), mais il n'est pas nécessaire ), et un vecteur "œil" qui est l'emplacement de la caméra.

Ceci est utilisé principalement pour la caméra, mais peut également être utilisé pour d'autres techniques telles que les ombres, les projecteurs, etc.

Franchement, je ne suis pas tout à fait sûr de savoir pourquoi le composant de traduction est défini comme dans cette méthode. Dans gluLookAt (à partir d'OpenGL), le composant de traduction est défini sur 0,0,0 car la caméra est toujours considérée comme étant à 0,0,0.

3
TM.

Le produit ponctuel projette simplement un point sur un axe pour obtenir la composante x, y ou z de l'œil. Vous déplacez l'appareil photo vers l'arrière de sorte que regarder (0, 0, 0) de (10, 0, 0) et de (100000, 0, 0) aurait un effet différent.

2
Eugene Yokota

Une matrice de transformation 4x4 contient deux-trois composantes: 1. matrice de rotation 2. traduction à ajouter . 3. échelle (de nombreux moteurs ne l'utilisent pas directement dans la matrice).

La combinaison des eux transformerait un point de l'espace A en espace B, il s'agit donc d'une matrice de transformation M_ab

Maintenant, l'emplacement de la caméra est dans l'espace A et il ne s'agit donc pas de la transformation valide pour l'espace B. Vous devez donc multiplier cet emplacement par la transformation de rotation.

La seule question qui reste posée est de savoir pourquoi les points? ?__. Eh bien, si vous écrivez les 3 points sur un papier, vous découvrirez que 3 points avec X, Y et Z est exactement comme une multiplication avec une matrice de rotation.

Un exemple pour cette quatrième ligne/colonne serait de prendre le point zéro - (0,0,0) dans l’espace mondial. Ce n’est pas le point zéro dans l’espace de la caméra, vous devez donc savoir quelle est sa représentation dans l’espace de la caméra, car la rotation et l’échelle laissent à zéro!

à votre santé

1
Adi

La matrice lookat effectue ces deux étapes:

  1. Traduire votre modèle à l'origine,
  2. Faites-le pivoter en fonction de l’orientation définie par le vecteur ascendant et le regard.
    direction.

Le produit scalaire signifie simplement que vous faites d'abord une traduction puis une rotation. Au lieu de multiplier deux matrices, le produit scalaire multiplie simplement une ligne avec une colonne.

1
Kalle

Il est nécessaire de placer le point de l'oeil dans votre espace des axes, pas dans l'espace du monde. Lorsque vous parlez un vecteur avec un vecteur de base d'unité de coordonnée, l'un des x, y, z, il vous donne les coordonnées de l'oeil dans that space. Vous transformez l'emplacement en appliquant les trois traductions à la dernière place, dans ce cas la dernière ligne. Ensuite, déplacer l'œil en arrière avec un négatif revient à déplacer tout le reste de l'espace vers l'avant. Comme si vous montiez dans un ascenseur, vous vous sentirez comme si le reste du monde se retirait de vous.

L'utilisation d'une matrice gauchère, avec la traduction comme dernière ligne droite au lieu de la dernière colonne, est une différence religieuse qui n'a absolument rien à voir avec la réponse. Cependant, c'est un dogme qui devrait être strictement évité. Il est préférable d’enchaîner les transformations globales-locales (cinématique directe) de gauche à droite, dans un ordre de lecture naturel, lors de la création d’esquisses. L'utilisation de matrices gaucher vous oblige à les écrire de droite à gauche. 

0
DragonLord