Cálculo de una matriz LookAt

Estoy escribiendo un motor en 3D y me encontré con el algoritmo LookAt descrito en la documentación de 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 

Ahora entiendo cómo funciona en el lado de la rotación, pero lo que no entiendo es por qué pone el componente de traducción de la matriz como esos productos de puntos. Al examinarlo un poco, parece que está ajustando la posición de la cámara en una pequeña cantidad en función de una proyección de los nuevos vectores de base sobre la posición del ojo / cámara.

La pregunta es por qué necesita hacer esto? ¿Qué logra?

Construyo una matriz de observación creando una matriz de rotación de 3×3 como lo has hecho aquí y luego expandiéndola a un 4×4 con ceros y al único 1 en la esquina inferior derecha. Luego construyo una matriz de traducción 4×4 utilizando las coordenadas negativas del punto del ojo (sin productos punto) y multiplico las dos matrices juntas. Mi suposición es que esta multiplicación produce el equivalente de los productos de puntos en la fila inferior de tu ejemplo, pero necesitaría resolverlo en papel para asegurarte.

La rotación 3D transforma tus ejes. Por lo tanto, no puede usar el punto del ojo directamente sin transformarlo en este nuevo sistema de coordenadas. Eso es lo que logran las multiplicaciones de la matriz, o en este caso, los 3 valores del producto punto.

Tenga en cuenta que el ejemplo dado es una matriz principal de filas zurdas .

Entonces la operación es: Traduce al origen primero (mueve by- eye ), luego gira para que el vector del ojo a A se alinee con + z:

Básicamente obtienes el mismo resultado si pre-multiplicas la matriz de rotación por una traducción – ojo :

 [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]
   [punto (xaxis, -eye) punto (yaxis, -eye) punto (zaxis, -eye) 1]

Notas adicionales:

Tenga en cuenta que una transformación de visualización se invierte (intencionalmente): se multiplica cada vértice por esta matriz para “mover el mundo” de modo que la parte que desea ver termine en el volumen de vista canónica.

También tenga en cuenta que el componente matriz de rotación (llamarlo R ) de la matriz LookAt es una matriz de cambio de base invertida donde las filas de R son los nuevos vectores base en términos de los viejos vectores base (de ahí los nombres de variables xaxis.x,. .xaxis es el nuevo eje x después de que se produce el cambio de base). Debido a la inversión, sin embargo, las filas y columnas se transponen.

Solo algo de información general:

La matriz lookat es una matriz que posiciona / gira algo para señalar (mirar) un punto en el espacio, desde otro punto en el espacio.

El método toma un “centro” deseado de la vista de las cámaras, un vector “arriba”, que representa la dirección “arriba” para la cámara (la subida es casi siempre (0,1,0), pero no tiene que ser ), y un vector “ojo” que es la ubicación de la cámara.

Esto se usa principalmente para la cámara, pero también se puede usar para otras técnicas como sombras, focos, etc.

Francamente, no estoy del todo seguro de por qué el componente de traducción se está configurando como está en este método. En gluLookAt (desde OpenGL), el componente de traducción se establece en 0,0,0 ya que la cámara se ve siempre a 0,0,0.

El producto de puntos simplemente proyecta un punto en un eje para obtener el componente x, yy z del ojo. Está moviendo la cámara hacia atrás, por lo que mirar (0, 0, 0) desde (10, 0, 0) y desde (100000, 0, 0) tendría un efecto diferente.

Ese componente de traducción lo ayuda creando una base ortonormal con su “ojo” en el origen y todo lo demás expresado en términos de ese origen (su “ojo”) y los tres ejes.

El concepto no es tanto que la matriz esté ajustando la posición de la cámara. Más bien, está tratando de simplificar las matemáticas: cuando quieres representar una imagen de todo lo que puedes ver desde tu posición de “ojo”, es más fácil pretender que tu ojo es el centro del universo.

Entonces, la respuesta corta es que esto hace que las matemáticas sean mucho más fáciles.

Respondiendo a la pregunta en el comentario: la razón por la que no solo resta la posición “ojo” de todo tiene que ver con el orden de las operaciones. Piénselo de esta manera: una vez que está en el nuevo marco de referencia (es decir, la posición de la cabeza representada por xaxis, yaxis y zaxis), ahora quiere express las distancias en términos de este nuevo marco de referencia (girado). Es por eso que utiliza el producto escalar de los nuevos ejes con la posición del ojo: eso representa la misma distancia que las cosas necesitan moverse, pero usa el nuevo sistema de coordenadas.

La matriz de lookat hace estos dos pasos:

  1. Traduzca su modelo al origen,
  2. Gírelo según la orientación configurada por el vector ascendente y el aspecto
    dirección.

El producto punto significa simplemente que primero haces una traducción y luego giras. En lugar de multiplicar dos matrices, el producto punto simplemente multiplica una fila con una columna.

Una matriz de transformación 4×4 contiene dos o tres componentes: 1. matriz de rotación 2. traducción para agregar. 3. escala (muchos motores no usan esto directamente en la matriz).

La combinación de ellos transformaría un punto del espacio A al Espacio B, por lo tanto, esta es una matriz de transformación M_ab

Ahora, la ubicación de la cámara está en el espacio A y, por lo tanto, no es la transformación válida para el espacio B, por lo que debe multiplicar esta ubicación con la transformación de rotación.

La única pregunta abierta que queda es por qué los puntos? Bueno, si escribes los 3 puntos en un papel, descubrirás que 3 puntos con X, Y y Z son exactamente como la multiplicación con una matriz de rotación.

Un ejemplo para esa cuarta fila / columna sería tomar el punto cero – (0,0,0) en el espacio mundial. No es el punto cero en el espacio de la cámara, por lo que necesita saber cuál es la representación en el espacio de la cámara, ya que la rotación y la escala lo dejan en cero.

aclamaciones

Es necesario poner el punto del ojo en el espacio del eje, no en el espacio del mundo. Cuando puntea un vector con un vector base de unidad de coordenadas, uno de los x, y, z, le da las coordenadas del ojo en ese espacio. Transforma la ubicación aplicando las tres traducciones en el último lugar, en este caso, la última fila. Luego, mover el ojo hacia atrás, con un negativo, es equivalente a mover todo el rest del espacio hacia delante. Al igual que subir en un ascensor te hace sentir que el rest del mundo te está saliendo por debajo.

Usar una matriz para zurdos, con la traducción como la última fila en lugar de la última columna, es una diferencia religiosa que no tiene absolutamente nada que ver con la respuesta. Sin embargo, es un dogma que debe ser estrictamente evitado. Lo mejor es encadenar transformaciones de global a local (cinemática directa) de izquierda a derecha, en un orden de lectura natural, al dibujar bocetos de árbol. El uso de matrices zurdas te obliga a escribir estas de derecha a izquierda.