Cómo obtener la traducción de la matriz de vista

11

¿Cómo puedo recuperar la posición del espacio mundial de la cámara desde su matriz de vista? Las únicas respuestas que he visto a esta pregunta sugieren que la traducción está en la última fila / columna, pero esto no funcionaría ya que la matriz contiene [x (punto) a la derecha, y (punto) arriba, aspecto z (punto)]

nuit5
fuente

Respuestas:

10

Respuesta corta

Primero invierta la matriz de vista. Luego busque la traducción de la última fila / columna.

Respuesta larga

Una forma de deducir el contenido de una matriz de vista es comenzar por considerar la cámara como cualquier otro objeto en el mundo y calcular una matriz mundial para ella:

RightX  RightY  RightZ  0
UpX     UpY     UpZ     0
LookX   LookY   LookZ   0
PosX    PosY    PosZ    1

Una matriz mundial transforma las coordenadas del espacio local en el espacio mundial. Pero en este caso, el espacio local de la cámara y el espacio de visualización son uno y el mismo, por lo que también podemos decir que esta matriz transforma las coordenadas del espacio de visualización al espacio mundial.

Como necesitamos una conversión en la dirección opuesta , tenemos que invertir la matriz. El resultado es lo que llamamos la matriz de vista que transforma las coordenadas del espacio mundial para ver el espacio:

   RightX        UpX        LookX      0
   RightY        UpY        LookY      0
   RightZ        UpZ        LookZ      0
-(Pos*Right)  -(Pos*Up)  -(Pos*Look)  1      // * = dot product

Y ese es el tipo de matriz que tienes. Entonces, para recuperar la posición de la cámara, primero deberá invertirla, y luego puede tomar la traducción de la última fila (o columna, según el sistema).

David Gouveia
fuente
1
¿Por qué invertir la matriz primero? Si (con suerte) sabe si está en fila mayor o columna mayor, la ubicación del vector de traducción debería ser obvia.
3Dave
7

En primer lugar, recomendaría ALTAMENTE almacenar la posición como un vector por separado, hará las cosas mucho más fáciles computacionalmente. De todos modos ...

[x (dot) right, y (dot) up, z (dot) look]no es la matriz de vista real. La matriz en sí es de la forma:

1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1

donde la matriz superior izquierda de 3x3 representa rotaciones, escala, etc. Toda la orientación de la cámara se realiza allí. La fila y la columna restantes se usan para la traducción y algunas otras cosas de perspectiva complicadas que no voy a abordar en este momento.

Cuando obtiene la matriz (suponiendo que sea una matriz 4x4), la traducción siempre se almacenará en la última fila o en la última columna, dependiendo de si su clase de matriz está ordenada por fila mayor o columna mayor.

Lo que probablemente te esté confundiendo es el hecho de que necesitas los productos de punto. Lo que está sucediendo es la simplificación de las matemáticas de la matriz, hay respuestas más detalladas en esta pregunta de desbordamiento de pila: /programming/349050/calculating-a-lookat-matrix

La solución se puede encontrar aquí , debe tomar el inverso de la matriz y obtener la traducción de eso:

Vector3 ViewTrans = Matrix.Invert(ViewMatrix).Translation;
Position = ViewTrans;
Robert Rouhani
fuente
5

Otras respuestas aquí explican cómo obtener la posición de la cámara desde la matriz de la cámara inversa.

Si la parte de 3x3 de la matriz de la cámara solo tiene rotación (sin escala ni cizallamiento) como suelen hacer, el cálculo puede optimizarse multiplicando la traducción de la matriz de la cámara con la transposición de la rotación de la cámara. La posición de la cámara es entonces el vector de traducción transformado multiplicado por -1. En GLSL esto es:

vec3 cameraPosition = -transpose(mat3(worldToCameraMatrix)) * worldToCameraMatrix[3].xyz;

o

vec3 cameraPosition = -worldToCameraMatrix[3].xyz * mat3(worldToCameraMatrix);

Esto es lo que he estado usando en mis sombreadores de vértices si no quiero calcular y pasar la posición de la cámara como uniforme.

msell
fuente