Свойства
|
OpenGL
|
Direct3D
|
XNA
|
Поддержка
различных платформ, число
|
Да, множество
|
Да, три
|
Да, две
|
Сложность
освоения
|
Высокая
|
Высокая
|
Низкая
|
Базовый язык
(нативный)
|
C
|
C
|
C#
|
Поддерживаемые
языки
|
Большинство
языков
|
Большинство
языков
|
NET языки
|
Высокая
производительность
|
Да
|
Да
|
Нет
|
Лицензионные
ограничения
|
Нет
|
Нет
|
Да
|
Поддержка
производителем
|
Нет
|
Да, платно
|
Да, платно
|
Платформа
Библиотеки
|
Нативный код
|
Нативный код
|
Управляемый код
|
1.5.3 Общие принципы работы с графическими API
Direct3D и OpenGL имеют ряд серьезных
различий в их структуре и наборе предоставляемых функций, но тем не менее они
выполняют одну и ту же роль, а именно подготавливают систему для исполнения
кода шейдера на GPU [7]. Этот процесс в общих чертах может быть разбит на следующие
этапы:
. Создание графического устройства (device) представляющее собой
своеобразную программную модель графического процессора. Именно через него
осуществляется почти работа с GPU.
. Подготовка буфера вершин (vertex buffer), содержащего перечень
координат всех вершин, а так же некоторых дополнительных параметров. К примеру,
в этой роли может выступать значение освещенности вершины, ее текстурные
координаты (они используются для привязки текстуры к графическому примитиву),
векторы нормали и.т.д.
. Подготовка текстур. На этом этапе все
текстуры используемые приложением копируются в специально отведенную для них
область графической памяти, откуда, позже будут считаны шейдерной программой.
4. Загрузка файлов-эффектов, представляющих собой набор
шейдеров, используемых при визуализации текущего объекта.
5. Загрузка в память графического адаптера
всех матриц и констант, необходимых для исполнения эффекта. На данном этапе так
же происходит ассоциация самплеров (sampler) эффекта с ранее загруженными текстурами.
. Далее следует ключевой этап -
визуализация сцены (Scene). Именно здесь в дело вступает графический конвейер, который
проделывает всю работу по превращению набора точек в законченное трехмерное
изображение.
. После окончания этапа визуализации буфер
кадра содержит изображение, являющееся результатом рендеринга. Далее оно может
быть либо отображено на экран, либо сохранено в текстуру.
Следует заметить, что перечисленные выше этапы едва ли можно
назвать четкой инструкцией к написанию графических приложений. Часть из них
можно попросту выкинуть, часть поменять местами. Все зависит от конкретной
реализуемой задачи.
1.6 Теоретический обзор шейдерных эффектов
1.6.1 Равномерное освещение
Равномерное освещение (ambient lighting) обеспечивает постоянное
начальное освещение для всей сцены. Оно освещает все вершины объектов
одинаково, потому что не зависит ни от каких других факторов освещения. Это
самый простой и быстрый тип освещения, но при этом дает наименее реалистичный
результат. Формула для вычисления этой модели освещения так же очень проста, т.
к. там всего одна арифметическая операция - умножение. Для ее вычисления
достаточно перемножить цвет материала на интенсивность освещения:
(1)
1.6.2 Диффузионная модель освещения
Диффузная модель освещения (diffuse lighting model) - модель освещения,
которая зависит от положения источника освещения и от объектной нормали
поверхности. Поскольку излучение света одинаково во всех направлениях, видовой
вектор не имеет значения, т.е. v = 0. Такой метод требует
большего вычисления, так как изменяется для каждой вершины объекта, однако
неплохо затеняет объекты и придает им объем. Свет падает, не заполняя всю
поверхность одинаковым цветом (как в случае с раномерным освещением), а
создается впечатление, что, свет направлен на какую либо поверхность.
Рисунок 1.2. Диффузная модель освещения
Если вектор позиции источника освещения
перпендикулярен поверхности, то никакой матовости не будет наблюдаться, потому
что интенсивность света зависит от угла б. Для расчета диффузной модели
освещения используется формула (по закону Ламберта):
(2)
1.6.3 Бликовая модель освещения
В этой модели освещения помимо векторов
позиции источника освещения и нормали (как в случае с диффузной моделью
освещения) используются еще два вектора: видовой вектор и вектор отражения.
Бликовую модель освещения (specular lighting model) предложил Буи-Туонг
Фонг [13].
Рисунок 1.3. Бликовая модель освещения
Угол между видовым вектором и вектором
отражения - в. Чем больше угол в, тем ярче бликовое освещение. Поэтому бликовая
модель освещения вычисляется по следующей формуле:
(3)
где п - коэффициент яркости
свечения.
С ростом параметра п отражение
становиться все более бликовым и все более концентрируется вдоль направления
вектора отражения R.
1.6.4
Модификация модели свещения по Блину
Джим Блинн [6] придумал альтернативный способ вычисления
бликового освещения, который устраняет дорогие вычисления над вектором
отражения.
Общая формула имеет вид:
(4)
Он ввел промежуточный вектор (half vector), который является
средним значением между видовым вектором и вектором позиции источника освещения
1.6.5 Тени ShadowMap
Тени являются важной зрительной подсказкой
как в реальности, так и в визуализированных сценах. На самом низком уровне тени
предоставляют информа-цию о расположении объектов относительно друг друга и
источников света, даже если эти источники на сцене не видны. Когда речь идет об
играх, тени могут сделать игровой мир совершенно жутким. Представьте, что вы
заворачиваете за угол в подземелье, освещенном лишь факелами, и входите в тень
своего самого страшного кошмара Питер Пен отдыхает'[5].
На сегодняшний день существует множество
алгоритмов построения теней. Эти алгоритмы являются важными в компьютерной
индустрии, так как они помогают реализовать важную часть в представлении
объектов моделируемого мира, без тени объекты не будут выглядеть реалистичными.
Существуют такие алгоритмы как Shadow
volume, Ray casting, Photo mapping, Radiosity, Shadow Mapping.
Shadow volume
Это техника используется компьютерной
графике для воспроизведения теней в отображаемой сцене. Впервые техника была
представлена Франком Кровом в 1977 году [20] как геометрически смоделированная
3D поверхность, закрывающая
собой источник света. Shadow volume разделяла виртуальный мир на две части: то что
находилось в тени и то что находилось не в тени.
Shadow volume становилась популярной
техникой для отображения теней в реальном времени, так же как и более
популярная shadow mapping. Техника shadow volume требует создания геометрии объекта-тени, что
может отразиться на производительности CPU (зависит от реализации).
Преимущество метода shadow map относительно SV в том, что она чаще
всего быстрее, в полигоны shadow volume часто очень большие в пределах пространства
экрана и требуют большого времени для отрисовки (особенно для выпуклых
объектов), тогда как карты теней не имеют этого ограничения.
Ray casting
Он используется для решения разнообразных
проблем в компьютерной графике, связанных с пересечением лучей света на
поверхности. В компьютерной графике способ был впервые представлен в 1982 году
на докладе Скота Роса по описанию метода для рендеринга CSG models [21].
Ray Casting имеет отношение к:
· Общая проблема определения
первого пересечения объекта с лучом.
· Методика для удаления невидимых
поверхностей, основанная на поиске первого пересечения луча, который
проектируется из точки обозрения к каждому пикселю изображения.
· Нерекурсивный вариант трассировки
лучей, при котором «бросаются» только первичные лучи.
· Метод прямого объёмного рендеринга,
также называемый «volumeray casting (англ.)».
Рейкастинг не является синонимом к
рейтрейсингу (трассировке лучей), но он может быть представлен как сокращённая
и существенно более быстрая версия алгоритма трассировки лучей. Оба алгоритма
являются «image order» и используются в компьютерной графике для рендеринга
трёхмерных сцен на двухмерный экран с помощью проекционных лучей, которые
проектируются от глаз обозревателя к источнику света. Метод бросания лучей не
вычисляет новые тангенсы лучей света, которые возникнут после того, когда луч,
который проектируется от глаза к источнику света, пересечётся с поверхностью.
Эта особенность делает невозможным точный рендеринг отражений, преломлений и
естественной проекции теней с помощью рейкастинга. Однако все эти особенности
могут быть добавлены с помощью «фальшивых» (обманных, аппроксимационных)
методик, например, через использование текстурных карт или другие методы.
Высокая скорость вычисления сделала рейкастинг удобным методом рендеринга в
ранних компьютерных играх с трёхмерной графикой реального времени.
В реальной природе источник света
испускает луч света, который, «путешествуя» по пространству, в конечном счёте
«натыкается» на какую-либо преграду, которая перерывает распространение этого
светового луча. Луч света можно представить в виде потока фотонов, который
движется вдоль вектора луча. В какой-либо точке пути с лучом света может
случиться любая комбинация трёх вещей: поглощение, отражение (рефлекция) и
преломление (рефракция). Поверхность может отразить весь световой луч или
только его часть в одном или нескольких направлениях. Поверхность может также
поглотить часть светового луча, что приводит к потере интенсивности отраженного
и / или преломлённого луча. Если поверхность имеет какие-либо свойства
прозрачности, то она преломляет часть светового луча внутри себя и изменяет его
направление распространения, поглощая некоторый (или весь) спектр луча (и,
возможно, изменяя цвет). Суммарная интенсивность светового луча, которая была
«потеряна» вследствие поглощения, преломления и отражения, должна быть в
точности равной исходящей (начальной) интенсивности этого луча. Поверхность не
может, например, отразить 66% входящего светового луча, и преломить 50%, так
как сумма этих порций будет равной 116%, что больше 100%. Отсюда истекает, что
отраженные и / или преломлённые лучи должны «стыкаться» с другими
поверхностями, где их поглощающие, отражающие и преломляющие способности снова
вычисляются, основываясь на результатах вычислений входящих лучей. Некоторые из
лучей, сгенерированных источником света, распространяются по пространству и, в
конечном счете, попадают на область просмотра (глаз человека, объектив фото-
или видеокамеры и т.д.). Попытка симулировать физический процесс
распространения света путём трассировки световых лучей, используя компьютер,
является чрезмерно расточительным, так как только незначительная доля лучей,
сгенерированных источником света, попадает на область просмотра.
Photon mapping
В компьютерной графике, photon mapping это двухходовой алгоритм
глобального освещения разработанный Henrik Wann Jensen [22] для решения
проблемы выравнивания при рендеренге. Лучи исходящие из источника света и лучи
исходящий из камеры трассируются самостоятельно, пока не встретиться некоторый
предел, затем они соединяются на последующем шаге для создания radiance value (излучающая величина). В
особенности, это искусная симуляция преломления света проходящего через
прозрачную субстанцию такую как стакан воды, diffuse interreflection между освещённым
объектами, subsurface scattering света в полупрозрачных материалах, и некоторые
эффекты такие как испарение воды и туман. Это может так же быть расширено более
аккуратной симуляцией света, та-кой как spectral rendering.
Shadow Mapping
Карты теней (Shadow maps) широко используются в
отображении теней в работе с компьютерной графикой. Shadow mapping, впервые был представлен
Ленсом Вильянсом в 1978 году, в докладе «Casting curved shadows on curved surfaces» [23].
Теория метода отображения тени проста.
Вопрос: какие части сцены попадут в тень'' Ответ, части, на которые не падает
непосредственно свет. Представьте, что вы наблюдаете сцену, находясь в
источнике света Что «увидел» бы источник света, будь он камерой? Все, что
наблюдается с позиции источника света, освещается, а все остальное попадает в
тень. Различие между наблюдением с позиции камеры и наблюдением с позиции
источника света иллюстрируется на рис. 3. С позиции камеры и источника света
сцена выглядит по-разному.
Рисунок 1.4. Изображение сцены с позиции
камеры и источника света
При визуализации сцены с позиции источника
света побочным эффектом является заполнение буфера глубины полезной
информацией. Благодаря этой информации мы для каждого пикселя знаем
относительное расстояние от источника света до ближайшей поверхности. Эти
поверхности освещаются источником света Все остальные поверхности, удаленные от
источника света, остаются в тени.
Чтобы получить тени, нужны ярко освещенные
области, которые контрастно подчеркнут тускло освещенные фрагменты, превратив
их в тени. Возникает вопрос: как определить, какие области освещать? Данный
вопрос является ключевым моментом при отображении тени. Определив, где
рисовать, мы раскрасим эти области в яркие оттенки, просто используя большие
коэффициенты освещения (вдвое больше, чем для затененных областей).
Основной нашей целью является
проектирование карты тени (вида с позиции источника света) сцены обратно на
сцену так, будто свет исходит от источника света, но наблюдение ведется с
позиции камеры. Мы проектируем полученные глубины, представляющие расстояние от
источника света до первого объекта, на который падают лучи света. Перевод
текстурных координат в нужную систему координат потребует немного
математических расчетов
В графическом конвейере идет процесс
преобразования вершин из пространства объектов в систему координат наблюдения,
затем - в усеченное пространство нормированных координат устройства и, наконец,
- в пространство окна. В работе с этими преобразованиями участвуют две матрицы,
одна представляет проекцию с позиции источника света, вторая - обычную проекцию
камеры. Два набора соответствующих преобразований показаны на рис. 1.5.
Рисунок 1.5. Процесс перехода из системы
наблюдения камеры в систему наблюдений источника света.
Большой стрелкой в центре на рисунке 4
показаны преобразования, которые нужно применить к текстурным координатам,
линейным в системе наблюдения
Процесс проектирования текстуры обычно
начинается с генерации текстурных координат, линейных в системе наблюдения. В
результате этого процесса автоматически создаются текстурные координаты. В
отличие от генерации текстурных координат, линейных в системе объекта, эти
координаты не привязаны к геометрии. В данном случае подразумевается как бы
кинопроектор, проектирующий текстуру на сцену. Однако здесь проекция
выполняется не на плоский экран, как в кинотеатре. Представьте, что вы идете
перед проектором, и фильм проектируется на ваше тело, имеющее неправильную
форму Тот же процесс происходит и здесь
В конце нам нужно получить текстурные
координаты, указывающие в нашу карту тени из усеченного пространства источники
света. Начинаем с проектирования текстурных координат, линейных в системе
наблюдения, в пространство «глаза камеры». Следовательно, вначале нужно перейти
во внешнюю систему координат, потом - в систему с центром в источнике света, а
затем - в усеченное пространство источника света. Это преобразование можно
обобщить следующей последовательностью матричных умножений.
(5)
Однако это еще не все. Усеченного
пространства источника света недостаточно. Помните, что для всех координат (х,
у и z)
усеченное пространство ограничивается диапазоном [-1,1]. Текстуру глубины карты
тени, подобно всем стандартным двухмерным текстурам, нужно индексировать в
диапазоне [0,1]. Кроме того, глубины, с которыми нужно сравнивать значения,
принадлежат диапазону [0,1], поэтому координату z также нужно перевести в
этот диапазон Для этого следует выполнить масштабирование с коэффициентом одна
вторая (S)
и сместить результат на одну вторую (В).
(6)
Если вы не знакомы с матричной формой
записи, принятой в OpenGL, у вас может возникнуть вопрос, почему эти матрицы идут в
обратном порядке. Ведь вначале нужно применить матрицу, обратную к относящейся
к камере матрице проекции модели, а матрица трансляция (или смещения) на одну
вторую применяется последней. В чем дело? В действительности все очень просто. OpenGL действует матрицей (М)
на координату (Т) в обратном порядке. Поэтому чтобы представлять порядок
преобразований, применяющихся к координатам, следует читать выражения справа
налево:
(7)
К сожалению, для большинства теневых
текстур, созданных по технологии shadow mapping допускает алиасинг - резкие границы теней.
Современные видео-карты имеют встроенные методы для понижения алиасинга на
простых текстурах: а именно mipmapping и anisotropic filtering. Эти методы не подходят
к стандартным теневым картам, так как они могут изменить глубину соседних
пикселей, которая хранится в компоненте цвета текстуры.
Для вычисления теней в общих сценах и
борьбы с алиасинг используется процентная Близкая Фильтрация (Percentage Closer Filtering, PCF) обеспечивает решение
проблемы алиасинга карты теней. Ключевой момент в том, что корректный алгоритм
фильтрации нуждается в выявление результатов срав-нения глубин, вместо их
фильтрации. Это совершается выборочно семплированием карты теней, таким
образом, требуя множество семплов для уничтожения помех.
Карты глубин хранит распределение глубин
каждого пикселя вместо единой глубины. Как результат, PCF может быть сделан как
препроцесс.
Однако, карта глубин не подлежит
реализации на аппаратном уровне по двум причинам: каждый пиксель должен
кодироваться как кусочно-линейная функция, используя большое количество данных,
а кроме того, процедура усреднения двух распределений не нулевая.
Тусклость карты теней кодируется
распределением глубин, используется фиксированное количество сохранённых
пикселей. Каждый пиксель хранит функция в карте глубин, функция эта создаётся
из фиксированного набора точек. Таким образом, алгоритм имеет преимущество в
скорости.
Альтернативное решение проблемы алиасинга
карты теней это изменение проекции карты теней. Этот подход рассматривается в adaptive shadow maps,
perspective shadow maps, light space perspective shadow maps и trapezoidal shadow maps.
2.
Проектирование 3D-приложения
Для проектирования 3D-приложения необходима библиотека классов,
которая облегчает процесс разработки такого рода приложений. Такую библиотеку
классов также часто называют «3D движком», Над разработкой «3D движка» работают многие
коммерческие фирмы с большим штатом программистов в течение длительного
времени, но все эти «3D движки» закрыты или являются очень дорогостоящими. В связи с
тем, что мы не обладаем большими финансовыми и штатными резервами и также
ограничены во времени, будем проектировать собственный «3D движок» c минимальным достаточным
набором функций.
2.1 Постановка задачи
Цель данной работы - разработка 3D-приложения на основе
библиотеки классов. Разработанная библиотека классов должна предоставлять
пользова-телю следующий перечень возможностей:
выводить, управлять Windows - окнами
подключать / отключать графическую библиотеку, в нашем случае
- OpenGL
обрабатывать действия пользователя, например нажатие клавиш и
перемещение мыши
уметь манипулировать математикой основных 3d данных:
) вектора разной размерности (2,3,4 компонентные),
) матрицы (3,4 разрядные),
) кватернионы
) углы Эйлера, а также их взаимное преобразование, а именно
переход из углов Эйлера в матрицу и наоборот
загружать / выгружать текстуры (файловые изображения)
уметь создавать базовые модели плоскость, куб, сфера, торус
уметь загружать / выгружать произвольные 3d-модели
загружать шейдеры
передавать данные в шейдер
задавать материалы к загруженным 3d-моделям
работа с внеэкранными буферами
D движок сложная структура и может быть представлена в виде,
как показано на рис. 2.1. Причем заметим, что подсистемы расчета
физики и подсистема
воспроизведения звука не обязательны для нашего минимального 3D движка, поэтому мы их
опустим, а подсистемы пользовательского ввода и подсистема вывода графики
необходимы.
Рисунок 2.1 Общая схема 3D-движка
Модуль Камера предназначен для создания и управления камерой наблюдателя
в нашем проектируемом 3d мире
Модуль Текстуры предназначен загрузки изображений и преобразований
ее формат OpenGL. В нашей программе мы используем TGA формат для загрузки изображения, как один
из наиболее распространенный.
Модуль шейдеры предназначен компиляции, отладки, подключение к
программе, а также передачи из программы в шейдер параметров
Модуль внеэкранный буфер предназначен
Модуль 3d математика
предназначен манипулировать математикой основных 3d данных:
) вектора разной размерности (2,3,4 компонентные),
) матрицы (3,4 разрядные),
) кватернионы
) углы Эйлера, а также их взаимное преобразование, а именно
переход из углов Эйлера в матрицу и наоборот
Модуль Справочная информация предназначен для вывода справочной
информации о ходе работы приложения (какая видео карта, как откомпилировались
шейдеры и т.д.) это нужно для быстрого анализа ошибок приложения при запуске на
других компьютерах и отличной от используемой видеокарты.
Модуль OpenGL API функции необходим для описания и подключений функций OpenGL и его расширений
Модуль приложения предназначен для создания окна windows и инициализации контекста OpenGL. В данной разработке мы используем OpenGL версии 3.3.
Модуль 3d модель
предназначен создания базовых примитивов базовые модели плоскость, куб, сфера,
торус, а также произвольных моделей в формате bin. Модель в формате bin представляет
собой бинарный файл, в котором записан массив мешей, где каждый меш описывается
следующими паромерами:
общее количество данных
- массив данных, в формате (вершина, текстурная
координата, нормаль)
- количество индексов
массив индексов
Модуль материалы предназначен для описания структуры
материала, а также передачи данных в шейдер. Считаем, что материал описывается
такими параметрами:
Свечение материала
Фоновое освещение материла
Рассеянный свет источника света
Отраженный свет источника света
Модуль тени предназначен для описания алгоритмов построения
теней от 3d
объектов
Модуль освещение предназначен для описания, создания ми
управления источниками света, а также передачи данных в шейдер. В данной работе
мы будем использовать направленный источник света. Считаем, что свет
описывается следующими параметрами:
Свечение источника света
Фоновое освещение источника света
Рассеянный свет источника света
Отраженный свет источника света
Позиция источника света
Направление источника света
Проекционная матрица источника света
2.2 Архитектура 3D-приложения с
использованием проектируемого 3D движка
Решение задачи проектирование 3D-приложения с 3D движком существенно
сокращает время разработки, а также облегчает понимание работы 3D приложения и сводится к
созданию и вызову соответствующих классов и модулей в основной программе.
3.
Реализация 3D-приложения
В данном разделе представлен и расписан алгоритм добавления
тени для 3D
объектов на основе теневой карты (shadow map) с фрагметнтами программного кода
и шейдерами. Весь программный код 3D - приложения приведен в приложениях А, Б, В, Г,
Д соответственно
3.1 Обобщенный алгоритм работы 3d-программы
Обобщенный алгоритм работы 3d-программы представлен на
рис. 3.1 и состоит из 8 шагов.
. Ввод исходных данных
На данном этапе вводиться ширина и высота окна
визуализирующий наш 3d мир. Это способность очень важна, если мы хотим
демонстрировать нашу программу на разных типах визуализации информации -
монитор, проектор, плазменный телевизор.
Также здесь вводятся модели для рисования
Источники света
Текстуры
Материалы
Дополнительный буфер
. Инициализируется Windows-окно и контекст OpenGL 3.3.
. Обработка очереди сообщений Windows-окна
. Обработка ввода с клавиатуры пользователя
. Рисование кадра 3D-приложения
. Пересчет кадра 3D-приложения
. Проверка условий работает ли 3D-приложение
. Деинициализация Windows-окна и контекста OpenGL 3.3
Рисунок 3.1 Обобщенный алгоритм работы 3d-программы
3.2 Рисование кадра 3d-приложения
Рисование кадра 3D-приложения представляет собой двух этапный
алгоритм (рис. 3.2) и состоит следующих этапов:
рисование сцены в текстуру тени.
рисование итогового изображения вместе с тенью
Рисунок 3.2 Алгоритм рисования кадра 3D-приложения
Подробный алгоритм рисование сцены в текстуру тени представлен на
рис. 3.3 и состоит в свою очередь из 6 этапов, а подробный алгоритм рисование
итогового изображения вместе с тенью рисунок 8 соответственно.
Рисование сцены в текстуру тени
Для получения теневой карты нам необходимо получить буфер
глубины сцены относительно положения и направления источника освещения. Мы
используем направленный источник освещения, чтобы получить буфер глубины сцены
для такого источника нам понадобиться построить две матрицы:
· Матрицу вида (view matrix)
· Матрицу проекции (projection matrix)
Как вы можете заметить, это те же самые матрицы, которые
используются в камере, поэтому удобно использовать существующие функции для
работы с камерой, чтобы произвести рендер сцены относительно источника
освещения.
На каждый источник освещения необходим дополнительный проход
рендера сцены, с использованием камеры источника освещения. В данном случаи у
нас используется только один источник освещения, поэтому понадобиться только
один дополнительный проход рендера.
Рисунок 3.3 Алгоритм рисования сцены в текстуру тени
Стоит также отметить, что для направленного источника
освещения используется не перспективная матрица проекции, а ортогональная, ее
построение выглядит следующим образом:
const mat4 OrthoProjection (float left, float
right,bottom, float top,zNear, float zFar)
{float tx = - (right + left) / (right - left),= -
(top + bottom) / (top - bottom),= - (zFar + zNear) / (zFar - zNear);
mat4 (2 / (right - left), 0, 0, tx,
, 2 / (top - bottom), 0, ty,
, 0, -2 / (zFar - zNear), tz,
0, 0, 0, 1);
}
Теневая карта использует буфер глубины (depth buffer), для
того, чтобы определить, находится ли пиксель в прямой видимости источника
освещения, либо он чем-то загорожен.
Одним из полезных свойств построения теневой карты является
то, что ее построение не зависит от сложности геометрии на сцене, необходимо
лишь получить буфер глубины для каждого из обсчитываемых источников освещения.
Для того, чтобы получить буфер глубины, нам необходимо:
Создать текстуру для хранения буфера глубины
Создать Framebuffer Object (FBO) и привязать к нему текстуру
Настроить камеру и выполнить рендер сцены в созданный FBO
Начнем по порядку, для начала создадим текстуру для хранения
буфера глубины, делается это следующим образом:
// функция создания текстуры для хранения буфера глубины
GLuint TextureCreateDepth (GLsizei width, GLsizei
height)
{texture;
// запросим у OpenGL свободный индекс текстуры(1,
&texture);
// сделаем текстуру активной(GL_TEXTURE_2D, texture);
// установим параметры фильтрации текстуры - линейная
фильтрация
glTexParameteri
(GL_TEXTURE_2D,_TEXTURE_MIN_FILTER, GL_LINEAR);(GL_TEXTURE_2D,_TEXTURE_MAG_FILTER,
GL_LINEAR);
// установим параметры «оборачиваниея» текстуры - отсутствие
оборачивания
glTexParameteri (GL_TEXTURE_2D,_TEXTURE_WRAP_S,
GL_CLAMP_TO_EDGE);(GL_TEXTURE_2D,_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// необходимо для использования depth-текстуры как shadow map
glTexParameteri
(GL_TEXTURE_2D,_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexImage2D (GL_TEXTURE_2D, 0,
GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
// проверим на наличие ошибок_CHECK_FOR_ERRORS();texture;
}
// создадим текстуру для хранения буфера глубины
GLuint depthTexture = TextureCreateDepth
(DEPTH_TEXTURE_WIDTH, DEPTH_TEXTURE_HEIGHT);
Отдельно стоит сказать про размеры текстуры для хранения
буфера глубины, часто, для использования этой текстуры как теневой карты, берут
удвоенный размер окна, в которое происходит рендер. Но это совсем не
обязательное требование, размер надо подбирать исходя из задачи.
Далее нам необходимо создать и настроить FBO, рендер сцены мы
будем осуществлять с его использованием, создание FBO выглядит следующим
образом:
// Framebuffer Object (FBO) для рендера в него буфера
глубиныdepthFBO = 0;
// переменная для получения состояния FBOfboStatus;
// создаем FBO для рендера глубины в текстуру(1,
&depthFBO);
// делаем созданный FBO текущим(GL_FRAMEBUFFER, depthFBO);
// отключаем вывод цвета в текущий FBO
glDrawBuffer (GL_NONE);(GL_NONE);
// указываем для текущего FBO текстуру, куда следует
производить рендер глубины
glFramebufferTexture (GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT, depthTexture, 0);
// проверим текущий FBO на корректность((fboStatus = glCheckFramebufferStatus
(GL_FRAMEBUFFER))!= GL_FRAMEBUFFER_COMPLETE)
{_ERROR («glCheckFramebufferStatus error 0x %
X\n», fboStatus);
return false;
}
// возвращаем FBO по-умолчанию(GL_FRAMEBUFFER, 0);
После создания FBO и привязки к нему текстуры мы можем
выполнить рендер всей сцены с использованием этого FBO:
// установим активный FBO(GL_FRAMEBUFFER, depthFBO);
// размер вьюпорта должен совпадать с размером текстуры для
хранения буфера глубины
glViewport (0, 0, DEPTH_TEXTURE_WIDTH,
DEPTH_TEXTURE_HEIGHT);
// отключаем вывод цвета(GL_FALSE,
GL_FALSE, GL_FALSE, GL_FALSE);
// включаем вывод буфера глубины(GL_TRUE);
// очищаем буфер глубины перед его заполнением
glClear (GL_DEPTH_BUFFER_BIT);
// отключаем отображение внешних граней объекта, оставляя
внутренние(GL_FRONT);
// выполним рендер сцены с использованием шейдерной программы
и камеры источника освещения(depthProgram, lightCamera);
Во-первых, необходимо пояснить, что при заполнении буфера
глубины нет никакой необходимости обрабатывать цвет пикселя, нам необходимо
узнать только его глубину по отношению к источнику освещения.
Во-вторых, рендер внутренних граней объекта помогает избежать
некоторых артефактов при использовании теневой карты. Однако данный способ
подходит только для замкнутых выпуклых объектов, именно такие мы и используем в
этом уроке.
В-третьих, рендер сцены мы производим с использованием
специальной шейдерной программы, в этой программе мы можем отключить все лишние
расчеты, оставив только необходимые для получения глубины.
В минимальном варианте вершинный шейдер для такой шейдерной
программы выглядит следующим образом:
layout (location = VERT_POSITION) in vec3
position;
// параметры преобразованийstruct Transform
{modelViewProjection;
} transform;main(void)
{
// переводим координаты вершины в однородные_Position =
transform.modelViewProjection * vec4 (position, 1.0);
}
Т.к. нас интересует только глубина фрагментов, а не их цвет,
то фактически фрагментный шейдер может быть пустым:
main(void)
{
}
Рисования итогового изображения вместе с тенью
Рисунок 3.4 Алгоритм рисования итогового изображения вместе с
тенью
Как уже отмечалось ранее, смыл использования теневой карты
заключается в определении является ли определенный фрагмент (пиксель) в тени
другого фрагмента. Проверить мы это можем при рендере сцены, используя
дополнительную матрицу источника освещения.
С помощью матрицы источника освещения мы переводим координаты
вершины объекта из мировой системы координат, сначала в пространство источника
освещения, а после в текстурные координаты карты глубины. Получить эту матрицу,
используя камеру источника освещения, мы можем следующим образом:
void CameraSetupLightMatrix (GLuint program,
const Camera &camera)
{
// матрица сдвига текстурных координатconst mat4
bias (
.5f, 0.0f, 0.0f, 0.5f,
.0f, 0.5f, 0.0f, 0.5f,
.0f, 0.0f, 0.5f, 0.5f,
0.0f, 0.0f, 0.0f, 1.0f
);
// расчитаем необходимые матрицы
mat4 view = GLFromEuler (camera.rotation) *
GLTranslation (-camera.position);viewProjection = bias * camera.projection *
view;
// передадим матрицу источника освещения в шейдерную
программу
glUniformMatrix4fv (glGetUniformLocation(program,
«transform.light»), 1, GL_TRUE, viewProjection.m);
}
Комментарий по поводу матрицы bias. Сначала мы получаем
видовую матрицу источника освещения view, она переводит координаты вершины из
мирового пространства координат в пространство координат источника освещения.
Затем, используя проекционную матрицу, мы переводим координаты в однородные.
Однако, известно что однородные координаты лежат в диапазоне [-1, 1], а нам
необходимо получить текстурные координаты, которые лежат в диапазоне [0, 1],
именно для этого используется матрица bias. Трансформация этой матрицы
равносильна операции a * 0.5 + 0.5 для каждого элемента трансформируемого
вектора.
В результате, используя матрицу источника освещения, мы можем
перевести координаты вершины из мирового пространства в текстурные координаты
карты глубины в вершинном шейдере:
layout (location = VERT_POSITION) in vec3
position;(location = VERT_TEXCOORD) in vec2 texcoord;(location = VERT_NORMAL)
in vec3 normal;
// параметры преобразованийstruct Transform
{model;viewProjection;light;normal;viewPosition;
} transform;
// параметры точеченого источника освещения
uniform struct Light
{ambient;diffuse;specular;4 position;
} light;
// параметры для фрагментного шейдера
out Vertex
{texcoord;smcoord;normal;lightDir;viewDir;
} Vert;
void main(void)
{
// переведем координаты вершины в мировую систему координат
vec4 vertex = transform.model * vec4 (position,
1.0);
// передадим в фрагментный шейдер некоторые параметры
// вычисляем текстурные координаты вершины на карте глубины
Vert.smcoord = transform.light * vertex;
// передаем текстурные координаты.texcoord = texcoord;
// передаем нормаль в мировой системе координат
Vert.normal = transform.normal * normal;
// передаем направление на источник освещения
Vert.lightDir = vec3 (light.position);
// передаем направление от вершины к наблюдателю в мировой
системе координат
Vert.viewDir = transform.viewPosition - vec3
(vertex);
// переводим координаты вершины в однородные_Position =
transform.viewProjection * vertex;
}
Используя полученные координаты и теневую карту мы можем
найти глубину фрагмента относительно камеры источника освещения. Обладая
информацией о глубине фрагмента относительно камеры источника освещения и
относительно камеры наблюдателя мы можем сравнить эти два значения и узнать, находится
ли этот фрагмент в тени другого в пространстве источника освещения.3.30
обладает двумя возможностями, которые облегчают нам получение требуемой
информации о фрагментах:
Самплер sampler2DShadow
Функция textureProj
Использование специального текстурного самплера
sampler2DShadow позволяет изменить логику работы некоторых функций для работы с
текстурой, а использование функции textureProj позволяет получить значение
текселя текстуры с коррекцией текстурных координат. При передаче в функцию
textureProj в качестве текстурных координат 3х компонентного вектора для
получения текселя она использует первые два компонента деленные на третий. Это
позволит нам получить корректное значение карты глубины с учетом глубины
фрагмента относительно камеры источника освещения.
При создании текстуры для хранения значений глубины мы
использовали специальный параметр:
glTexParameteri
(GL_TEXTURE_2D,_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
Использование этого параметра позволяет производить
автоматический тест на затенение (shadow test), это происходит когда мы
вызываем функцию textureProj. В случае если глубина фрагмента с координатами
smccord больше чем в текстуре глубины depthTexture функция textureProj вернет
1.0, иначе она вернет 0.0. Итоговый фрагментый шейдер:
// текстурный самплер карты глубиныsampler2DShadow
depthTexture;
// параметры точеченого источника освещенияstruct Light
{ambient;diffuse;specular;position;
} light;
// параметры материалаstruct Material
{D texture;ambient;diffuse;specular;emission;shininess;
} material;
// параметры полученные из вершинного шейдера
in Vertex
{texcoord;smcoord;normal;lightDir;viewDir;
} Vert;
(location = FRAG_OUTPUT0) out vec4 color;
void main(void)
{
// нормализуем полученные данные для коррекции интерполяции
vec3 normal = normalize (Vert.normal);lightDir =
normalize (Vert.lightDir);viewDir = normalize (Vert.viewDir);
// коэффициент затененияshadow = textureProj (depthTexture,
Vert.smcoord);
// добавим собственное свечение материала= material.emission;
// добавим фоновое освещение+= material.ambient *
light.ambient;
// добавим рассеянный светNdotL = max (dot(normal, lightDir),
0.0);
color += material.diffuse * light.diffuse *
NdotL;
// добавим отраженный светRdotVpow = max (pow(dot (reflect(-lightDir, normal), viewDir),
material.shininess), 0.0);+= material.specular * light.specular * RdotVpow;
// вычислим итоговый цвет пикселя на экране с учетом текстуры
color *= texture (material.texture,
Vert.texcoord) * shadow;
}
Для сглаживания краев тени в используется техника Percentage
Closer Filtering (PCF). Данная техника заключается в том, что производится
несколько тестов на затенение в окрестностях искомого фрагмента и для затенения
используется среднее значение этих тестов, таким образом, граница тени будет
более «мягкой».
Относительно описанного выше фрагментного шейдера эту технику
можно использовать так:
// сглаживание границы тени, используем PCF с выборкой 3x3
float PCF (in vec4 smcoord)
{res = 0.0;+= textureProjOffset (depthTexture,
smcoord, ivec2 (-1, - 1));+= textureProjOffset (depthTexture, smcoord, ivec2
(0, - 1));+= textureProjOffset (depthTexture, smcoord, ivec2 (1, - 1));+=
textureProjOffset (depthTexture, smcoord, ivec2 (-1, 0));+= textureProjOffset
(depthTexture, smcoord, ivec2 (0, 0));+= textureProjOffset (depthTexture,
smcoord, ivec2 (1, 0));+= textureProjOffset (depthTexture, smcoord, ivec2 (-1,
1));+= textureProjOffset (depthTexture, smcoord, ivec2 (0, 1));+=
textureProjOffset (depthTexture, smcoord, ivec2 (1, 1));
(res / 9.0);
}
// коэффициент затененияshadow = PCF (Vert.smcoord);
3.3 Пересчет кадра 3d-приложения
В связи с тем, что мы используем не статический, а
динамический источник света а также динамическую камеру наблюдения и объекты,
необходимо заново рассчитывать основные параметры для камеры, источника света и
объектов. Алгоритм пересчета всех этих параметров представлен на рисунке 3.5.
Блок 1 и 2 отвечают за изменение параметров объектов и их реализация выглядит:
// зададим углы поворота куба с учетом
времени((torusRotation[0] += 30.0f * (float) deltaTime) > 360.0f)[0] -=
360.0f;((torusRotation[1] += 15.0f * (float) deltaTime) > 360.0f)[1] -=
360.0f;
((torusRotation[2] += 7.0f * (float) deltaTime) >
360.0f)[2] -= 360.0f;
// зададим матрицу вращения куба[1].rotation = GLFromEuler
(torusRotation[0],[1],[2]);[2].rotation =GLFromEuler (-torusRotation[0],[1],
torusRotation[2]);
Рисунок 3.5. Алгоритм пересчета кадра 3D-приложения
Блок 3 и 4 отвечают за изменение параметров наблюдателя и их
реализация выглядит:
// вращаем камеру(mainCamera, (float) deltaTime *
rotateDelta[1], (float) deltaTime * rotateDelta[0], 0.0f);
// двигаем камеру(mainCamera, (float) deltaTime *
moveDelta[0]*5, 0.0f, (float) deltaTime * moveDelta[1]*5);
[0] = rotateDelta[1] = 0;[0] = moveDelta[1] = 0;
Блок 5 и 6 отвечают за изменение источника света и их
реализация выглядит:
// движение источника света=
false;(directionalLight.position[0] < -50)
(directionalLight.position[0] > 50)= true;
(decLightPos).position += vec3 (-deltaTime*2, 0, 0);.position
+= vec3 (deltaTime*2, 0, 0);
(lightCamera, directionalLight.position, vec3 (0,0,0),
vec3_y);[4].position = directionalLight.position;[4].position += vec3 (2,2,2);
4.
Тестирование реализации 3d приложения
Тестирование реализации 3D приложения будем
производить на разных настройках карт теней. Изменять будем проекционную
матрицу. Как известно из предыдущих разделов проекционная матрица задается
функцией OrthoProjection (float left, float right, float bottom, float top, float zNear, float zFar).
Будем пропорционально увеличивать left, right, bottom, top для тестов 1-3, а для
тестов 4 и 5 ZNear соотвествестно.
Тест 1
Значение параметров
left = -10.0f, right = 10.0f,
bottom = -10.0f, top = 10.0f,= 0.0f, zFar = 100.0
Рисунок 4.1 Результат теста 1
Тест 2
Значение параметров
left = -50.0f, right = 50.0f,
bottom = -50.0f, top = 50.0f,
zNear = 0.0f, zFar = 100.0
Рисунок 4.2 Результат теста 2
Тест 3
Значение параметров
left = -100.0f, right = 100.0f,
bottom = -100.0f, top = 100.0f,
zNear = 0.0f, zFar = 100.0
Рисунок 4.3 Результат теста 3
Тест 4
Значение параметров
left = -10.0f, right = 10.0f,
bottom = -10.0f, top = 10.0f,
zNear = 20.0f, zFar = 100.0
Результат теста 4 при параметрах -10.0f, 10.0f, -10.0f,
10.0f, 20.0f, 100.0f
Рисунок 4.4 Результат теста 4
Тест 5
Значение параметров
left = -10.0f, right = 10.0f,
bottom = -10.0f, top = 10.0f,
zNear = 60.0f, zFar = 100.0
Результат теста 5 при параметрах -10.0f, 10.0f, -10.0f,
10.0f, 60.0f, 100.0f
Рисунок 4.5 Результат теста 5
Исходя из тестов можно сделать следующие выводы:
1. При увеличении параметры left, right, bottom, top происходит уменьше-ние
доли занимаемой сцены в карте теней.
2. Уменьшение доли занимаемой сцены в карте теней ведет
к ухудшению качества тени
. Увеличение параметра zNear при неизменном zFar и left, right, bottom, top ведет к увеличению
четкости карты теней и следовательно качеству теней в итоговом изображении.
5.
Технико-экономическое обоснование
5.1 Концепция экономического обоснования
Целью технико-экономического обоснования дипломной работы
является разработка плана организации исследований выполняемых работ, обобщение
организационно-экономических показателей и получение оценок эффективности
проекта. Индустрия компьютерных игр, графические редакторы для дизайнеров и
специалистов в области мультимедиа, навигационные программы и визуализация
ландшафта местности, применяемая для разведки и освоения полезных ископаемых -
все эти области требуют всё больших затрат оперативной памяти и ресурсов
процессора для всё более качественных эффектов и детальной прорисовки моделируемых
объектов в режиме реального времени. В свою очередь, рынок и научно-технический
прогресс не стоит на месте, предлагая всё новые технологии и эффекты. В данном
случае речь пойдёт о динамичес-ком освещении, ему и посвящена данная работа.
Для технико-экономического обоснования НИР выделены
сле-дующие этапы:
определение трудоемкости проводимых в ходе дипломного
проектирования работ и составление календарного плана выпол-нения работ;
составление сметы затрат на проведение работ;
оценка эффективности дипломной работы.
В конце технико-экономического обоснования будут сделаны
выводы о научно-технических результатах данной дипломной Ра-боты.
5.2
Трудоемкость и календарный план выполнения работы
Все необходимые действия по выполнению данной НИР производились
в составе научного сотрудника и инженера-программиста на кафедре МОЭВМ.
5.3 Смета затрат на проведение работ
Калькуляция себестоимости разработки осуществляется по
следующим статьям:
материалы;
расходы на оплату труда;
отчисления на социальные нужды;
накладныерасходы;
прочие прямые расходы.
Затраты на израсходованные материалы приведены в таблице
5.3.1.
Таблица 5.3.1 Затраты на материалы
Материал
|
Количество, шт.
|
Стоимость
единицы, руб.
|
Стоимость, руб.
|
Ч/б картридж
для принтера
|
1
|
1800
|
1800
|
Бумага размера A4 для принтера, пачка
|
1
|
150
|
150
|
Комплектканцелярских
принадлежностей
|
1
|
-
|
60
|
USBflash-накопительемкостью на 2 Гб
|
1
|
1
|
299
|
Транспортные
расходы
|
7-10% от общих
затрат на материалы
|
-
|
231
|
ИТОГО:
|
2540
|
Основная и дополнительная заработные платы непосредст-венных
исполнителей проекта рассчитываются на основании трудо-емкости выполнения работ
научным сотрудником Тр и инженером-программистом Ти,
ставок научного сотрудника Др и инженера-программиста Ди
и величины процента дополнительной заработной платы (12%):
Тр = 13 чел.-дн.;
Ти = 52 чел.-дн.;
Др = 24000 руб./мес.;
Ди = 12000 руб./мес.
Основная заработная плата исполнителей Сзо
рассчитывается по формуле:
(1)
где число 22 - норматив рабочих дней в месяце.
Сзо = (13 Ч 24000 + 52Ч12000) = 42 545 руб.
Дополнительная заработная плата - заработная плата за
неотработанное время, как правило, это «отпускные». Дополнительная заработная
плата исполнителей Сдоп. рассчитывается по формуле:
(2)
где число 0,12 - ставка дополнительной заработной платы.
Сдоп. = 42 545 Ч 0,12 = 5 105 руб.
Величина расходов на оплату труда составляет 47650 руб.
Рассчитаем величину отчислений во внебюджетные фонды. Она
рассчитывается по формуле:
(3)
где Сзо - величина заработной платы; Hвф - суммарный процент отчислений во внебюджетные фонды
составляет 26,2%.
Свф=42 545* 26,2/100 = 11 147 руб.
К прочим прямым расходам отнесем плату за Internet, приведенную для рабочего места на основе использованного Internet-трафика, а также абонентскую плату за
телефон по данным кафедры, и сведем их к таблице 6.3.2.
Так как все работы по исследованию производились ни личном
компьютере, то нет необходимости считать амортизационные отчисления для
персональных компьютеров кафедры проведения исследовательских работ.
Таблица 6.3.2 Расходы, относящиеся к статье «Прочие прямые
расходы»
Наименование
|
Сумма, руб.
|
Плата за Internet
|
1100
|
Абонентская
плата за телефон
|
200
|
ИТОГО:
|
1300
|
К накладным расходам мы отнесем затраты на управление и
организацию выполнения работ.
Накладные расходы составляют 20% от оплаты труда и выплат во
внебюджетные фонды:
(4)
где Сзо - величина заработной платы; Свф -
величина отчислений во внебюджетные фонды.
Снр = (42 545+11 147) * 0,2 = 10 738 руб.
Рассчитаем общую себестоимость проекта, для чего все предыдущие
вычисления сведем в одну таблицу 5.3.3.
Таблица 5.3.3 Смета затрат на проведение НИР
Наименование
статьи расходов
|
Сумма, руб.
|
Материалы
|
2 540
|
Расходы на
оплату труда
|
47650
|
Внебюджетные
фонды
|
11 147
|
Прочие прямые
расходы
|
1 300
|
Накладные
расходы
|
10 738
|
Итого:
|
73375
|
5.4 Комплексная оценка эффективности
внедрения программы
Разработанный
программный продукт можно использовать в качестве обучающего материала на
кафедре МОЭВМ в течении года, что принесет экономию средств в размере 32000 р.
Вышеуказанная
сумма получилась после того, как было взято общее количество занятий в год и
подсчитаны расходы на материалы (на бумагу и другие канцтовары).
Коэффициент
эффективности (32000/73375= 0.415) или 43.6%. Таким образом, средства будут окуплены
примерно через два года, или более точно (100/43.6=2. года).
Заключение
Разработана и реализована архитектура библиотеки классов,
способная отрисовывать любые трехмерные сцены с использованием основных
алгоритмов обработки. В библиотеке реализованы следующие алгоритмы 3D-графики: освещение
объекта (равномерное, диффузное, бликовое), текстурирование, Shadow Mapping, вывод в квадрат любой
текстуры, создание и управление навигацией камеры, загрузка и визуализация
сложных 3D
моделей, настройка материалов, загрузка, выгрузка и передача данных в шейдеры.
Создано демонстрационное приложение с использованием этой библиотеки. Кроме
того, данный набор библиотек может служить основой для разработки коммерческой
системы моделирования, а само приложение может быть использовано в качестве
учебного материала по дисциплине компьютерная графика.
Список использованных источников
1.
Горнаков
С.Г. DirectX 9: «Уроки программирования на С++». - СПб.: БХВ-Петербург, 2005.
- 400 с.
2.
Программирование
игр на платформе XNA [Электронный ресурс]. - Режим доступа: http://www.xnadev.ru свободный.
3.
Luna, Frank D. Introduction to 3D game programming with DirectX
9.0. - Wordware Publishing, Inc, 2003. - 421 p.
4.
ixbt.com [Электронный ресурс]. - Режим доступа: http://www.ixbt.com
свободный.
5.
Blinn, James F. Simulation of Wrinkled Surfaces // Computer
Graphics, Vol. 12 (3), pp. 286-292, SIGGRAPH-ACM (August 1978).
6.
Dempski, Kelly and Viale, Emmanuel, Advanced Lighting and
Materials with Shaders // Wordware Publishing Inc., 2005, 361 p.
7.
Программирование
игр [Электронный ресурс]. - Режим доступа: http://www.gamedev.ru свободный.
8.
Nitschke B. Professional XNA Game Programming: For Xbox 360 and
Windows - Wrox Press, 2007. - 504 p.
9.
Krishnamurthy and Levoy, Fitting Smooth Surfaces to Dense Polygon
Meshes // SIG-GRAPH 1996.
10. Guardado, Juan, NVIDIA,
GPU Gems, 2004 by NVIDIA Corporation.
11. Pharr, Matt and Fernando,
Randima, NVIDIA, GPU Gems 2: Programming Techniques for High-Performance
Graphics and General-Purpose Computation, 2005, by Addison-Wesley Professional,
880 p.
12. Cook, Robert L., Shade
trees // Proceedings of the 11th annual conference on Computer graphics and
interactive techniques, p. 223-231, January 1984, SIGGRAPH-ACM.
13. Phong, Bui-Tuong, Illumination
for computer generated images // Comm. ACM 18, 6 (June 1975) 311-317.
14. Blinn, James F., Models
of Light Reflection for Computer Synthesized Pictures // Computer Graphics,
Vol. 11, No. 2, July, 1977, 192-198.
15. Krishnamurthy and Levoy,
Fitting Smooth Surfaces to Dense Polygon Meshes // SIG-GRAPH 1996
16. Cohen et al.,
Appearance-Preserving Simplification // SIGGRAPH 1998
17. Cignoni et al., A general
method for recovering attribute values on simplifed meshes // IEEE
Visualization 1998
18. Oliveira, Manuel M.;
Bishop, Gary; McAllister, David, Relief texture mapping // International
Conference on Computer Graphics and Interactive Techniques archive, proceedings
of the 27th annual conference on Computer graphics and interactive techniques,
Pages: 359 - 368, 2000.
19. Kaneko, T., et al.,
Detailed Shape Representation with Parallax Mapping // In Proceedings of ICAT
2001, pp. 205-208, 2001.
20. Crow, F., Shadow
algorithms for computer graphics, // SIGGRAPH, vol. 11, 242-248, 1977.
21. Roth, Scott D., Ray
Casting for Modeling Solids // Computer Graphics and Image Processing 18:
109-144, doi:10.1016/0146-664X(82) 90169, February 1982.
22. Jensen, Realistic Image
Synthesis Using Photon Mapping // AK Peters, July 2001.
23. Williams, Lance; Casting
curved shadows on curved surfaces // SIGGRAPH-ACM, Volume 12, Issue 3 (August
1978), pp: 270 - 274., 1978.
24. Spencer, Greg; Shirley
Peter; Zimmerman, Kurt; Greenberg, Donald P.; Physically-based glare effects
for digital images // SIGGRAPH: 325. doi:10.1145/218380.218466., 1995.
25. Debevec, Paul E. and
Malik Jitendra, Recovering High Dynamic Range Radiance Maps from Photographs //
SIGGRAPH, 1997.