Геометрические свойства нескольких изображений

21.09.2019

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

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

Будем реалистами с практическим уклоном и возьмём в качестве подопытного 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 модифицируются под диапазон .

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

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

Рис. 1.5.3. Общая схема центральной проекции

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

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

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

где – константа для данной пары точек и .

Рис. 1.5.4. Схема разворотов плоскости изображения

Учитывая, что съемочная камера может быть развернута на углы и относительно осей , из (1.5.8) получаем

, (1.5.8)

где – координаты центра проектирования в системе ; – координаты центра проектирования в системе .

Если учесть, что поверхность проекции является плоской , начало координат системы , как правило, совпадает с главной точкой картинной плоскости , расположенной на расстоянии от , то

. (1.5.9)

Исключая в (1.5.9) константу путем деления первой и второй строк на третью, получаем уравнения, связывающие координаты сопряженных точек в системах и :

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

Характерной особенностью центральной проекции является существенное различие в масштабах изображения предметов, находящихся на различных расстояниях от центра проектирования. Это связано с уменьшением угловых размеров предмета (и соответственно с уменьшением линейных размеров в плоскости изображения) при удалении от съемочной сцены. На рис.1.5.5 приведен результат съемки предмета в виде полосы с нанесением на нее рисунка из периодически повторяющихся прямоугольников. Изменение ширины полосы и размеров прямоугольников создает ощущение глубины пространства. Принципиально изображение может быть рассчитано, например, по формулам (1.5.12), но его можно построить с достаточной степенью точности, если задать точку схода лучей. Расчеты с использованием координаты точки схода лучей значительно проще. Потому такой подход широко используется при имитации визуально наблюдаемой обстановки в видеотренажерах.

Сегодня мы более подробно рассмотрим устройство виртуальной камеры. Начнём с картинки.

На рисунке мы видим координатное пространство камеры. Направление ("взгляд") камеры всегда совпадает с положительным направлением оси z, а сама камера расположена в начале координат.

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

Обратите внимание на три плоскости. Первая расположена на расстоянии 1 по оси z. Это ближняя плоскость. То что находится до неё игрок никогда не увидит. В данном случае значение z равно единице, но вообще говоря, оно может быть любым. Именно с ближней плоскостью связан один дефект отображения графики. Этот дефект проявляется прежде всего в шутерах (из-за большой свободы камеры). Когда ты слишком близко подходишь к объекту, то можно оказаться "внутри". Из последних игр этот дефект особенно сильно проявлялся в Left 4 dead: когда на игрока наваливалась толпа зомби, то очень часто можно было заглянуть внутрь других персонажей.

Плоскость расположенная на расстоянии 100 единиц по оси z называется дальней. Опять же, значение может быть произвольным. Пользователь никогда не увидит объекты расположенные дальше этой плоскости.

Шесть плоскостей ограничивающих пространство, которое увидит пользователь, называются отсекающими (clipping planes): левая правая верхняя нижняя ближняя и дальняя.

Плоскость расположенная между ближней и дальней - проекционная. В дальнейшем, эту плоскость мы будем располагать в z=1, т.е. она будет совпадать с ближней. Здесь я отделил ближнюю и проекционную плоскости, чтобы показать, что это всё-таки не одно и то же. Проекционная плоскость предназначена для последнего преобразования координат: преобразование из трёхмерного пространства камеры - в двухмерное пространство.

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

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

Поле зрения/зона обзора (field of view)

На рисунке выше у проекционной плоскости (а значит и у изображения, которое увидит пользователь) ширина больше высоты. Ширина и высота проекционной плоскости задаются с помощью углов. Встречаются разные названия этих углов: поля зрения или зоны обзора. В английском - fields of view.

Зоны обзора задаются двумя углами. Назовём их: fovx - зона обзора по горизонтали, fovy - зона обзора по вертикали. Подробно о зонах обзора: ниже.

Z-буфер / w-буфер / буфер глубины (z-buffer / w-buffer / depth buffer)

Посмотрим на картинку, на которой представлено два треугольника: на расстоянии в 25 и 50 единиц от камеры. На рисунке (а) показано местоположение треугольников в пространстве (вид сверху), а на рисунке (б) можно увидеть конечное изображение:

Как вы возможно догадываетесь, изображение нужно рисовать начиная с самых дальных элементов и заканчивая самыми ближними. Очевидное решение: вычислить расстояние от начала координат (от камеры) до каждого объекта, а затем сравнить. В компьютерной графике используется немного более усовершенствованный механизм. У этого механизма несколько названий: z-буфер, w-буфер, буфер глубины. Размер z-буфера по количеству элементов совпадает с размером фонового и основного буферов. В z-буфер заносится z-компонента самого ближнего к камере объекта. В данном примере, там где синий треугольник перекрывает зелёный, в буфер глубины будут занесены z-координаты синего. Мы ещё поговорим о z-буферах более подробно в отдельном уроке.

Ортографическая / параллельная проекция (orthographic / parallel projection)

Операция при которой происходит уменьшение размерности пространства (было трёхмерное пространство, стало двухмерным) называется проекцией. Прежде всего нас интересует перспективная проекция, но сналача мы познакомимся с параллельной (parallel или orthographic projection).

Для вычисления параллельной проекции достаточно отбросить лишнюю координату. Если у нас есть точка в пространстве [ 3 3 3 ], то при параллельной проекции на плоскость z=1, она спроецируется в точку .

Перспективная проекция (perspective projection) на проекционную плоскость

В данном виде проекции все линии сходятся в одной точке. Именно так устроено наше зрение. И именно с помощью перспективной проекции моделируется "взгляд" во всех играх.


Сравните этот рисунок с рисунком показывающим однородные координаты из предыдущего урока. Чтобы из трёхмерного пространства перейти в двухмерное, нужно первые две компоненты векторов разделить на третью: [ x/z y/z z/z ] = [ x/z y/z 1 ].

Как я уже писал выше, проекционная плоскость может располагаться где угодно между ближней и дальней. Мы будем всегда размещать проекционную плоскость в z=1, но в этом уроке мы рассмотрим и другие варианты. Посмотрим на картинку:


Расстояние до проекционной плоскости от начала координат обозначим как d. Мы рассмотрим два случая: d=1 и d=5. Важный момент: третья компонента всех векторов после проекции должна быть равна d - все точки расположены в одной плоскости z=d. Этого можно добиться умножив все компоненты вектора на d: [ xd/z yd/z zd/z ]. При d=1, мы получим: [ x/z y/z 1 ], именно эта формула использовалась для преобразования однородных координат.

Теперь, если мы отодвинем проекционную плоскость в точку z=5 (соотвтественно d=5), мы получим: [ xd/z yd/z zd/z ] = [ 5x/z 5y/z 5 ]. Последняя формула проецирует все векторы пространства в одну плоскость, где d=5.
У нас здесь небольшая проблемка. Предыдущая формула работает с трёхмерными векторами. Но мы договорились использовать четырёхмерные векторы. Четвёртую компоненту в данном случае можно просто отбросить. Но мы не будем этого делать, так как её использование даёт некоторые специфические возможности, которые мы ещё обсудим.

Нужно найти общий делитель третьей и четвёртой компонент, при делении на который в третьей компоненте остаётся значение d, а в четвёртой единица. Делитель этот - d/z. Теперь из обычного вектора [ x y z 1 ] нам нужно получить вектор готовый к проекции (делению) [ x y z z/d ]. Делается это с помощью матрицы преобразования (проверьте результат умножив любой вектор на данную матрицу):


Последнее преобразование - это ещё не проекция. Здесь мы просто приводим все векторы к нужной нам форме. Напоминаю, что мы будем размещать проекционную плоскость в d=1, а значит векторы будут выглядеть вот так: [ x y z z ].

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

Мы рассмотрим матрицу перспективного преобразования использующуюся в DirectX:

Теперь мы знаем для чего предназначен элемент _34. Мы также знаем, что элементы _11 и _22 масштабируют изображение по горизонтали и вертикали. Давайте посмотрим, что конкретно скрывается за именами xScale и yScale.

Данные переменные зависят от зон обзора, о которых мы говорили выше. Увеличивая или уменьшая эти углы, можно масштавбировать (scale или zoom) изображение - менять размер и соотношение сторон проекционной плоскости. Механизм масштабирования отдалённо напомниает масштабирование в фотоаппаратах/камерах - принцип очень похожий. Рассмотрим рисунок:


Разделим угол fov на две части и рассмотрим только одну половинку. Что мы тут видим: увеличивая угол fov/2 (а соответсвенно и угол fov), мы увеличиваем sin угла и уменьшаем cos. Это приводит к увеличению проекционной плоскости и соответственно к уменьшеню спроецированных объектов. Идеальным для нас углом будет fov/2 = P/4. Напоминаю, что угол в P/4 радиан равен 45 градусам. При этом fov будет равен 90 градусам. Чем для нас хорош угол в 45 градусов? В данном случае не происходит масштабирования, а cos(P/4)/sin(P/4)=1.

Теперь мы можем легко масштабировать картинку по вертикали (горизонтали), используя синус и косинус половины зоны обзора (функция котангенса в C++ называется cot):

yScale = cos(fovY/2)/sin(fovY/2) = cot(fovY/2)
В DirectX используется только вертикальная зона обзора (fovY), а масштабирование по горизонатли зависит от вертикальной зоны обзора и соотношения сторон.

Напоминаю, что окно в наших программах размером в 500x500. Соотношение сторон: 1 к 1. Поэтому переменные будут равны: xScale=1, yScale=1.

Соотношение сторон стандартного монитора/телевизора: 4:3. Этому соотношению соответствуют разрешения экрана: 640x480, 800x600, 1600x1200. Мы пока не будем касаться полноэкранного режима, но можем изменить размер окна программы. Вы можете поменять размер окна (в present parameters), например, на 640X480. Но чтобы все предметы не растянулись (квадраты будут выглядеть как прямоугольники), не забудьте поменять соответствующие переменные в проекционной матрице.

Чуть не забыл, форумула для xScale в DirectX:

xScale = yScale / соотношение сторон
Соотношения сторон задаются просто: 1/1, 4/3, 16/9 - это из стандартных.

Осталось выяснить назначение элементов _33, _34 матрицы перспективного преобразования. zf - z-координата дальней плоскости (от far - далеко), а zn - z-координата ближней (от near - близко). Обратите внимание, что элемент _43 = _33 * -zn.

Легче всего понять, что именно делают эти формулы, можно на примерах. Умножим стандартный вектор [ x y z w ] на матрицу представленную выше. Рекомендую вам сделать это, взяв лист бумаги и карандаш (надеюсь вы помните как перемножать две матрицы). Компоненты вектора примут следующий вид.

1-ая = x*xScale
2-ая = y*yScale
3-я = z*(zf/(zf-zn)) + w*(-(zn*zf)/(zf-zn)) = (zf/(zf-zn))*(z - w*zn)
4-ая = (w*z)/d
Совершим проекционное преобразование (разделим все элементы на 4-ую компоненту, при этом допустим, что d=1 и w=1):

1-ая = (d*x*xScale)/(w*z) = (x*xScale)/z
2-ая = (d*y*yScale)/(w*z) = (y*xScale)/z
3-я = (zf/(zf-zn))*(z - w*zn)*(w*d/z) = (zf/(zf-zn))*(1 - zn/z)
4-ая = 1
В результате мы получили вектор вида:

[ x/(z*xScale) y/(z*yScale) (zf/(zf-zn))*(1-zn/z) 1 ]
Теперь, если вы зададите конкретные значения zf и zn, то обнаружите следующее (для положительных значений): если вектор расположен до ближней плоскости, то z-компонента после преобразования будет меньше нуля, если вектор расположен за дальней плоскостью, то z-компонента будет больше единицы.

Нет никакой разници где именно расположены ближняя и дальняя плоскости: zn=1, zf=10 или zn=10, а zf=100 (или любые другие значения) - после преобразования видимая область будет располагаться в отрезке от нуля до единицы, включительно.

Именно для этого и предназначены формулы в элементах _33, _34 проекционной матрицы - спроецировать расстояние от ближней до дальней плоскости в отрезок . Проверьте это, вычислив значения нескольких векторов для конкретных значений zn,zf (да-да, на листке бумаги!!!).

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

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

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

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

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

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

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

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

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

Мировые и экранные координаты

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

Пусть мировые координаты будут трехмерными декартовыми координатами. Где должен размещаться центр координат, и какими будут единицы измерения вдоль каждой оси, пока для нас не очень важно. Важно то, что для изображения мы будем знать какие-то числовые значения координат отображаемых объектов.

Для получения изображения в определенной проекции необходимо рассчитать координаты проекции. Из них можно получить координаты для графического устройства- назовем их экранными координатами. Для синтеза изображения на плоскости достаточно двумерной системы координат. Одна­ко в некоторых алгоритмах визуализации используются трехмерные экранные координаты, например, в алгоритме Z-буфера.

Основные типы проекций

В компьютерной графике наиболее распространены параллельная и цент­ральная проекции (рис. 2.15).

Для центральной проекции (также называемой перспективной) лучи проеци­рования исходят из одной точки, размещенной на конечном расстоянии от объектов и плоскости проецирования. Для параллельной проекции лучи про­ецирования параллельны.

Аксонометрическая проекция

Аксонометрическая проекция - разновидность параллельной проекции. Для нее все лучи проецирования располагаются под прямым углом к плоскости проецирования (рис. 2.16).

[Зададим положения плоскости проецирования с помощью двух углов - α и β, Расположим камеру так, чтобы проекция оси z на плоскости проецирова|ния Х0Y была бы вертикальной линией (параллельной оси ОУ).

Рис. 2.16. Аксонометрическая проекция

Для того чтобы найти соотношения между координатами (х, у, z ) и (X , Y , Z ) для любой точки в трехмерном пространстве, рассмотрим преобразования системы координат (х , у, z ) в систему (X , Y , Z). Зададим такое преобразование двумя шагами.

1-й шаг. Поворот системы координат относительно оси z на угол α. Такой поворот осей описывается матрицей

2-й шаг. Поворачиваем систему координат (x , у", z ") относительно оси х" на угол β - получаем координаты (X , Y , Z ). Матрица поворота

Преобразования координат выражаем произведением матриц В * А:

Запишем
преобразование для координат проекции в виде формул:

Как вы считаете, будет ли получена та же проекция, если описывать преобра­зования координат теми же двумя шагами, но в другой последовательности - сначала поворот системы координат относительно оси х на угол β, а потом поворот системы координат относительно оси z " на угол α? И будут ли вер­тикальные линии в системе координат (x , y , z ) рисоваться также вертикалями в системе координат (X , У, Z)? Иначе говоря, выполняется ли А*В - В*А? Обратное преобразование координат аксонометрической проекции. Для того, чтобы координаты проекции (X , Y , Z ) преобразовать в мировые коорди­наты (х, у, z ), нужно проделать обратную последовательность поворотов. Вначале выполнить поворот на угол -β а затем - поворот на угол - α. Запи­шем обратное преобразование в матричном виде

Матрицы поворотов:

Перемножив матрицы А -1 и В -1 , получим матрицу обратного преобразования:

Запишем обратное преобразование также и в виде формул

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

Перспективную проекцию (рис. 2.17) сначала рассмотрим при вертикальном расположении камеры, когда а=β = 0. Такую проекцию можно себе пред­ставить как изображение на стекле, через которое смотрит наблюдатель, рас­положенный сверху в точке (х, у, z ) = (0, 0, z k). Здесь плоскость проецирова­ния параллельна плоскости (хОу).

Исходя из подобия треугольников, запишем такие пропорции:

Учитывая также координату Z:

В матричной форме преобразования координат можно записать так:

Рис. 2.17. Перспективная проекция

Обратите внимание на то, что здесь коэффициенты матрицы зависят от коор­динаты z (в знаменателе дробей). Это означает, что преобразование коор­динат является нелинейным (а точнее, дробно-линейным), оно относится к классу проективных преобразований.

Теперь рассмотрим общий случай - для произвольных углов наклона каме­ры и р) так же, как и для параллельной аксонометрической проекции. Пусть (х", у", z 1 ) - координаты для системы координат, повернутой относи­тельно начальной системы (х, у, z ) на углы α и β.

Запишем преобразования координат перспективной проекции в виде:

Последовательность преобразования координат можно описать так:

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

Для такой перспективной проекции плоскость проецирования перпендику­лярна лучу, исходящему из центра (х, у, z )= (0, 0, 0) и наклоненному под углом α, β. Если камеру отдалять от центра координат, то центральная проек­ция видоизменяется. Когда камера в бесконечности, центральная проекция вырождается в параллельную проекцию.

Укажем основные свойства перспективного преобразования. В центральной

проекции:

□ не сохраняется отношение длин и площадей;

□ прямые линии изображаются прямыми линиями;

□ параллельные прямые изображаются сходящимися в одной точке.

Последнее свойство широко используется в начертательной геометрии для ручного рисования на бумаге. Проиллюстрируем это на примере каркаса до­мика (рис. 2.18).

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

Рассмотрим косоугольную проекцию, для которой лучи проецирования не перпендикулярны плоскости проецирования. Основная идея такой проекции - камера поднята на высоту h с сохранением вертикального положения плоскости проектирования (рис. 2.19).

Рис. 2.18. Параллельные линии изображаются в центральной проекции сходящимися в одной точке

Рис. 2.19. Косоугольная проекция

Получить такую проекцию можно следующим способом:

1. Выполняем поворот вокруг оси z на угол а.

2. Заменяем z " на -у", а.у" на z".

3. Выполняем сдвиг системы координат вверх на высоту камеры h

4. В плоскости (х", у", 0) строим перспективную проекцию уже рассмотрен­ным выше способом (точка схода лучей на оси z ).

Преобразование координат может быть описано таким образом. Сначала оп­ределяются (x", у", z ).

А потом выполняется перспективное преобразование

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

Примеры изображений в различных проекциях. Приведем примеры изо­бражений одинаковых объектов в различных проекциях. В качестве объектов будут кубы одинакового размера. Положение камеры определим углами на­клона α = 27°, β = 70°.

Пример аксонометрической проекции приведен на рис. 2.20.

Рис. 2.20. Аксонометрическая проекция

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

В оптических системах известно понятие фокусного расстояния. Чем больше фокусное расстояние объектива, тем меньше восприятие перспективы (рис. 2.21" и наоборот, для короткофокусных объективов перспектива наибольший (рис. 2.22). Данный эффект вы, наверное, уже замечали, если занимались съемками видеокамерой или фотоаппаратом. В наших примерах можно наблюдать некоторое соответствие величины расстояния от камеры до плоскости проецирования { z k z пл ) и фокусного расстояния объектива. Это соответствие, однако, условно, аналогия с оптическими системами здесь неполная.

Для приведенных Ниже примеров (рис. 2.21, 2.22) z пл = 700. Углы наклона камеры α = 27°, β = 70°.

Рис. 2.21. Перспективная проекция для длиннофокусной камеры ( z K = 2000)

Рис. 2.22. Перспективная проекция для короткофокусной камеры ( z K = 1200)

В случае короткофокусной камеры (z K = 1200) восприятие перспективы наиболее заметно для кубов, которые расположены ближе всего к камере. Вертикальные линии объектов не являются вертикалями на проекции (объекты разваливаются").

Усмотрим примеры косоугольной проекции (рис. 2.23, 2.24). Для нее вер­тикальные линии объектов сохраняют вертикальное расположение на проекции. Положение камеры (точки схождения лучей проецирования) описывается углом поворота α = 27° и высотой подъема h = 500. Плоскость проециро­вания параллельна плоскости (х"Оу") и располагается на расстоянии z пл = 700.

Рис. 2.23. Косоугольная перспективная проекция для длиннофокусной камеры ( z K = 2000)

Рис. 2.24. Косоугольная перспективная проекция для короткофокусной камеры ( z K = 1200)

Рассмотрим еще один пример изображения в центральной проекции - тега в стиле фильма "Звездные войны":

Отображение в окне

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

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

Введем обозначения. Пусть (Хэ, Уэ, Z э) - это экранные координаты объектов в графическом устройстве отображения. Заметим, что не следует восприни­мать слово "экранные" так, будто речь идет только о дисплеях - все ниже­следующее можно отнести и к любым другим устройствам, использующим декартову систему координат. Координаты проецирования обозначим здесь как (X, Y, Z).

Назовем окном прямоугольную область вывода с экранными координатами

X э min Уэтп) - (Хэтах Уэтах)- Обычно Приходится Отображать В Окно ИЛИ ВСЮ

сцену, или отдельную ее часть (рис. 2.25).

Рис. 2.25. Отображение проекции сцены

а - границы сцены в координатах проекции; б - в окне часть сцены, в - вся сцена с сохранением пропорций вписана в окно

Преобразование координат проекции в экранные координаты можно задать как растяжение/сжатие и сдвиг:

Х Э = КХ + dx , ; Y Э = KY + dy ; Z э = KZ .

Такое преобразование сохраняет пропорции объектов благодаря одинаково­му коэффициенту растяжения/сжатия (К) для всех координат. Заметим, что для плоского отображения можно отбросить координату Z. Рассмотрим, как можно вычислить К, dx и dy . Например, необходимо впи­сать все изображение сцены в окно заданных размеров. Условие вписывания можно определить так:

Если прибавить (1) к (3), то получим:

Из неравенств (2) и (4) следует:

Решением системы (1)-(4) для K будет: К min {Кх, Ку} = К min .

Если значение К х или значение K Y равно бесконечности, то его необходим отбросить. Если оба - то значение К min можно задать равным единице. Дга| того чтобы изображение в окне имело наибольший размер, выберем К = К min Теперь можно найти dx . Из неравенства (1):

Из неравенства (3): I

Поскольку dx 1 < dx 2, то величину dx можно выбрать из интервала I dx 1 dx dx 2. Выберем центральное расположение в окне: I

Аналогично найдем dy:

При таких значениях dx и dy центр сцены будет в центре окна.

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

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



© dagexpo.ru, 2024
Стоматологический сайт