Вычисление матрицы LookAt
Я посреди написания 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
Теперь я понимаю, как это работает на стороне вращения, но я не совсем понимаю, почему он превращает компонент перевода матрицы в эти точечные продукты. Изучив это немного, кажется, что он корректирует положение камеры на небольшую величину на основе проекции новых базисных векторов на положение глаза/камеры.
Вопрос в том, зачем это нужно? Что он делает?
Ответы
Ответ 1
Я построю матрицу взглядов, создав матрицу вращения 3x3, как вы это сделали, а затем расширив ее до 4x4 с нулями и синглом 1 в нижнем правом углу. Затем я строю матрицу преобразования 4x4, используя координаты отрицательной точки (без точечных произведений), и умножаю две матрицы вместе. Мое предположение заключается в том, что это умножение дает эквивалент точечных продуктов в нижней строке вашего примера, но мне нужно будет выполнить его на бумаге, чтобы убедиться.
3D-поворот преобразует ваши оси. Поэтому вы не можете напрямую использовать глазную точку, не превращая ее в эту новую систему координат. То, что выполняет матричное умножение - или в этом случае - 3 значения точечного продукта.
Ответ 2
Обратите внимание, что приведенный пример представляет собой основную матрицу с левым строком.
Итак, операция: Сначала перевести на начало координат (переместить по -eye), а затем повернуть так, чтобы вектор от глаз до В линии линии с + z:
В основном вы получаете тот же результат, если вы предварительно умножите матрицу вращения на перевод -ee:
[ 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 - новая ось x после смены базы). Однако из-за инверсии строки и столбцы транспонируются.
Ответ 3
Только некоторые общие сведения:
Матрица lookat - это матрица, которая позиционирует/поворачивает что-то, чтобы указать (смотреть) на точку в пространстве, из другой точки пространства.
Метод принимает желаемый "центр" просмотра камер, "вверх" вектор, который представляет направление "вверх" для камеры (вверх почти всегда (0,1,0), но он не должны быть) и вектор "глаз", который является местоположением камеры.
Это используется в основном для камеры, но также может использоваться для других методов, таких как тени, прожекторы и т.д.
Честно говоря, я не совсем уверен, почему компонент перевода задан так, как он есть в этом методе. В gluLookAt
(из OpenGL) компонент перевода установлен на 0,0,0, так как камера просматривается как 0,0,0 всегда.
Ответ 4
Точечный продукт просто проецирует точку на ось, чтобы получить x-, y- или z-компонент глаза. Вы перемещаете камеру назад, поэтому просмотр (0, 0, 0) из (10, 0, 0) и из (100000, 0, 0) будет иметь разный эффект.
Ответ 5
Этот компонент перевода помогает вам создать ортонормированный базис с вашим "глазом" в начале и всем остальном, выраженным в терминах этого происхождения (ваш "глаз" ) и три оси.
Концепция заключается не столько в том, что матрица регулирует положение камеры. Скорее, он пытается упростить математику: когда вы хотите сделать снимок всего, что вы можете видеть из своего "глазного" положения, проще всего притвориться, что ваш глаз является центром вселенной.
Итак, короткий ответ заключается в том, что это значительно упрощает математику.
Отвечая на вопрос в комментарии: причина, по которой вы не просто вычитаете позицию "глаз" из всего, связана с порядком операций. Подумайте об этом так: как только вы попадете в новую систему отсчета (то есть положение головы, представленное xaxis, yaxis и zaxis), теперь вы хотите выразить расстояния в терминах этой новой (повернутой) системы координат. Вот почему вы используете точечный продукт новых осей с положением глаз: это то же расстояние, что и вещи, которые нужно перемещать, но использует новую систему координат.
Ответ 6
Матрица lookat выполняет следующие два шага:
- Перевести свою модель на начало координат,
- Поверните его в соответствии с ориентацией, настроенной вектором вверх и поиском
направление.
Точечный продукт означает, что сначала вы делаете перевод, а затем вращаетесь. Вместо умножения двух матриц точечный продукт просто умножает строку на столбец.
Ответ 7
Матрица преобразования 4x4 содержит два-три компонента:
1. матрица вращения
2. перевод для добавления.
3. масштаб (многие двигатели не используют это непосредственно в матрице).
Сочетание из них преобразует точку из пространства A в пространство B, следовательно, это матрица преобразования M_ab
Теперь местоположение камеры находится в пространстве A, и поэтому это не является допустимым преобразованием для пространства B, поэтому вам нужно умножить это местоположение на преобразование вращения.
Остается открытым вопрос, почему точки?
Ну, если вы напишете 3 точки на бумаге, вы обнаружите, что 3 точки с X, Y и Z точно так же, как умножение с матрицей вращения.
Пример для этой четвертой строки/столбца будет принимать нулевую точку - (0,0,0) в мировом пространстве. Это не нулевая точка в пространстве камеры, поэтому вам нужно знать, что представляет собой изображение в пространстве камеры, поскольку вращение и масштаб оставляют его на нуле!
веселит
Ответ 8
Нужно поместить глазную точку в пространство оси, а не в мировое пространство. Когда вы усеиваете вектор с базовым вектором координатной единицы, один из x, y, z дает координаты глаза в этом пространстве. Вы преобразовываете местоположение, применяя три перевода в последнем месте, в этом случае последнюю строку. Затем перемещение глаза назад, с отрицательным, эквивалентно перемещению всего остального пространства вперед. Точно так же, как движение вверх в лифте заставляет вас почувствовать, что остальная часть мира вываливается из-под вас.
Использование левой матрицы с переводом в качестве последней строки вместо последнего столбца является религиозной разницей, которая не имеет абсолютно никакого отношения к ответу. Однако это догма, которую следует строго избегать. Лучше всего привязать глобальные к локальным (вперед кинематические) преобразования влево-вправо, в естественном порядке чтения, при рисовании эскизов деревьев. Использование левых матриц заставляет вас писать эти права налево.