Матрицы камеры
В UNIGINE камера имеет 2 матрицы: view и projection. Они используются при рендеринге изображения с камеры во вьюпорт .
Прежде чем перейти к основным аспектам матриц камеры, необходимо знать особенности системы координат, используемой в UNIGINE, и освежить общие сведения о векторных пространствах и матрицах преобразования, используемых для визуализации вершин.
Система координат#
Трехмерное пространство в UNIGINE представлено правой декартовой системой координат: оси X и Y образуют горизонтальную плоскость, ось Z направлена вверх.
Оси и направления#
Для узлов в виртуальной сцене:
- Ось +Z считается направлением вверх . Чтобы переместить узел вверх / вниз, перенесите его по оси Z.
- Ось +Y считается прямым направлением . Чтобы переместить узел вперед / назад, перенесите его по оси Y.
- Ось +Y считается направлением вверх .
- Ось -Z считается прямым направлением .
Камера с единичной матрицей преобразования по умолчанию смотрит вниз:
Работа с направлениями#
Как видите, векторы направления узлов и камер различаются. Например, если вам нужно получить прямое направление узла, вы должны вызвать метод getAxisY() для его матрицы преобразования:
// get the node transformation matrix
Mat4 t = node->getWorldTransform();
// get the node "forward" vector from the matrix
vec3 node_forward = t.getAxisY();
И если вам нужно получить прямое направление камеры, вы должны вызвать метод -getAxisZ() для его матрицы преобразования:
// get the inverse modelview matrix as it is equal to the world transformation one
mat4 camera_transform = camera->getIModelview();
// get the camera "forward" vector from the matrix
vec3 camera_forward = -camera_transform.getAxisZ(); // the negative Z vector will be returned
Однако камеру можно установить на узел player . В этом случае, если вы просто вызовете getAxisY(), как и любой другой узел, вы получите направление камеры вверх. Чтобы этого избежать, реализуйте следующее:
// get the node transformation matrix
Mat4 t = node->getWorldTransform();
// get the "forward" vector from the matrix
vec3 forward = vec3(node->isPlayer() ? -t.getAxisZ() : t.getAxisY());
Прямое направление узла / камеры (при установке на узел player) также можно получить с помощью метода Node::getDirection()/getWorldDirection():
vec3 forward = node->getDirection(node->isPlayer() ? Math::AXIS_NZ : Math::AXIS_Y);
Векторные пространства и матрицы преобразования#
Существуют следующие векторные пространства:
- Local space - это пространство, в котором все вершины объекта определены относительно центра этого объекта.
- World space - это пространство, в котором все вершины объекта определены относительно центра мира.
- View space - это пространство, в котором все вершины объекта определены относительно камеры.
- Clip space - это пространство, в котором все вершины объекта определены в кубоиде с размерами [-1;1] для каждой оси. Координата Z вершины указывает, как далеко вершина находится от экрана.
- Screen space - это пространство, в котором все вершины объекта сплющены и имеют экранные координаты.
При рендеринге вершина преобразуется из одного пространства в другое в следующем порядке:
Для преобразования между пробелами используются следующие матрицы:
-
World Transformation Matrix хранит трансформацию объекта относительно начала координат мира. Эта матрица используется для преобразования вершин объекта из локального пространства в мировое пространство: матрица умножается на каждую вершину объекта.
В UNIGINE такое преобразование выполняется автоматически при добавлении узла в мир. Когда узел добавляется в мир как дочерний по отношению к другому узлу, он также имеет локальную матрицу преобразования, в которой сохраняется преобразование объекта относительно его родителя. Чтобы преобразовать локальную матрицу преобразования такого объекта в мировую, локальная матрица преобразования объекта умножается на локальную матрицу преобразования родительского объекта. Чтобы получить больше информации о локальных и мировых матрицах трансформации, проверьте Матричная иерархия глава.
-
View Matrix используется для преобразования вершин объекта из мирового пространства в пространство вида.
В UNIGINE матрица вида называется modelview. - Projection Matrix используется для преобразования вершин объекта из пространства вида в пространство отсечения.
Каждый узел, добавленный в мир, имеет матрицу преобразования мира . Однако передавать эту матрицу шейдеру для рендеринга вершин неразумно: это приведет к потере точности из-за преобразования двойных координат в плавающие. По этой причине в UNIGINE узел сначала преобразуется в пространство представления: произведение матрицы преобразования мира и матрицы представления вычисляется на ЦП и передается шейдеру. Такая матрица называется Modelview (в общем смысле).
Таким образом, преобразование координат вершины объекта можно представить следующей формулой:
VertexClip = ProjectionMatrix * ModelviewMatrix * VertexLocal
Здесь ModelviewMatrix - это произведение матрицы преобразования мира и матрицы вида. Порядок умножения матриц читается справа налево.
Матрица View#
В UNIGINE матрица View - это матрица 4x4, которая управляет тем, как камера смотрит на сцену. Матрица вида равна матрице обратного преобразования мира камеры : он хранит положение и поворот камеры в мировом пространстве.
Матрица используется для преобразования вершин объекта из мирового пространства в пространство вида (координаты вершин задаются относительно начала координат камеры): матрица вида камеры умножается на матрицу преобразования мира объекта, а затем полученная матрица умножается по вершинам объекта.
Объект и камера в мировом пространстве |
Объект в поле зрения |
Матрица Projection#
Матрица проекции - это матрица, которая определяет, как вершины отображаются на экране. Значения матрицы проекции зависят от типа проекции:
-
Для ортографической проекции , используется следующая матрица:
-
Для перспективной проекции , используется следующая матрица:
По умолчанию матрица проекции камеры не сохраняет соотношение сторон экрана (ширину к высоте): коррекция формата выполняется автоматически для текущего вьюпорта. Если коррекция формата выполняется вручную, автоматическую коррекцию формата для вьюпорта необходимо отключить, чтобы избежать неверных результатов.
Если вы измените FOV (или ширину и высоту для ортогональной проекции), ближнюю и дальнюю плоскости отсечения, матрица обновится.
Матрица проекции используется для преобразования вершин объекта из view space в clip space. Это пространство представлено кубоидом с размерами [-1;1] для каждой оси и используется для отсечения вершин: все вершины внутри этого объема будут отображаться на экране. В этом пространстве координата Z каждой вершины указывает, как далеко вершина находится от экрана.
Затем координаты вершин в пространстве клипа автоматически преобразуются в нормализованные координаты устройства с использованием перспективного деления. Сопоставление этих координат с пространством экрана выполняется на графическом процессоре с использованием вектора преобразования вьюпорта, который хранит следующее:
(width, height, 1/width, 1/height)
Симулятор матриц камеры#
Взгляните на следующую таблицу, чтобы получить полное представление о том, как матрицы камеры обрабатываются в UNIGINE. Он показывает, как матрицы World Transformation, View и Projection влияют на координаты вершины, которые можно использовать в целях отладки.