Як отримати переклад з матриці перегляду


11

Як я можу отримати положення світового простору камери з матриці її перегляду? Єдині відповіді, які я бачив на це питання, дозволяють припустити, що переклад знаходиться в останньому рядку / col, але це не працює, оскільки матриця містить [x (крапка) право, y (крапка) вгору, z (точка) погляд]

Відповіді:


10

Коротка відповідь

Спочатку переверніть матрицю перегляду. Потім вийміть переклад з останнього рядка / стовпця.

Довга відповідь

Один із способів вивести вміст матриці перегляду - це почати з розгляду камери як будь-якого іншого об'єкта у світі та обчислення для неї світової матриці:

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

Світова матриця перетворює координати з місцевого простору в світовий простір. Але в цьому випадку локальний простір камери та простір перегляду - це одне і те ж, тому ми можемо також сказати, що ця матриця перетворює координати з простору зору в простір світу.

Оскільки нам потрібне перетворення у зворотному напрямку, ми маємо інвертувати матрицю. У результаті ми називаємо матрицю подання, яка перетворює координати зі світового простору в простір:

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

І ось така матриця у вас є. Отже, щоб повернути з нього положення камери, спочатку потрібно буде її перевернути, а потім можна захопити переклад з останнього ряду (або стовпця залежно від системи).


1
Навіщо спочатку інвертувати матрицю? Якщо ви (сподіваємось) знаєте, чи знаходитесь ви в рядку-мажор чи стовпчик-головний, розташування вектора перекладу має бути очевидним.
3Dave

7

Спочатку я б настійно рекомендував просто зберігати позицію як вектор окремо, це полегшить обчислення набагато простіше. Все одно ...

[x (dot) right, y (dot) up, z (dot) look]не є фактичною матрицею перегляду. Сама матриця має вигляд:

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

де лівий верхній 3x3 матриця відображає обертання, масштаб тощо. Усі орієнтації камери зроблені там. Решта та стовпець, що залишився, використовуються для перекладу та деяких інших складних перспективних матеріалів, у які я зараз не збираюся вступати.

Коли ви отримуєте матрицю (якщо припустити, що це матриця 4x4), переклад завжди зберігатиметься або в останньому рядку, або в останньому стовпчику, залежно від того, чи є ваш матричний клас строковим чи головним стовпчиком.

Те, що ви, мабуть, плутаєтесь - це той факт, що вам потрібні крапки. У цьому питанні є спрощення математики матриці, у цьому питанні щодо переповнення стека є більш детальні відповіді: /programming/349050/calculating-a-lookat-matrix

Вирішення можна знайти тут , вам потрібно взяти обернену матрицю і отримати переклад цього:

Vector3 ViewTrans = Matrix.Invert(ViewMatrix).Translation;
Position = ViewTrans;

5

Інші відповіді тут пояснюють, як отримати положення камери з матриці камери назад.

Якщо частина 3x3 матриці камери має лише обертання (без масштабування чи зсуву), як це зазвичай робиться, обчислення можна оптимізувати, помноживши переклад матриці камери на переміщення обертання камери. Потім положення камери - це перетворений вектор перекладу, помножений на -1. У GLSL це:

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

або

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

Це те, що я використовував у своїх вершинних шейдерах, якщо я не хочу обчислювати та передавати положення камери як єдину форму.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.