Матрица вида в directx
Для того, чтобы вращать объекты (или камеру), необходима серьезная математическая база, с помощью которой будут расчитываться координаты всех объектов при выводе на «плоский» экран компьютера. Сразу хочу сказать, что не стоит пугаться, все математические библиотеки уже написаны за нас, мы будем их только использовать. В любом случае, следующий текст пропускать не нужно, независимо от уровня знаний математики.
Преобразования матрицы
В приложениях, работающих с 3D-графикой, с помощью геометрических преобразований можно:
- выражать местоположение одного объекта относительного другого объекта;
- поворачивать объекты и задавать их размер;
- менять позиции наблюдателя, направления и перспективы.
Любую точку (X,Y,Z) можно преобразовать в другую точку (X', Y', Z') с помощью матрицы 4x4, как показано в следующем уравнении.
Примените следующие уравнения к (X, Y, Z) и матрице для получения точки (X', Y', Z').
Наиболее распространенные преобразования — это параллельный перенос, поворот и масштабирование. Можно объединить матрицы, которые обеспечивают эти эффекты, в одну матрицу и вычислять сразу несколько преобразований. Например, можно построить единую матрицу для параллельного переноса и поворота серии точек.
Матрицы записываются в порядке строка-столбец. Матрица, которая равномерно масштабирует вершины вдоль каждой оси — так называемое пропорциональное масштабирование — в математической записи будет представлена следующей матрицей.
В C++ Direct3D объявляет матрицы в виде двумерного массива с помощью структуры D3DMATRIX . В следующем примере показано, как инициализировать структуру D3DMATRIX для работы в качестве унифицированной матрицы масштабирования.
1. Матрицы, общие понятия
Что такое матрицы? Вспоминаем высшую математику: матрица – это набор чисел с заранее известной размерностью строк и столбцов.
Наша задача – создать объект, т.е. заполнить матрицу координатами вершин объекта. Каждая вершина – это вектор (X, Y, Z) в трехмерном пространстве. Теперь, чтобы произвести какое-то действие, нужно взять наш объект (то есть матрицу) и умножить на матрицу преобразования, результат этой операции – новый объект, заданный в виде матрицы.
В Direct3D определены и используются три основные матрицы: мировая матрица, матрица вида и матрица проекции. Рассмотрим их подробнее.
Мировая матрица (World Matrix) – позволяет производить вращение, трансформацию и масштабирование объекта, а также наделяет каждый из объектов своей локальной системой координат.
Функции для работы с мировой матрицей:
Матрица вида (View Matrix) – определяет местоположение камеры просмотра сцены и может состоять из любых комбинаций трансляции и вращения.
D3DXMatrixLookAtLH()и D3DXMatrixLookAtRH() определяет положение камеры и угла просмотра для левостороней и правостороней систем координат соответственно.
Матрица проекции (Projection Matrix) – создает проекцию 3D сцены на экран монитора. С ее помощью объект трансформируется, начало координат переносится в переднюю часть, а также определяется передняя и задняя плоскости отсечения.
Заполняя эти матрицы и делая преобразования, вы создаете трехмерную сцену, в которой получаете возможность перемещать, вращать, приближать, удалять и производить другие действия над объектами, в зависимости от ваших потребностей.
Перевод
Следующее уравнение параллельно переносит точку (X, Y, Z) в новую точку (X', Y', Z').
Матрицу параллельного переноса можно вручную создать в C++. В следующем примере показан исходный код для функции, которая создает матрицу для параллельного переноса вершин.
Для удобства библиотека служебной программы D3DX предоставляет функцию D3DXMatrixTranslation .
3. Создание матриц преобразования
Напишем в файле render.h функцию SetupMatrix() в которой будут происходить все действия над матрицами.
Для того, чтобы объект вращался, необходимо получить системное время и каждое «мгновение» изменять угол между локальной системой координат и мировой ситемой координат. Вращать будем относительно оси Х, поэтому используем функцию D3DXMatrixRotationX. После расчета мировой матрицы необходимо применить ее значения с помощью функции SetTransform:
Установка матрицы вида
Устанавливаем камеру в нужном месте и направляем ее на объект
После расчета необходимо применить полученные значения:
Установка матрицы проекции
После просчета необходимо применить полученные значения:
Помещаем вызов функции расчета матриц в функцию отрисовки сцены RenderScene().
Запускаем на компиляцию и наблюдаем вращение :)
Исходные файлы:
Язык: C++ ( 10.zip) (3 Кб)
Язык: Delphi ( D3D9_Leson2.zip - представил Pavia ) (2,8 Кб)
Если у Вас возникли проблемы, вопросы или пожелания к статье – милости просим в тему поддержки этой статьи.
В компьютерной графике определенны понятия различных матриц. Это мировая матрица (World Matrix), матрица вида (View Matrix) и матрица проекции (Projection Matrix). С помощью данных матриц в исходном коде программы производятся матричные преобразования над моделями. Матричные преобразования подразумевают под собой умножение каждой вершины объекта на одну из матриц, а точнее последовательное умножение всех вершин объекта на каждую из трех матриц. Такой подход позволяет корректно представить модель в трехмерном пространстве вашего двухмерного монитора. Техника прохода модели через три перечисленные матрицы представляет суть механизма работы с графическими данными в трехмерной плоскости монитора.
Мировая матрица
Мировая матрица – позволяет производить различные матричные преобразования (трансформацию и масштабирование) объекта в мировой системе координат. Мировая система координат – это своя локальная система координат данного объекта, которой наделяется каждый объект, скажем так прошедший через мировую матрицу, поскольку каждая вершина участвует в произведении этой матрицы.
Новая локальная система координат значительно упрощает аффинные преобразования объекта в пространстве. Например, чтобы перенести объект с левого верхнего угла дисплея в нижний правый угол дисплея, то есть переместить игровой объект в пространстве, необходимо просто перенести его локальную точку отсчета, системы координат на новое место. Если бы не было мировой матрицы, то этот объект пришлось переносить по одной вершине. Поэтому любой объект, а точнее все вершины этого объекта проходят через мировую матрицу преобразования.
Как уже упоминалось, мировое преобразование вершин объекта может состоять из любых комбинаций вращения, трансляции и масштабирования. В математической записи вращение вершины по оси Х выглядит следующим образом:
Мировая матрица
где cos — угол вращения в радианах.
Вращение вершины вокруг оси Y выглядит так:
Вращение вершины вокруг оси Y
А вращение вокруг оси Z происходит по следующей формуле:
вращение вокруг оси Z
Трансляция вершины позволяет переместить эту саму вершину с координатами x, y, z в новую точку с новыми координатами x1, y1, z1. В математической записи это выглядит так:
Трансляция вершины в матричной записи выглядит следующим образом:
Трансляция вершины в матричной записи
где Tx, Ty и Tz — значения смещения по осям X, Y и Z.
Масштабировать вершину в пространстве (удалять или приближать) с координатами x, y, z в новую точку с новыми значениями x1, y1, z1, можно посредством следующей записи:
В матричной записи это выражается следующим образом:
Масштабировать вершину
где Sx, Sy, Sz — значения коэффициентов растяжения или сжатия по осям X, Y, Z.
Все перечисленные операции можно делать в исходном коде программы вручную, то есть вычислять приведенные записи так, как я их только что описал. Но естественно так никто не делает (почти никто), потому что в DirectX имеется огромное количество методов, которые сделают все выше приведенные операции за вас.
Матрица вида
Матрица вида – задает местоположение камеры в пространстве и это вторая по счету матрица, на которую умножаются вершины объекта. Эта матрица способствует определению направления просмотра трехмерной сцены. Трехмерная сцена – это все то, что вы видите на экране монитора. Это как в театре, где вы сидите в портере или на галерке и наблюдаете за действиями на сцене. Так вот сидя в портере у вас будет одно местоположение камеры, а сидя на галерке уже совсем другое.
Фактически эта матрица позволяет определять жанр игры. Например, игра DOOM от первого лица – это можно сказать первые ряды портера в театре, тогда как игра Warcraft – это галерка на балконе. Матрица вида предназначена для определения положения камеры в пространстве, и вы можете смещать позицию камеры влево, вправо, вверх, вниз, удалять, приближать ее и так далее.
Матрица проекции
Матрица проекции – это более сложная матрица, которая создает проекцию трехмерного объекта на плоскость двумерного экрана монитора. С помощью этой матрицы определяются передняя и задняя области отсечения трехмерного пространства, что позволяет регулировать пространство отсечения невидимых на экране объектов, а заодно и снизить нагрузку процессора видеокарты. На рисунке изображен механизм проекции объекта в плоскости и отсечение пространства.
Матрица проекции
Программирование трехмерной графики невозможно себе представить без использования матриц. Матрица – это двухмерный массив данных заполненный определенными значениями. Матрицы позволяют легко и быстро производить любые манипуляции с вершинами объектов в пространстве. С помощью матриц можно связать несколько однородных операций над вершинами, что в результате позволяет выполнить колоссальные по объему математические вычисления за небольшой промежуток времени. Более того, матрицы можно использовать и в описании координатных систем для переноса, масштабирования, вращения и трансформации объектов в пространстве. Размерность матрицы может быть любой, но в компьютерной графике типичной размерностью является матрица 4х4, то есть четыре строки и четыре столбца.
Если вам необходимо определить положение элемента внутри матрицы, то нужно сначала указать в какой именно строке находится этот элемент, а затем указать в каком столбце он располагается. В итоге получается, что искомый элемент матрицы с размерностью m на n находится в строке m столбца n.
Сложение и вычитание матриц
Все математические операции над матрицами основаны на знаниях, которые мы изучали в школе. Единственное условие в сложениях и вычитаниях матриц является их одинаковая размерность. Чтобы сложить между собой две матрицы, необходимо просто сложить поэлементно обе матрицы между собой, а результат записать в отдельную матрицу.
Вычитание двух матриц происходит по той же схеме.
Умножение матриц
Умножение матриц бывает двух видов. Это скалярное произведение и матричное произведение. Скалярное произведение матрицы — это умножение матрицы на любое скалярное значение. В этом случае элементы матрицы поочередно перемножаются на это самое скалярное значение, а результат записывается в итоговую матрицу. При такой операции размерность матриц не имеет абсолютно никакого значения.
Матричное произведение отличается от скалярного произведения тем, что в этой операции используются две и более матрицы, где обязательно должно соблюдаться следующие условие: количество столбцов матрицы А должно быть равно количеству строк матрицы В. Механизм перемножения двух матриц между собой заключается в последовательном произведении каждого элемента из первой строки матрицы А на каждый элемент первого столбца матрицы В. Затем это произведение суммируется между собой, а результат записывается в отдельную матрицу.
Матричное произведение
В этом показательном примере, первый элемент матрицы А умножается на первый элемент первого столбца матрицы В. Далее, второй элемент первой строки матрицы А умножается на второй элемент первого столбца матрицы В. И так далее, до окончания всех элементов в строке матрицы А и в столбце матрицы В. Затем эти результаты суммируются между собой, а итоговое значение записывается в первую строку матрицы С. Все записи в матрице С происходят слева направо и сверху вниз. Перемножение матриц между собой носит название матричной конкатенации.
Примечание. Операция умножения матрицы А на матрицу В не коммутативна то есть А * В = С, но В * А не равно С.
This section introduces the basic concepts of the view transform and provides details on how to set up a view transform matrix in a Direct3D application.
The view transform locates the viewer in world space, transforming vertices into camera space. In camera space, the camera, or viewer, is at the origin, looking in the positive z-direction. Recall that Direct3D uses a left-handed coordinate system, so z is positive into a scene. The view matrix relocates the objects in the world around a camera's position - the origin of camera space - and orientation.
There are many ways to create a view matrix. In all cases, the camera has some logical position and orientation in world space that is used as a starting point to create a view matrix that will be applied to the models in a scene. The view matrix translates and rotates objects to place them in camera space, where the camera is at the origin. One way to create a view matrix is to combine a translation matrix with rotation matrices for each axis. In this approach, the following general matrix equation applies.
In this formula, V is the view matrix being created, T is a translation matrix that repositions objects in the world, and Rₓ through Rz are rotation matrices that rotate objects along the x-, y-, and z-axis. The translation and rotation matrices are based on the camera's logical position and orientation in world space. So, if the camera's logical position in the world is , the aim of the translation matrix is to move objects -10 units along the x-axis, -20 units along the y-axis, and -100 units along the z-axis. The rotation matrices in the formula are based on the camera's orientation, in terms of how much the axes of camera space are rotated out of alignment with world space. For example, if the camera mentioned earlier is pointing straight down, its z-axis is 90 degrees (pi/2 radians) out of alignment with the z-axis of world space, as shown in the following illustration.
The rotation matrices apply rotations of equal, but opposite, magnitude to the models in the scene. The view matrix for this camera includes a rotation of -90 degrees around the x-axis. The rotation matrix is combined with the translation matrix to create a view matrix that adjusts the position and orientation of the objects in the scene so that their top is facing the camera, giving the appearance that the camera is above the model.
Конкатенация матриц
Одним из преимуществ использования матриц является то, что эффекты двух или нескольких матриц можно объединить путем перемножения этих матриц. Это означает, что для поворота модели и последующего ее параллельного переноса в какое-либо место не нужно применять две матрицы. Вместо этого необходимо перемножить матрицы поворота и параллельного переноса для получения составной матрицы, содержащей все их эффекты. Этот процесс называется конкатенацией матриц и может описываться следующим уравнением.
В этом уравнении C — создаваемая составная матрица, а M₁ – Mₙ — отдельные матрицы. В большинстве случаев объединяют только две или три матрицы, однако на самом деле их количество не ограничено.
Используйте функцию D3DXMatrixMultiply для умножения матрицы.
Порядок, в котором выполняется перемножение матриц, имеет решающее значение. Приведенная выше формула отражает правило конкатенации матриц "слева направо". Это значит, что визуальные эффекты матриц, используемых для создания составной матрицы, имеют место в порядке слева направо. В следующем примере показана типичная мировая матрица. Предположим, вы создаете мировую матрицу для классической летающей тарелки. Наверное, имеет смысл вращать летающую тарелку вокруг ее центра — оси Y модельного пространства — и параллельно переносить ее в какое-либо другое место в сцене. Для достижения этого эффекта необходимо сначала создать матрицу поворота, а затем умножить ее на матрицу параллельного переноса, как показано в следующем уравнении.
В этой формуле Ry — это матрица для поворота вокруг оси Y, а Tw — это параллельный перенос в некоторую точку в мировых координатах.
Порядок, в котором перемножаются матрицы, имеет значение, потому что, в отличие от умножения двух скалярных значений, умножение матриц не является коммутативным. Перемножение матриц в обратном порядке будет производить визуальный эффект параллельного переноса летающей тарелки в ее положение в мировом пространстве, а затем ее поворота вокруг мирового начала координат.
Вне зависимости от того, матрицу какого типа вы создаете, помните о правиле "слева направо", чтобы результаты всегда соответствовали ожидаемым.
2. Создание объекта
Добавляем заголовочный файл и библиотеку для использования матричных функций
Также нам понадобятся стандартные функции работы со временем, поэтому подключаем соответствующий заголовочный файл:
Изменим формат представления вершин:
Будем использовать не преобразованный тип вершин, т.к. преобразования будем делать матрицами.
Изменяем код функции InitDirectX(). В эту функцию необходимо добавить установку двух режимов отображения.
Отключаем режим отсечения для того, чтобы при вращении можно было видеть все стороны объекта:
На данный момент мы не пользуемся освещением, а закрашиваем вершины в определенный цвет, поэтому отключаем освещение:
Упростим наше сердце, представив его в виде трех треугольников. Будем использовать локальную систему координат.
Setting Up a View Matrix
The D3DXMatrixLookAtLH and D3DXMatrixLookAtRH helper functions create a view matrix based on the camera location and a look-at point.
The following example creates a view matrix for left-handed coordinates.
Direct3D uses the world and view matrices to configure several internal data structures. Each time you set a new world or view matrix, the system recalculates the associated internal structures. Setting these matrices frequently is computationally time-consuming. You can minimize the number of required calculations by concatenating your world and view matrices into a world-view matrix that you set as the world matrix, and then setting the view matrix to the identity. Keep cached copies of individual world and view matrices that you can modify, concatenate, and reset the world matrix as needed. For clarity, the samples rarely employ this optimization.
Компонент Direct3D, перемещающий геометрию через фиксированный конвейер функциональной геометрии, называется модулем преобразования. Он находит модель и смотрящего в реальном мире, проецирует вершины для отображения на экране и обрезает вершины в окне просмотра. Модуль преобразования также выполняет вычисления освещения, чтобы определить рассеянные и зеркальные компоненты в каждой вершине.
Геометрический конвейер принимает вершины в качестве входных данных. Модуль преобразований применяет к вершинам мировое, видовое и проекционное преобразования, кадрирует результат и передает все в средство программной прорисовки.
В начале конвейера вершины модели объявлены относительно локальной системы координат. Локальная система координат — это локальное начало координат и ориентация. Эта ориентация координат часто называется пространством модели, а отдельные координаты называются координатами модели.
Первый этап геометрического конвейера преобразует вершины модели из их локальной системы координат в систему координат, используемую всеми объектами в сцене. Процесс переориентирования вершин называется преобразованием мира. Эта новая ориентация обычно называется мировым пространством, и каждая вершина в мировом пространстве объявляется с помощью мировых координат.
На следующем этапе вершины, которые описывают ваш трехмерный мир, ориентируются по отношению к камере. То есть приложение выбирает точку зрения для сцены, а координаты мирового пространства перемещаются и поворачиваются вокруг представления камеры, превращая мир в пространство камеры. Это преобразование представления.
Следующий этап — преобразование проекции. В этой части конвейера объекты обычно масштабируются по отношению к их расстоянию от средства просмотра, чтобы дать иллюзию глубины сцене; Закрываемые объекты отображаются больше, чем удаленные объекты, и т. д. С целью упрощения в этой документации пространство, в котором существуют вершины после проекционного преобразования, называется проекционным пространством. В некоторых книгах по графике проекционное пространство может называться постперспективным однородным пространством. Не все проекционные преобразования обеспечивают масштабирование размера объектов в сцене. Такая проекция иногда называется аффинной или ортогональной проекцией.
На последнем этапе конвейера все вершины, которые не будут видны на экране, удаляются, чтобы средство программной прорисовки не тратило время на вычисление цветов и затенения для того, что никто не увидит. Этот процесс называется кадрированием. После кадрирования оставшиеся вершины масштабируются в соответствии с параметрами окна просмотра и преобразуются в экранные координаты. Итоговые вершины, отображаемые на экране после растеризации стены, существуют в экранном пространстве.
Преобразования используются для преобразования геометрии объектов из одного пространства координат в другое. В Direct3D для 3D-преобразований используются матрицы. В этом разделе объясняется, как матрицы создают трехмерные преобразования, описывают некоторые распространенные способы использования преобразований и подробное описание способа объединения матриц для создания одной матрицы, охватывающей несколько преобразований.
-
— преобразование из пространства модели в мир — преобразование из мирового пространства в представление — преобразование из пространства представления в пространство проекции
Масштабирование
Следующее уравнение масштабирует точку (X, Y, Z) на произвольные значения в направлениях (X, Y, Z) для получения новой точки (X', Y', Z').
Rotate
Описанные здесь преобразования предназначены для левовинтовых систем координат и, следовательно, могут отличаться от матриц преобразования, которые встречались вам где-либо еще.
Следующее уравнение поворачивает точку (X, Y, Z) вокруг оси X для получения новой точки (X', Y', Z').
Следующее уравнение поворачивает точку вокруг оси Y.
Следующее уравнение поворачивает точку вокруг оси Z.
В этих примерах матриц греческой буквой тета обозначен угол поворота в радианах. Углы измеряются по часовой стрелке, если смотреть вдоль оси поворота в направлении начала координат.
В приложении C++ используйте функции D3DXMatrixRotationX, D3DXMatrixRotationY и D3DXMatrixRotationZ , предоставляемые библиотекой служебной программы D3DX, для создания матриц поворота. Ниже приведен код для функции D3DXMatrixRotationX .
Читайте также: