Вычисление матрицы LookAt - PullRequest
       38

Вычисление матрицы LookAt

36 голосов
/ 08 декабря 2008

Я нахожусь в процессе написания трехмерного движка и натолкнулся на алгоритм LookAt, описанный в документации по 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

Теперь я понимаю, как это работает на стороне вращения, но я не совсем понимаю, почему он ставит компонент перевода матрицы в эти точечные продукты. Рассматривая его немного, кажется, что он немного регулирует положение камеры на основе проекции новых базисных векторов на положение глаза / камеры.

Вопрос в том, зачем это нужно делать? Что это делает?

Ответы [ 8 ]

49 голосов
/ 23 июля 2011

Обратите внимание, что приведенный пример представляет собой левую матрицу мажорных строк .

Итак, операция такова: сначала переведите в начало координат (переместитесь на - eye ), затем поверните так, чтобы вектор от eye до At выровнялся с + z:

По сути, вы получаете тот же результат, если предварительно умножить матрицу вращения на перевод - 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 ]

Дополнительные примечания:

Обратите внимание, что трансформация просмотра (преднамеренно) инвертирована : вы умножаете каждую вершину на эту матрицу, чтобы "переместить мир", чтобы часть, которую вы хотите увидеть, оказалась в объеме канонического представления.

Также обратите внимание, что компонент матрицы вращения (назовите ее R ) матрицы LookAt представляет собой инвертированное изменение базиса матрицы, где строки R новые базисные векторы в терминах старых базисных векторов (следовательно, имена переменных xaxis.x, .. xaxis - это ось new x после изменения базиса). Однако из-за инверсии строки и столбцы транспонируются.

16 голосов
/ 09 декабря 2008

Я строю матрицу наблюдения, создавая матрицу вращения 3x3, как вы сделали здесь, а затем расширяя ее до 4x4 с нулями и одиночной 1 в нижнем правом углу. Затем я строю матрицу перевода 4x4, используя отрицательные координаты точки зрения (без точечных произведений), и умножаю две матрицы вместе. Я предполагаю, что это умножение дает эквивалент точечных произведений в нижнем ряду вашего примера, но мне нужно было бы проработать это на бумаге, чтобы убедиться.

Вращение 3D преобразует ваши оси. Следовательно, вы не можете использовать точку глаза напрямую, не преобразовав ее в эту новую систему координат. Это то, что умножение матрицы - или в этом случае, 3 значения продукта точки - достигают.

3 голосов
/ 09 декабря 2008

Просто общая информация:

Матрица lookat - это матрица, которая позиционирует / поворачивает что-то, чтобы указывать (смотреть на) точку в пространстве, из другой точки в пространстве.

Метод принимает желаемый «центр» вида камеры, вектор «вверх», который представляет направление «вверх» для камеры (вверх почти всегда (0,1,0), но это не так должен быть), и вектор «глаза», который является местоположением камеры.

Это используется в основном для камеры, но может также использоваться для других методов, таких как тени, прожекторы и т. Д.

Честно говоря, я не совсем уверен, почему компонент перевода устанавливается так, как в этом методе. В gluLookAt (из OpenGL) для компонента перевода задано значение 0,0,0, поскольку камера всегда выглядит как 0,0,0.

3 голосов
/ 08 декабря 2008

Этот компонент перевода помогает вам, создавая ортонормированный базис с вашим «глазом» в начале координат и всем остальным, выраженным в терминах этого источника (вашего «глаза») и трех осей.

Идея не столько в том, что матрица регулирует положение камеры. Скорее, он пытается упростить математику: когда вы хотите отобразить картину всего, что вы видите из своего положения «глаз», проще всего притвориться, что ваш глаз - центр вселенной.

Итак, короткий ответ заключается в том, что это значительно упрощает математику.

Отвечая на вопрос в комментарии: причина, по которой вы не просто вычитаете позицию «глаз» из всего, связана с порядком операций. Подумайте об этом следующим образом: как только вы окажетесь в новой системе отсчета (то есть в положении головы, представленном xaxis, yaxis и zaxis), вы теперь хотите выразить расстояния в этой новой (повернутой) системе отсчета. Вот почему вы используете точечное произведение новых осей с положением глаза: оно представляет собой то же расстояние, на которое нужно двигаться, но использует новую систему координат.

2 голосов
/ 08 декабря 2008

Точечный продукт просто проецирует точку на ось, чтобы получить x-, y- или z-компонент глаза. Вы перемещаете камеру назад, так что взгляд на (0, 0, 0) из (10, 0, 0) и из (100000, 0, 0) будет иметь разный эффект.

1 голос
/ 15 февраля 2009

Матрица преобразования 4х4 содержит два-три компонента: 1. матрица вращения 2. перевод добавить. 3. масштаб (многие движки не используют это непосредственно в матрице).

Их комбинация преобразует точку из пространства A в пространство B, следовательно, это матрица преобразования M_ab

Теперь местоположение камеры находится в пространстве A, и поэтому оно не является действительным преобразованием для пространства B, поэтому вам нужно умножить это местоположение на преобразование вращения.

Единственный открытый вопрос остается, почему точки? Что ж, если вы напишите 3 точки на бумаге, вы обнаружите, что 3 точки с X, Y и Z точно так же, как умножение с матрицей вращения.

Примером этой четвертой строки / столбца будет взятие нулевой точки - (0,0,0) в мировом пространстве. Это не нулевая точка в пространстве камеры, и поэтому вам нужно знать, каково представление в пространстве камеры, поскольку поворот и масштаб оставляют его равным нулю!

ура

1 голос
/ 09 декабря 2008

Матрица lookat выполняет следующие два шага:

  1. Переведите свою модель на происхождение,
  2. Поверните его в соответствии с ориентацией, установленной вектором вверх и видом
    направление.

Точечный продукт означает, что вы сначала делаете перевод, а затем вращаетесь. Вместо умножения двух матриц скалярное произведение просто умножает строку на столбец.

0 голосов
/ 24 апреля 2014

Необходимо поставить точку глаза в пространстве вашей оси, а не в мировом пространстве. Если вы поставите точку на вектор с помощью базового вектора координатной единицы, одного из x, y, z, он даст вам координаты глаза в этом пространстве. Вы преобразуете местоположение, применяя три перевода в последнем месте, в данном случае в последнем ряду. Затем перемещение глаза назад с отрицательным значением эквивалентно перемещению всего остального пространства вперед. Точно так же, как движение вверх в лифте заставляет вас чувствовать, что весь остальной мир выпадает из-под вас.

Использование матрицы для левой руки с переводом в качестве последней строки вместо последнего столбца является религиозным отличием, которое не имеет абсолютно никакого отношения к ответу. Тем не менее, это догма, которую следует строго избегать. При построении эскизов дерева лучше всего связывать глобальные-локальные (прямая кинематическая) преобразования слева направо в естественном порядке чтения. Использование левосторонних матриц заставляет вас писать их справа налево.

...