Вопрос

Я занимаюсь написанием 3D-движка и наткнулся на алгоритм 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

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

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

Это было полезно?

Решение

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

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

Другие советы

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

Итак, операция следующая: сначала перевести на исходную точку (переместить на - 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 после изменения базиса). Однако из-за инверсии строки и столбцы транспонируются.

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

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

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

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

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

Этот компонент перевода поможет вам, создав ортонормированную основу с вашей & квотой; глаз Quot &; в начале координат и во всем остальном, выраженном в терминах этого происхождения (ваш " eye ") и трех осей.

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

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

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

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

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

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

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

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

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

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

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

    ваше здоровье

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

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

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top