Тарифы Услуги Сим-карты

Матрица общего перспективного преобразования. Геометрические свойства нескольких изображений

В определённый момент у любого разработчика в области компьютерной графики возникает вопрос: как же работают эти перспективные матрицы? Подчас ответ найти очень непросто и, как это обычно бывает, основная масса разработчиков бросает это занятие на полпути.

Это не решение проблемы! Давайте разбираться вместе!

Будем реалистами с практическим уклоном и возьмём в качестве подопытного OpenGL версии 3.3. Начиная с этой версии каждый разработчик обязан самостоятельно реализовывать модуль матричных операций. Замечательно, это то, что нам нужно. Проведём декомпозицию нашей с вами нелёгкой задачи и выделим основные моменты. Немного фактов из спецификации OpenGL:

  • Матрицы хранятся по столбцам (column-major);
  • Однородные координаты;
  • Канонический объём отсечения (CVV) в левосторонней системе координат.
Существует два способа хранения матриц: сolumn-major и row-major. На лекциях по линейной алгебре как раз используется схема row-major. По большому счёту представление матриц в памяти не имеет значения, потому что матрицу всегда можно перевести в одного вида представления в другое простым транспонированием. А раз разницы нет, то для всех последующих расчётов мы будем использовать классические row-major матрицы. При программировании OpenGL есть небольшая хитрость, которая позволяет отказаться и от транспонирования матриц при сохранении классических row-major расчётов. В шейдерную программу матрицу нужно передавать как есть, а в шейдере производить умножение не вектора на матрицу, а матрицы на вектор.

Однородные координаты – это не очень хитрая система с рядом простых правил по переводу привычных декартовых координат в однородные координаты и обратно. Однородная координата это матрица-строка размерности . Для того чтобы перевести декартову координату в однородную координату необходимо x , y и z умножить на любое действительное число w (кроме 0). Далее необходимо записать результат в первые три компоненты, а последний компонент будет равен множителю w . Другими словами:
- декартовы координаты
w – действительное число, не равное 0

- однородные координаты

Небольшой трюк: Если w равно единице, то всё что нужно для перевода, это перенести компоненты x , y и z и приписать единицу в последний компонент. То есть получить матрицу-строку:

Несколько слов о нуле в качестве w . С точки зрения однородных координат это вполне допустимо. Однородные координаты позволяют различать точки и вектора. В декартовой же системе координат такое разделение невозможно.

- точка, где (x, y, z ) – декартовы координаты

- вектор, где (x, y, z ) – радиус-вектор

Обратный перевод вершины из однородных координат в декартовы координаты осуществляется следующим образом. Все компоненты матрицы-строки необходимо разделить на последнюю компоненту. Другими словами:

- однородные координаты
- декартовы координаты

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

Канонический объём отсечения или Canonic view volume (CVV) – это одна из мало документированных частей OpenGL. Как видно из рис. 1 CVV – это выровненный по осям куб с центром в начале координат и длиной ребра равной двойке. Всё, что попадает в область CVV подлежит растеризации, всё, что находится вне CVV игнорируется. Всё, что частично выходит за границы CVV, подлежит алгоритмам отсечения. Самое главное что надо знать - система координат CVV левосторонняя!


Рис. 1. Канонический объём отсечения OpenGL (CVV)

Левосторонняя система координат? Как же так, ведь в спецификации к OpenGL 1.0 ясно написано, что используемая система координат правосторонняя? Давайте разбираться.


Рис. 2. Системы координат

Как видно из рис. 2 системы координат различаются лишь направлением оси Z . В OpenGL 1.0 действительно используется правосторонняя пользовательская система координат. Но система координат CVV и пользовательская система координат это две совершенно разные вещи. Более того, начиная с версии 3.3, больше не существует такого понятия как стандартная система координат OpenGL. Как упоминалось ранее, программист сам реализует модуль матричных операций. Формирование матриц вращения, формирование проекционных матриц, поиск обратной матрицы, умножение матриц – это минимальный набор операций, входящих в модуль матричных операций. Возникает два логичных вопроса. Если объём видимости это куб с длиной ребра равной двум, то почему сцена размером в несколько тысяч условных единиц видна на экране? В какой момент происходит перевод пользовательской системы координат в систему координат CVV. Проекционные матрицы – это как раз та сущность, которая занимается решением этих вопросов.

Главная мысль вышеизложенного – разработчик сам волен выбрать тип пользовательской системы координат и должен корректно описать проекционные матрицы. На этом с фактами об OpenGL закончено и подошло время сводить всё воедино.

Одна из наиболее распространённых и сложно постигаемых матриц – это матрица перспективного преобразования. Так как же она связана с CVV и пользовательской системой координат? Почему объекты с увеличением расстояния до наблюдателя становятся меньше? Для того чтобы понять почему объекты уменьшаются с увеличением расстояния, давайте рассмотрим матричные преобразования трёхмерной модели шаг за шагом. Не секрет, что любая трёхмерная модель состоит из конечного списка вершин, которые подвергаются матричным преобразованиям совершенно независимо друг от друга. Для того чтобы определить координату трёхмерной вершины на двухмерном экране монитора необходимо:

  1. Перевести декартову координату в однородную координату;
  2. Умножить однородную координату на модельную матрицу;
  3. Результат умножить на видовую матрицу;
  4. Результат умножить на проекционную матрицу;
  5. Результат перевести из однородных координат в декартовы координаты.
Перевод декартовой координаты в однородную координату обсуждался ранее. Геометрический смысл модельной матрицы заключается в том, чтобы перевести модель из локальной системы координат в глобальную систему координат. Или как говорят, вынести вершины из модельного пространства в мировое пространство. Скажем проще, загруженный из файла трёхмерный объект находится в модельном пространстве, где координаты отсчитываются относительно самого объекта. Далее с помощью модельной матрицы производится позиционирование, масштабирование и поворот модели. В результате все вершины трёхмерной модели получают фактические однородные координаты в трёхмерной сцене. Модельное пространство относительно мирового пространства является локальным. Из модельного пространства координаты выносятся в мировое пространство (из локального в глобальное). Для этого используется модельная матрица.

Теперь переходим к шагу три. Здесь начинает работу видовое пространство. В этом пространстве координаты отсчитываются относительно положения и ориентации наблюдателя так, как если бы он являлся центром мира. Видовое пространство является локальным относительно мирового пространства, поэтому координаты в него надо вносить (а не выносить, как в предыдущем случае). Прямое матричное преобразование выносит координаты из некоторого пространства. Чтобы наоборот внести их в него, надо матричное преобразование инвертировать, поэтому видовое преобразование описывается обратной матрицей. Как же получить эту обратную матрицу? Для начала получим прямую матрицу наблюдателя. Чем характеризуется наблюдатель? Наблюдатель описывается координатой, в которой он находится, и векторами направления обзора. Наблюдатель всегда смотрит в направлении своей локальной оси Z . Наблюдатель может перемещаться по сцене и осуществлять повороты. Во многом это напоминает смысл модельной матрицы. По большому счёту так оно и есть. Однако, для наблюдателя операция масштабирования бессмысленна, поэтому между модельной матрицей наблюдателя и модельной матрицей трёхмерного объекта нельзя ставить знак равенства. Модельная матрица наблюдателя и есть искомая прямая матрица. Инвертировав эту матрицу, мы получаем видовую матрицу. На практике это означает, что все вершины в глобальных однородных координатах получат новые однородные координаты относительно наблюдателя. Соответственно, если наблюдатель видел определённую вершину, то значение однородной координаты z данной вершины в видовом пространстве точно будет положительным числом. Если вершина находилась за наблюдателем, то значение её однородной координаты z в видовом пространстве точно будет отрицательным числом.

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

Рассмотрим матрицу вида:

И точку в однородном пространстве наблюдателя:

Произведём умножение однородной координаты на рассматриваемую матрицу:

Переведём получившиеся однородные координаты в декартовы координаты:

Допустим, есть две точки в видовом пространстве с одинаковыми координатами x и y , но разными координатами z . Другими словами одна из точек находится за другой. Из-за перспективного искажения наблюдатель должен увидеть обе точки. Действительно, из формулы видно, что из-за деления на координату z , происходит сжатие к точке начала координат. Чем больше значение z (чем дальше точка от наблюдателя), тем сильнее сжатие. Вот и объяснение эффекту перспективы.

В спецификации OpenGL сказано, что операции по отсечению и растеризации выполняются в декартовых координатах, а процесс перевода однородных координат в декартовы координаты производится автоматически.

Матрица (1) является шаблоном для матрицы перспективой проекции. Как было сказано ранее, задача матрицы проекции заключается в двух моментах: установка пользовательской системы координат (левосторонняя или правосторонняя), перенос объёма видимости наблюдателя в CVV. Выведем перспективную матрицу для левосторонней пользовательской системы координат.

Матрицу проекции можно описать с помощью четырёх параметров (рис. 3):

  • Угол обзора в радианах (fovy );
  • Соотношение сторон (aspect );
  • Расстояние до ближней плоскости отсечения (n );
  • Расстояние до дальней плоскости отсечения (f ).


Рис. 3. Перспективный объём видимости

Рассмотрим проекцию точки в пространстве наблюдателя на переднюю грань отсечения перспективного объёма видимости. Для большей наглядности на рис. 4 изображён вид сбоку. Так же следует учесть, что пользовательская система координат совпадает с системой координат CVV, то есть везде пользуется левосторонняя система координат.


Рис. 4. Проецирование произвольной точки

На основании свойств подобных треугольников справедливы следующие равенства:

Выразим yꞌ и xꞌ:

В принципе, выражений (2) достаточно для получения координат точек проекции. Однако для правильного экранирования трёхмерных объёктов необходимо знать глубину каждого фрагмента. Другими словами необходимо хранить значение компоненты z . Как раз это значение используется при тестах глубины OpenGL. На рис. 3 видно, что значение zꞌ не подходит в качестве глубины фрагмента, потому что все проекции точек умеют одинаковое значение zꞌ . Выход из сложившейся ситуации – использование так называемой псевдоглубины.

Свойства псевдоглубины:

  1. Псевдоглубина рассчитывается на основании значения z ;
  2. Чем ближе к наблюдателю находится точка, тем меньшеe значение имеет псевдоглубина;
  3. У всех точек, лежащих на передней плоскости объёма видимости, значение псевдоглубины равно -1;
  4. У всех точек, лежащих на дальней плоскости отсечения объёма видимости, значение псевдоглубины равно 1;
  5. Все фрагменты, лежащие внутри объёма видимости, имеют значение псевдоглубины в диапазоне [-1 1].
Давайте выведем формулу, по которой будет рассчитываться псевдоглубина. В качестве основы возьмём следующее выражение:

Коэффициенты a и b необходимо вычислить. Для того чтобы это сделать, воспользуемся свойствами псевдоглубины 3 и 4. Получаем систему из двух уравнений с двумя неизвестными:

Произведём сложение обоих частей системы и умножим результат на произведение fn , при этом f и n не могут равняться нулю. Получаем:

Раскроем скобки и перегруппируем слагаемые так, чтобы слева осталась только часть с а , а справа только с b :

Подставим (6) в (5). Преобразуем выражение к простой дроби:

Умножим обе стороны на -2fn , при этом f и n не могут равняться нулю. Приведём подобные, перегруппируем слагаемые и выразим b :

Подставим (7) в (6) и выразим a :

Соответственно компоненты a и b равны:

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

Пусть расстояние до передней плоскости отсечения n равно 2, а расстояние до дальней плоскости отсечения f равно 10. Рассмотрим пять точек в однородном пространстве наблюдателя:

Взаимное расположение точки и объёма видимости
Точка Значение Описание
1 1 Точка находится перед передней плоскостью отсечения объёма видимости. Не проходит растеризацию.
2 2 Точка находится на передней грани отсечения объёма видимости. Проходит растеризацию.
3 5 Точка находится между передней гранью отсечения и дальней гранью отсечения объёма видимости. Проходит растеризацию.
4 10 Точка находится на дальней грани отсечения объёма видимости. Проходит растеризацию.
5 20 Точка находится за дальней гранью отсечения объёма видимости. Не проходит растеризацию.

Умножим все точки на матрицу (8), а затем переведём полученные однородные координаты в декартовые координаты . Для этого нам необходимо вычислить значения новых однородных компонент и .
Точка 1:

Обратите внимание, что однородная координата абсолютно верно позиционируется в CVV, а самое главное, что теперь возможна работа теста глубины OpenGL, потому что псевдоглубина полностью удовлетворяет требованиям тестов.

С координатой z разобрались, перейдём к координатам x и y . Как говорилось ранее весь перспективный объём видимости должен умещаться в CVV. Длина ребра CVV равна двум. Соответственно, высоту и ширину перспективного объёма видимости надо сжать до двух условных единиц.

В нашем распоряжении имеется угол fovy и величина aspect . Давайте выразим высоту и ширину, используя эти величины.


Рис. 5. Объём видимости

Из рис. 5 видно, что:

Теперь можно получить окончательный вид перспективной проекционной матрицы для пользовательской левосторонней системы координат, работающей с CVV OpenGL:

На этом вывод матриц закончен.

Пару слов о DirectX - основном конкуренте OpenGL. DirectX отличается от OpenGL только габаритами CVV и его позиционированием. В DirectX CVV - это прямоугольный параллелепипед с длинами по осям x и y равными двойке, а по оси z длина равна единице. Диапазон x и y равен [-1 1], а диапазон z равен . Что касается системы координат CVV, то в DirectX, как и в OpenGL, используется левосторонняя система координат.

Для вывода перспективных матриц для пользовательской правосторонней системы координат необходимо перерисовать рис. 2, рис.3 и рис.4 с учётом нового направления оси Z . Далее расчёты полностью аналогичны, с точностью до знака. Для матриц DirectX свойства псевдоглубины 3 и 4 модифицируются под диапазон .

На этом тему перспективных матриц можно считать закрытой.

Перспективное проецирование

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

На фотографиях, картинах, экране изображения кажутся нам естественными и правильными. Эти изображения называют перспективными. Свойства их таковы, что более удаленные предметы изображаются в меньших масштабах, параллельные прямые в общем случае непараллельны. В итоге геометрия изображения оказывается достаточно сложной, и по готовому изображению сложно определить размер тех или иных частей объекта.

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

Существует три системы координат. Обычно программист работает и держит данные о геометрических объектах в мировых координатах. Для повышения реалистичности при подготовке к выводу изображения на экран данные об объектах из мировых координат переводят в видовые координаты. И только в момент вывода изображения непосредственно на экран дисплея переходят к экранным координатам, которые представляют собой номера пикселов экрана.

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

В этой матрице элементы a , d , е отвечают за масштабирование, m , n , L - за смещение, p , q , r - за проецирование, s - за комплексное масштабирование, х - за вращение.

Одноточечное проецирование на плоскость z = 0

Суть этого проецирования такова: чем глубже находится предмет, тем больше становится значение z-координаты и знаменателя rz + 1, и, следовательно, тем мельче выглядит предмет на плоскости проекции. Выполним несложные выкладки и поясним их графически:
уравнение x"/F = x/(F + z пр) равносильно: x" = xF/(F + z пр) = x/(1 + z пр /F) = x/(1 + rz пр), где r = 1/F, F - фокус.

Для того, чтобы точки, лежащие на линии, параллельной оси z , не терялись друг за другом, используется одноточечное проецирование на линию (см. матрицу преобразования и рис. 4.2 ); исчезла z-координата, но, поскольку дальние предметы стали более мелкими, чем такие же близкие, у зрителя появляется ощущение глубины. Запомните: это первый способ передачи глубины на плоскости!

Для того, чтобы вращать объекты (или камеру), необходима серьезная математическая база, с помощью которой будут расчитываться координаты всех объектов при выводе на "плоский" экран компьютера. Сразу хочу сказать, что не стоит пугаться, все математические библиотеки уже написаны за нас, мы будем их только использовать. В любом случае, следующий текст пропускать не нужно, независимо от уровня знаний математики.

1. Матрицы, общие понятия

Что такое матрицы? Вспоминаем высшую математику: матрица ¬- это набор чисел с заранее известной размерностью строк и столбцов.

Матрицы можно складывать, умножать на число, перемножать друг с другом и много еще чего интересного, но этот момент мы пропустим, т.к. он достаточно подробно изложен в любом учебнике по высшей математике (учебники можно поискать на google.com). Мы будем пользоваться матрицами как программисты, мы их заполняем и говорим, что с ними делать, все расчеты произведет математическая библиотека Direct3D, поэтому нужно включить в проект заголовочный модуль d3dx9.h (и библиотеку d3dx9.lib).

Наша задача - создать объект, т.е. заполнить матрицу координатами вершин объекта. Каждая вершина - это вектор (X, Y, Z) в трехмерном пространстве. Теперь, чтобы произвести какое-то действие, нужно взять наш объект (то есть матрицу) и умножить на матрицу преобразования, результат этой операции - новый объект, заданный в виде матрицы.

В Direct3D определены и используются три основные матрицы: мировая матрица, матрица вида и матрица проекции. Рассмотрим их подробнее.

Мировая матрица (World Matrix) - позволяет производить вращение, трансформацию и масштабирование объекта, а также наделяет каждый из объектов своей локальной системой координат.

Функции для работы с мировой матрицей:

  • D3DXMatrixRotationX(), D3DXMatrixRotationY(), D3DXMatrixRotationZ() - вращение точки относительно одной из осей;
  • D3DXMatrixTranslation() - перемещение точки в другое положение;
  • D3DXMatrixScale() - масштабирование.

    Матрица вида (View Matrix) - определяет местоположение камеры просмотра сцены и может состоять из любых комбинаций трансляции и вращения.
    D3DXMatrixLookAtLH()и D3DXMatrixLookAtRH() определяет положение камеры и угла просмотра для левостороней и правостороней систем координат соответственно.

    Матрица проекции (Projection Matrix) - создает проекцию 3D сцены на экран монитора. С ее помощью объект трансформируется, начало координат переносится в переднюю часть, а также определяется передняя и задняя плоскости отсечения.

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

    2. Создание объекта

    Создаем новый проект, аналогично первому. Прежде чем продолжить усложнять наш код, разобьем его на части для лучшей читаемости кода. Наш проект логично разделить на три составляющие:
    1. Окно Windows (инициализация окна, сообщения, …)
    2. Инициализация 3D (загрузка координат объектов, удаление ресурсов, …)
    3. Рендер сцены (матрицы, рисование примитивов, …)
    В результате у нас будет 3 файла - window.cpp, init3d.h, render.h с таким содержанием: init3d.h - переносим глобальный переменные и структуры, объявление функций, функции InitDirectX(), InitBufferVertex(), Destroy3D() render.h - переносим функцию RenderScene() все, что осталось, касается главного окна, это будет файл - window.cpp .

    Добавляем заголовочный файл и библиотеку для использования матричных функций

    #include // или C:\DXSDK\Include\d3dx9.h #pragma comment(lib, "d3dx9.lib") //или C:\\DXSDK\\Lib\\d3dx9.lib

    Также нам понадобятся стандартные функции работы со временем, поэтому подключаем соответствующий заголовочный файл:

    #include

    Изменим формат представления вершин:

    #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ/D3DFVF_DIFFUSE) struct CUSTOMVERTEX { FLOAT x, y, z; DWORD color; };

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

    PDirectDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

    На данный момент мы не пользуемся освещением, а закрашиваем вершины в определенный цвет, поэтому отключаем освещение:

    PDirectDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

    Упростим наше сердце, представив его в виде трех треугольников. Будем использовать локальную систему координат.


    CUSTOMVERTEX stVertex= { { -1.0f, 0.5f, 0.0f, 0x00ff0000 }, { -0.5f, 1.0f, 0.0f, 0x00ff0000 }, { 0.0f, 0.5f, 0.0f, 0x00ff0000 }, { 0.0f, 0.5f, 0.0f, 0x000000ff }, { 0.5f, 1.0f, 0.0f, 0x000000ff }, { 1.0f, 0.5f, 0.0f, 0x000000ff }, { -1.0f, 0.5f, 0.0f, 0x0000ff00 }, { 1.0f, 0.5f, 0.0f, 0x0000ff00 }, { 0.0f, -1.0f, 0.0f, 0x0000ff00 }, };

    3. Создание матриц преобразования

    Напишем в файле render.h функцию SetupMatrix() в которой будут происходить все действия над матрицами.

    Создадим матрицы:

  • D3DXMATRIX MatrixWorld; - мировая матрица
  • D3DXMATRIX MatrixView; - матрица вида
  • D3DXMATRIX MatrixProjection; - матрица проекции
    Установка мировой матрицы

    Для того, чтобы объект вращался, необходимо получить системное время и каждое "мгновение" изменять угол между локальной системой координат и мировой ситемой координат. Вращать будем относительно оси Х, поэтому используем функцию D3DXMatrixRotationX. После расчета мировой матрицы необходимо применить ее значения с помощью функции SetTransform:

    UINT iTime=timeGetTime()%5000; FLOAT fAngle=iTime*(2.0f*D3DX_PI)/5000.0f; D3DXMatrixRotationX(&MatrixWorld, fAngle); pDirectDevice->SetTransform(D3DTS_WORLD, &MatrixWorld); Установка матрицы вида

    Устанавливаем камеру в нужном месте и направляем ее на объект

  • D3DXMatrixLookAtLH(&MatrixView, - результат выполнения функции
  • &D3DXVECTOR3(0.0f, 0.0f, -8.0f), - точка, в которой находится камера
  • &D3DXVECTOR3(0.0f, 0.0f, 0.0f), - точка, в которую мы смотрим
  • &D3DXVECTOR3(0.0f, 1.0f, 0.0f)); - верх объекта

    После расчета необходимо применить полученные значения.

  • В компьютерной графике определенны понятия различных матриц. Это мировая матрица (World Matrix), матрица вида (View Matrix) и матрица проекции (Projection Matrix). С помощью данных матриц в исходном коде программы производятся матричные преобразования над моделями. Матричные преобразования подразумевают под собой умножение каждой вершины объекта на одну из матриц, а точнее последовательное умножение всех вершин объекта на каждую из трех матриц. Такой подход позволяет корректно представить модель в трехмерном пространстве вашего двухмерного монитора. Техника прохода модели через три перечисленные матрицы представляет суть механизма работы с графическими данными в трехмерной плоскости монитора.

    Мировая матрица

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

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

    Как уже упоминалось, мировое преобразование вершин объекта может состоять из любых комбинаций вращения, трансляции и масштабирования. В математической записи вращение вершины по оси Х выглядит следующим образом:


    Мировая матрица

    где cos - угол вращения в радианах.

    Вращение вершины вокруг оси Y выглядит так:


    Вращение вершины вокруг оси Y

    А вращение вокруг оси Z происходит по следующей формуле:


    вращение вокруг оси Z

    Трансляция вершины позволяет переместить эту саму вершину с координатами x, y, z в новую точку с новыми координатами x1, y1, z1. В математической записи это выглядит так:

    X1 = x + Tx y1 = y + Ty z1 = z + Tz

    Трансляция вершины в матричной записи выглядит следующим образом:


    Трансляция вершины в матричной записи

    где Tx, Ty и Tz - значения смещения по осям X, Y и Z.

    Масштабировать вершину в пространстве (удалять или приближать) с координатами x, y, z в новую точку с новыми значениями x1, y1, z1, можно посредством следующей записи:

    X1 = x * S y1 = y * S z1 = z * S

    В матричной записи это выражается следующим образом:


    Масштабировать вершину

    где Sx, Sy, Sz - значения коэффициентов растяжения или сжатия по осям X, Y, Z.

    Все перечисленные операции можно делать в исходном коде программы вручную, то есть вычислять приведенные записи так, как я их только что описал. Но естественно так никто не делает (почти никто), потому что в DirectX имеется огромное количество методов, которые сделают все выше приведенные операции за вас.

    Матрица вида

    Матрица вида – задает местоположение камеры в пространстве и это вторая по счету матрица, на которую умножаются вершины объекта. Эта матрица способствует определению направления просмотра трехмерной сцены. Трехмерная сцена – это все то, что вы видите на экране монитора. Это как в театре, где вы сидите в портере или на галерке и наблюдаете за действиями на сцене. Так вот сидя в портере у вас будет одно местоположение камеры, а сидя на галерке уже совсем другое.

    Фактически эта матрица позволяет определять жанр игры. Например, игра DOOM от первого лица – это можно сказать первые ряды портера в театре, тогда как игра Warcraft – это галерка на балконе. Матрица вида предназначена для определения положения камеры в пространстве, и вы можете смещать позицию камеры влево, вправо, вверх, вниз, удалять, приближать ее и так далее.

    Матрица проекции

    Матрица проекции – это более сложная матрица, которая создает проекцию трехмерного объекта на плоскость двумерного экрана монитора. С помощью этой матрицы определяются передняя и задняя области отсечения трехмерного пространства, что позволяет регулировать пространство отсечения невидимых на экране объектов, а заодно и снизить нагрузку процессора видеокарты. На рисунке изображен механизм проекции объекта в плоскости и отсечение пространства.


    Матрица проекции

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

    На фотографиях, картинах, экране изображения кажутся нам естественными и правильными. Эти изображения называют перспективными. Свойства их таковы, что более удаленные предметы изображаются в меньших масштабах, параллельные прямые в общем случае непараллельны. В итоге геометрия изображения оказывается достаточно сложной, и по готовому изображению сложно определить размер тех или иных частей объекта.

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

    Существует три системы координат. Обычно программист работает и держит данные о геометрических объектах в мировых координатах. Для повышения реалистичности при подготовке к выводу изображения на экран данные об объектах из мировых координат переводят в видовые координаты. И только в момент вывода изображения непосредственно на экран дисплея переходят к экранным координатам, которые представляют собой номера пикселов экрана.

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

    Матрица общего перспективного преобразования

    В этой матрице элементы a , d , е отвечают за масштабирование, m , n , L — за смещение, p , q , r — за проецирование, s — за комплексное масштабирование, х — за вращение.