К. В. Рябинин вычислительная геометрия и алгоритмы компьютерной графики
Скачать 1.44 Mb.
|
4.3. Преобразования проекции Проекция объектов на плоскость экрана производится по сле- дующему алгоритму: 1. Выделяется фиксированная область пространства Ξ ⊂ R 3 в виде параллелепипеда, называемая нормированными коорди- натами устройства (англ. Normalized Device Coordinates , NDC). 2. На сцене выделяется «область интереса» Ω ⊂ R 3 , т. е. часть пространства, которая должна быть видима в данный момент в соответствии с логикой работы графического приложения. 3. Ко всем вершинам всех объектов сцены применяется преобра- зование p(v) = { v ′ ∈ Ξ, v ∈ Ω v ′′ ∈ Ψ, Ψ ∩ Ξ = ∅, v ∈ Φ, Φ ∩ Ω = ∅ , т. е. преобразование, которое переводит объекты из «области интереса» в NDC. 4. На экране выделяется прямоугольная область, называемая портом просмотра (англ. Viewport ). 5. Осуществляется проекция NDC в порт просмотра путём от- брасывания координаты Z и линейного масштабирования ито- гового множества точек до совпадения с размером порта про- смотра. Конкретный вид NDC является конвенционализмом (догово- рённостью), принятым в каждом конкретном стандарте графическо- го API. В OpenGL за NDC принят куб со стороной 2 и центром в начале координат, т. е. куб [ −1, 1] × [−1, 1] × [−1, 1] . В Direct3D за NDC принят параллелепипед [ −1, 1] × [−1, 1] × [0, 1] Направление осей NDC также является конвенционализмом. Отличие осей в NDC OpenGL и Direct3D представлено на рис. 7. На основе приведённого выше алгоритма можно сформулиро- вать общее утверждение: на экран попадают те и только те объ- екты сцены, которые в результате всех преобразований попали в NDC . Это утверждение справедливо для всех современных графиче- ских API. 27 Рис. 7. Система координат, принятая в OpenGL и Direct3D Для удобства представления преобразований отображение «области интереса» в NDC выделяют в отдельную матрицу. Эту матрицу называют матрицей проекции (англ. Projection Matrix ). Однако с математической точки зрения она описывает не саму проекцию, а лишь подготовительное преобразование (умножение слева координат точки пространства на эту матрицу не понижает размерности точки, а лишь перемещает её из области интереса в NDC). Наиболее часто используемыми в компьютерной графике про- екциями являются параллельная (англ. Parallel Projection ) и пер- спективная (англ. Perspective Projection ). Параллельная проекция, как следует из названия, сохраняет параллельность прямых линий. В этом случае «область интереса» представляет собой параллелепипед, называемый параллелепипе- дом видимости (англ. View Piped ), который отображается на NDC при помощи обычных аффинных преобразований. Параллелепипед видимости и полученная в итоге проекция на экран показаны на рис. 8. Такой тип проекции используется в основном в чертёжном деле (так как не вносит искажений в объекты) и при отображении двумерной графики средствами трёхмерной (например, индикаторы здоровья, силы и боеприпасов персонажа, отображаемые поверх игровой сцены). Стороны параллелепипеда называются левой (англ. Left ), пра- вой (англ. Right ), верхней (англ. Top ), нижней (англ. Bottom ), ближ- ней (англ. Near ) и дальней (англ. Far ) плоскостями отсечения. 28 Рис. 8. Параллелепипед видимости и результат параллельной проекции Такие названия обусловлены тем, что эти стороны, по сути, ограничивают видимую область пространства, отсекая невидимые части сцены. Исходя из указанных на рис. 8 обозначений, матрица проекции для этого случая имеет вид P par = 2 r −l 0 0 − r+l r −l 0 2 t −b 0 − t+b t −b 0 0 − 2 f −n − f +n f −n 0 0 0 1 . Перспективная проекция учитывает искажения, наблюдаемые в реальной жизни, когда более далёкие от наблюдателя объекты кажутся более маленькими. Чтобы смоделировать этот эффект, «область интереса» представляется в виде усечённой пирамиды, называемой усечённой пирамидой видимости (англ. View Frustum ), расширяющейся с удалением от наблюдателя. При отображении такой области в параллелепипед NDC осуществляется сжатие объ- ектов, причём коэффициент сжатия будет зависеть от удалённости. Усечённая пирамида видимости и полученная в итоге проекция на экран показаны на рис. 9. Такой тип проекции используется для реалистичной визуализации трёхмерных сцен (при создании компьютерных игр, симуляторов, компьютерной мультипликации, кинематографических эффектов и т. п.), так как соответствует восприятию человека. 29 Рис. 9. Усечённая пирамида видимости и результат перспективной проекции Преобразование «области интереса» в NDC, используемое в данном случае, не сохраняет параллельность прямых, поэтому оно по определению не может быть выражено через аффинные. Тем не менее оно допускает матричное представление вида v = x y z w , v ′ = P persp v, v ′′ = v ′ v ′ w , где v – исходный вектор, v ′′ – результирующий вектор, P persp – матрица перспективной проекции. С учётом обозначений рис. 9 матрица перспективной проекции имеет вид P persp = 2n r −l 0 r+l r −l 0 0 2n t −b t+b t −b 0 0 0 − f +n f −n − 2f n f −n 0 0 −1 0 . Поскольку в случае аффинных преобразований v w ≡ 1 , оба типа проекции сводятся к единообразному механизму. Для задания перспективной проекции удобно бывает пользо- ваться понятием угла обзора (англ. Field Of View , FOV). Смысл этого понятия отражён на рис. 10. 30 Рис. 10. Связь угла обзора θ и усечённой пирамиды видимости В таком случае, для заданных z = n и z = f ближней и даль- ней плоскостей отсечения соответственно, элементы матрицы пер- спективной проекции могут быть вычислены на основе следующих соотношений: −l = r = n tg θ 2 , −b = t = n w h tg θ 2 , где w, h – соответственно ширина и высота сторон экрана (обычно в пикселях), на который будет произведена проекция, θ – угол обзора. Значения n и f для перспективной проекции выбираются ис- ходя из структуры сцены, но, как видно из приведённых формул, должно быть соблюдено условие n ̸= f ̸= 0 . Для параллельной про- екции это условие является более мягким: n ̸= f С учётом вышесказанного, положение объекта в NDC можно получить, преобразовав все его вершины по формуле v ′ = P M v, v ′′ = v ′ v ′ w , где v ′′ – результирующий вектор координат вершины, v – исходный вектор координат вершины, M – матрица модели (для размещения объекта на сцене, возможно – результат перемножения множества матриц), P – матрица проекции. Как правило, нормировку вектора (деление его компонентов на w ) берёт на себя графический процессор, делая это автомати- чески. От программиста же требуется вычислить лишь первичную трансформацию вершины, т. е. v ′ = P M v 31 Для работы с матрицами в приложении могут быть ис- пользованы специальные библиотеки, например, Eigen [3], OpenSceneGraph [4] или GLM [5]. Эти библиотеки предостав- ляют необходимые структуры данных и функции для того, чтобы оперировать векторами и матрицами. Задание: В целях тренировки читателю предлагает- ся реализовать мини-библиотеку работы с матрица- ми и векторами самостоятельно. Библиотека долж- на позволять конструировать матрицы аффинных преобразований, матрицы проекций и векторы, осу- ществлять их перемножение. Подсказка: Для эффективной работы графического приложения матрицы следует хранить в виде массива float[16] . Касательно векторов возможны варианты, так как часто бывают нужны векто- ры размерности 2 и 3 , причём различных типов (как float , так и int ). В связи с этим, реализуя проект на C++, имеет смысл создать шаблонный класс либо несколько классов для различных нужд. Замечание: На сегодняшний день графические процессоры при построении сцены используют одинарную точность чисел с пла- вающей точкой ( float , а не double ). Поэтому двойная точность не нужна для представления векторов и матриц, которые будут использованы непосредственно при построении сцены (и может понадобится лишь для произведения сопутствующих расчётов, предусмотренных логикой графического приложения). 32 5. Структура графического приложения Под графическим приложением будем подразумевать про- грамму, работающую с графикой посредством прямых вызовов низкоуровневого API (такое понятие, вообще говоря, является жаргонизмом, однако активно используется в литературе). 5.1. Графический контекст Ключевой структурой данных в графическом приложении яв- ляется графический контекст (англ. Graphical Context ). Он объеди- няет в себе дескрипторы всех графических ресурсов (например, объ- ектов сцены, представленных в виде массивов вершин и хранящих- ся в видеопамяти), дескрипторы точек доступа к видеодрайверу и все необходимые для управления сценой и процессом визуализации сер- висные структуры данных. Конкретная структура графического контекста различается для разных стандартов графического API и для разных платформ. Для его создания используются механизмы, предусмотренные конкретной операционной средой (например, оконной системой). В связи с этим, работая с графическим контекстом напрямую, невоз- можно полностью избавиться от системно-зависимого кода, даже если в качестве стандарта вывода графики используется OpenGL, имеющий реализации почти под все существующие платформы. Однако системно-зависимый код может быть сведён к минимуму и ограничен лишь инициализацией контекста. Все дальнейшие действия по управлению и отрисовке сцены стандартизованы и от конкретной платформы уже не зависят. Важной структурой данных, неразрывно связанной с графическим контекстом, является поверхность рендеринга (англ. Rendering Surface ) – объект в составе конкретной системы отображения (оконной или иной системы управления отображением 33 элементов графического интерфейса приложений), при помощи которого происходит демонстрация результатов визуализации сцены. 5.2. Обобщённое графическое приложение Большинство графических приложений интерактивны, т. е. предполагают активное участие пользователя в работе. Типичными примерами являются компьютерные и видеоигры, симуляторы, графические редакторы. В таких приложениях управление сценой полностью предоставлено пользователю, который инициирует своими командами большую часть происходящих в приложении действий. Существуют, однако, и такие графические приложения, как, например, видеоплееры. В них влияние пользователя на про- исходящее сводится к заданию начальных настроек (разрешение экрана, настройка звука, субтитров и т. д.), а затем лишь к приоста- новке/возобновлению воспроизведения и перемотке. Роль основного управляющего механизма берёт на себя сама система, используя средства слежения за временем (таймеры). Тем не менее в обоих случаях внутренняя структура графи- ческого приложения почти идентична, а различается лишь набор допустимых для пользователя действий и реакций системы на них. Чаще всего графическое приложение содержит потенциально бес- конечный цикл (прерывание которого происходит лишь по команде пользователя на завершение приложения). В этом цикле с учётом текущего состояния приложения (отданных пользователем команд) перестраивается сцена и выполняется отправка всех необходимых данных на графический конвейер. При необходимости, в конце цикла выполняется команда обновления поверхности рендеринга. Обычно поверхность рендеринга устроена с использованием механизма двойной буферизации (англ. Double Buffering ): имеет- ся два буфера, видимый (показываемый пользователю в данный мо- мент) и активный (подверженный изменению в процессе работы гра- фического конвейера). Команда обновления такой поверхности рен- деринга называется сменой буферов (англ. Swap Buffers ). Она пред- 34 полагает ожидание завершения всех команд, отправленных на кон- вейер, и обмен ролями активного и видимого буферов. Общую структуру графического приложения можно описать следующей последовательностью шагов: 1. Инициализировать графический контекст и поверхность рен- деринга. 2. Создать графические ресурсы. 3. Построить сцену. 4. Пока не дана команда завершения, повторять: 4.1. Изменить состояние сцены в соответствии с текущим со- стоянием приложения. 4.2. Отправить данные на графический конвейер. 4.3. Обновить поверхность рендеринга. 5. Удалить графические ресурсы. 6. Удалить графический контекст и поверхность рендеринга. Состояние сцены включает в себя набор присутствующих на ней объектов, их положение (т. е. значения их матриц преобразова- ния) и параметры (визуальные свойства), значения матриц проек- ции и параметры графического конвейера. Набор параметров гра- фического конвейера называется машиной состояний (англ. State Machine ). Эти параметры управляют работой различных этапов кон- вейера в пределах допустимых вариаций, описанных стандартом гра- фического API. Шаги (2) и (3) в указанном выше алгоритме иногда вносят в те- ло цикла (4). Однако создание ресурсов – затратная операция, потому рекомендуется выносить её в отдельный этап и в разумных пределах осуществлять опережающую загрузку. То же самое касается началь- ного построения сцены (под которым понимается инициализация по- ложения и визуальных свойств объектов). По тем же причинам этап (4.1) следует делать как можно более коротким, не допуская «холостых» изменений состояния объектов и конвейера (многократных изменений одного и того же свойства без вызова отрисовки). Следует обратить особое внимание на шаги (5) и (6). Хотя при завершении приложения ОС берёт на себя задачу утилизации всех 35 выделенных ресурсов, хорошим тоном является полная очистка па- мяти и удаление всех созданных ресурсов вручную. Это важно в слу- чае, если написанный код затем будет перемещён в более крупный проект, куда войдёт в составе отдельного модуля. 5.3. Анимация Цикл (4) не содержит никаких сторонних средств организа- ции задержки и выполняется с той максимальной скоростью, какую обеспечивает система. Шаг (4.1) должен учитывать этот факт в логи- ке своей работы, если в нём предусмотрена программная анимация (англ. Animation ). Анимация – это изменение свойств сцены (или отдельных объ- ектов сцены) с течением времени, демонстрируемое пользователю в виде последовательности кадров, каждый из которых по возможно- сти минимально отличается от предыдущего (сохраняется межкад- ровое соответствие , англ. Interframe Coherence ). Фактическая скорость перерисовки сцены может меняться в зависимости от внешних факторов, например текущей загружен- ности вычислительной системы. Чтобы сделать скорость анимации независимой от фактической скорости перерисовки, необходимо программно измерять время, затраченное на одну итерацию, и использовать его в качестве масштабного коэффициента для ве- личины изменения свойств объектов. Например, если с момента предыдущего измерения прошло ∆ t секунд (в системах визуализа- ции, работающих в реальном времени, ∆ t < 1 ) и есть некоторый параметр сцены p , который в соответствии с логикой приложения должен линейно измениться на ∆ p за секунду, то p (i) = p (i −1) + ∆ p ∆ t , где i – номер итерации, p (i) – значение параметра p на i -й итерации. У монитора, при помощи которого пользователь просматри- вает результат визуализации, есть некоторая рабочая частота, т. е. 36 скорость обновления изображения. На сегодняшний день большин- ство мониторов работают на частоте 60 Гц, т. е. тратят на обновле- ние 1/60 секунды. Следовательно, приложению нет смысла генери- ровать больше изображений в секунду, чем способен отобразить мо- нитор. Для удовлетворения такого ограничения используется верти- кальная синхронизация (англ. Vertical Synchronization , vsync) – ме- ханизм блокировки процесса на шаге (4.3) до готовности монитора. На этапе отладки вертикальную синхронизацию можно отключить, чтобы программно оценить скорость выполнения под- готовки изображения. Однако в итоговом продукте вертикальная синхронизация должна быть включена, чтобы приложение не совершало «холостых» итераций. В случае отображения сложных сцен, скорость подготовки изображения может оказаться меньше скорости обновления мони- тора. В идеале это означает необходимость оптимизации кода и графических ресурсов, однако на практике оптимизация не всегда приводит к желаемому результату. Именно поэтому для каждого графического приложения формулируют минимальные требования к конфигурации вычислительной системы, при удовлетворении которых приложение гарантированно может обеспечить прием- лемую для пользователя скорость визуализации. На сегодняшний день стандартом де-факто «идеальной» скорости является 60 кадров в секунду (англ. Frames Per Second , FPS). Однако приемлемыми значениями можно считать и 30 , и даже 20 FPS. Согласно иссле- дованиям минимальная скорость для относительно комфортного восприятия движений человеком – 8 FPS [6]. |