close

Вход

Забыли?

вход по аккаунту

?

makarenkoindd

код для вставкиСкачать
Министерство образования и науки российской федерации
Государственное образовательное учреждение
высшего профессионального образования
Санкт-Петербургский государственный университет
аэрокосмического приборостроения
В. Н. Макаренко
МАТЕМАТИЧЕСКИЕ МЕТОДЫ И
АЛГОРИТМЫ КОМПЬЮТЕРНОЙ ГРАФИКИ
Учебное пособие
Санкт-Петербург
2010
УДК 004.92
ББК 32.973.26
М15
Рецензенты:
доктор физико-математических наук, профессор Санкт-Петербургского
государственного политехнического университета А. А. Липовский;
кандидат технических наук, старший научный сотрудник
Центрального научно-исследовательского института
робототехники и технической кибернетики В. П. Макарычев
Утверждено
редакционно-издательским советом университета
в качестве учебного пособия
Макаренко В. Н.
М15 Математические методы и алгоритмы компьютерной графики: учеб. пособие / В. Н. Макаренко. – СПб.: ГУАП, 2010.
– 186 с.
ISBN 978-5-8088-0533-0
В учебном пособии изложена концепция графического конвейера, представляющего собой логически связанную последовательность вычислений, которые синтезируют на выходе графической
системы образ пространственной сцены. Разделы пособия посвящены методам, чаще других используемых для реализации каждого из
этапов графического конвейера. В пособии представлены популярные формализмы геометрического моделирования; основные алгоритмы модельных преобразований и алгоритмы удаления невидимых линий и поверхностей; наиболее часто используемые на практике модели освещенности и алгоритмы построения теней; методы
текстурирования, закраски и алгоритмы сглаживания.
Пособие предназначено для студентов и аспирантов технических
вузов, изучающих компьютерную графику и занимающихся разработкой новых алгоритмов и прикладных графических программ.
УДК 004.92
ББК 32.973.26
ISBN 978-5-8088-0533-0
© Санкт-Петербургский государственный
университет аэрокосмического
приборостроения (ГУАП), 2010
© В. Н. Макаренко, 2010
Введение
Практически все современные системы трехмерной графики используют концепцию так называемого графического конвейера
(Graphic Pipeline), представляющего собой логически связанную последовательность (или группу) вычислений, которые синтезируют на
выходе системы образ пространственной сцены. Конвейер разделен
на ряд этапов, на каждом из которых аппаратно или программно выполняется некоторая функция. Реализация конвейера может быть
полностью программной, полностью аппаратной или смешанной
(программно-аппаратной). Обычно в структуре графического конвейера выделяют ряд последовательных этапов обработки исходной
пространственной сцены. В частности, в данном случае будем придерживаться достаточно традиционной структуры (см., например
[5]). Пример конвейера, разделенного на два стадии: геометрические
преобразования и рендеринг приведен на рис. 1.
Указанные стадии процесса создания изображений на экране
монитора связаны между собой достаточно прочно, и ни одна из
них в отдельности не может привести к созданию достаточно реалистичных графических объектов.
Разделы пособия будут посвящены методам, чаще других используемым для реализации каждого из представленных на рис. 1
этапов.
Здесь же, во введении кратко рассмотрим каждую из стадий графического конвейера с тем, чтобы понять, о чем собственно пойдет
разговор.
Геометрические преобразования
Первый этап (моделирование) состоит в аппроксимации трехмерных объектов пространственной сцены, которые в общем случае представляют собой криволинейные поверхности множеством
многоугольников (полигонов). Отсюда термин – «полигональная
аппроксимация поверхности». Чаще всего в качестве таких полигонов используются треугольники (как самые простые полигоны).
Следует учитывать, что, чем мельче полигоны, тем ближе аппроксимация к модели, но и тем более громоздким становится описание
объекта, а, следовательно, и больше времени требуется на его обработку. Представление криволинейной поверхности совокупностью
плоских граней-полигонов c точностью, достаточной для имита3
ции гладкой поверхности, называется тесселяцией (tesselation), а
в случае, когда в качестве таких полигонов выступают простейшие
многоугольники – треугольники, применяется термин триангуляция (triangulation). Множество таких полигонов (сотни, а иногда
и тысячи) соединяются друг с другом и образуют сложные трехмерные сетки. В качестве достойной альтернативы полигональной
аппроксимации в последнее время в графических конвейерах все
чаще выступают методы моделирования гладких поверхностей, использующие для этой цели кривые (поверхности) Безье или сплайны. Причем вычислительные мощности современных компьютеров
возросли настолько, что позволяют отображать такие поверхности
даже в текстурированном виде практически в реальном времени.
Криволинейные поверхности, построенные на основе таких методов, для человеческого глаза кажутся идеально плавными и гладкими, в отличие от традиционных полигональных сеток, которым
все труднее соперничать с реальностью вследствие того, что реализованные с помощью полигональных моделей изображения выглядят угловатыми и недостаточно правдоподобными. В настоящее
время модели, использующие кривые Безье и сплайны, составляют
лишь небольшую долю от общего числа представленных на рынке
графических пакетов и акселераторов. Но, вероятно, их количество
будет расти, особенно после того, как в таком популярном у пользователей графическом пакете, как 3D Studio MAX, начали использовать NURBS-инструментарий (NURBS – Non-Uniform Rational
B-Splines – неоднородные рациональные В-сплайны). Совершенно
понятно, что и конкуренты 3D Studio MAX не заставят себя ждать,
и, таким образом, можно ожидать предложений подобного инструментария в других графических пакетах, ориентированных на сегмент рынка для массового пользователя.
На втором этапе выполняются элементарные геометрические
преобразования (Geometry Transformation) трехмерных объектов – операции сдвига, поворота, масштабирования и проецирования. Процедуры проецирования при этом являются, как правило,
составными частями методов удаления невидимых поверхностей
(Hidden Surface Removal), т. е. тех участков трехмерных объектов,
которые закрыты другими телами пространственной сцены или
собственным телом. Использование этих методов на раннем этапе
графического конвейера позволяет существенно сократить объем
информации, которая обрабатывается на последующих этапах, поскольку невидимые поверхности исключаются из рассмотрения.
4
Следует отметить, что удаление невидимых поверхностей на
этом этапе графического конвейера допустимо, если сцена состоит
только из непрозрачных объектов. Если же это не так, то сначала
необходимо выбрать модель освещенности, с учетом которой формируется эффект освещения объектов (третий этап стадии геометрических преобразований – Lighting). Здесь необходимо учитывать оптические свойства объектов. Если сцена состоит только из
непрозрачных объектов, то объекты, перекрытые ими от взгляда
наблюдателя, будут просто невидимыми. Сложнее дело обстоит с
прозрачными и полупрозрачными (просвечиваемыми) объектами.
Прозрачность (transparency) объекта позволяет видеть и объекты,
расположенные за ним, а просвечиваемость (translucency) позволяет проходить через него лучам света от источников. Кроме того,
поверхность имеет некоторый цвет, а также характеризуется степенью отражения (она может быть глянцевой или матовой). Для
того чтобы получить реалистичное изображение пространственной
сцены, приходится отслеживать прохождение лучей от установленных источников освещения, достигающих глаза наблюдателя
как при отражении от поверхностей, так и при преломлении при
прохождении через прозрачные и просвечиваемые объекты. При
этом должны учитываться эффекты перспективы, как оптической
(искажение формы), так и атмосферной (имитация дымки или тумана).
Следует помнить, что стадия геометрических преобразований
требует выполнения большого объема вычислительных операций,
включая операции с плавающей точкой.
Стадия рендеринга
Render в переводе с английского означает “визуализировать, формировать изображение″. Таким образом, рендеринг (rendering) – это
процесс создания растрового изображения трехмерных объектов.
На стадии рендеринга по описанию треугольников, аппроксимирующих трехмерные объекты, генерируются пиксели изображения.
В отличие от стадии геометрических преобразований в процессе
рендеринга объем операций с плавающей точкой не столь велик и
в основном состоит из простых операций над пикселями. Стадия
рендеринга также состоит из четырех этапов, описанию которых
посвящена вторая часть пособия. Здесь коротко перечислим основные характеристики каждого из этапов стадии рендеринга.
5
На первом этапе рендеринга (смешение текстур) выполняется
обработка так называемого альфа-буфера и собственно смешение
текстур. Эта процедура заключается в смешении атрибутов двух
пикселей в сцене для получения одного составляющего пикселя.
Второй этап на стадии рендеринга (наложение текстуры) придает поверхностям предметов, изображаемых на экране, свойства
реалистичных покрытий, увеличивая тем самым визуальное качество изображаемой сцены в целом.
На третьем этапе рендеринга реализуется один из методов закраски треугольников, аппроксимирующих объекты в трехмерном
пространстве. Для выполнения этой задачи чаще всего используется одна из трех основных моделей: плоское закрашивание, закрашивание по Гуро или закрашивание по Фонгу. В первом случае
освещенность для каждого полигона (треугольника) есть величина
постоянная. Для того чтобы несколько улучшить визуальное качество изображения (с тем, чтобы соседние полигоны не так резко
отличались друг от друга по цвету), цвет каждого из них рассчитывается как усредненное значение цветов прилегающих к полигону соседей. В случае закрашивания по Гуро пользуются методом
интерполяции освещенности по полигону, т. е., прежде всего, рассчитывается освещенность в вершинах треугольника, а затем с помощью процедуры линейной интерполяции получают цвет каждой
точки полигона. При закрашивании по Фонгу интерполируется
уже не освещенность, а вектор нормали к поверхности, и только после этого вычисляется освещенность каждой точки полигона, что
улучшает визуальное восприятие изображения, но требует гораздо
больше вычислительных ресурсов.
На заключительном этапе рендеринга применяется один из алгоритмов сглаживания (аnti-aliasing) для устранения так называемого «лестничного» эффекта на границе изображаемых объектов.
Эти алгоритмы позволяют сгладить ступенчатость прямых линий,
которая неизбежна в силу природы экранов современных мониторов.
Конкретная реализация графического конвейера в коммерческих графических пакетах может значительно изменяться как по
используемой терминологии, так и по последовательности этапов,
заложенных в конвейер.
6
1. Стадия геометрических преобразований
1.1. Моделирование
По мере развития трехмерной компьютерной графики проблема
моделирования приобретает все более определяющее значение, поскольку влияние данного этапа графического конвейера на качество результирующего изображения весьма велико. При генерации
реалистических трехмерных изображений необходимо передать,
по возможности, все присущие моделируемому объекту свойства:
местоположение в пространстве, объем, текстуру; учитывая при
этом освещенность объекта (прорисовка тени, передача полутонов,
бликов) и т. п. Причем, чем выше требования к степени реалистичности изображения, тем сложнее решаемая задача с точки зрения
количества производимых вычислений. В связи со сложностью генерации реалистических трехмерных изображений, на практике
итоговое изображение формируется из фрагментов объекта, для
чего используются специальные алгоритмы его декомпозиции на
составные части.
В этой части пособия рассмотрим основные подходы, которые
применяются для выполнения этапа моделирования в подавляющем числе графических пакетов и акселераторов.
В первую очередь рассмотрим подход, заложенный в основу моделирования на заре развития 3D-графики. Это, так называемое,
полигональное моделирование. Процесс разбиения поверхности
объектов на полигоны выполняется с помощью так называемых алгоритмов тесселяции.
Полигональная модель – основа любого 3D-пакета, своеобразный
остов объекта, который впоследствии «обрастет» поверхностной
текстурой, и приобретет достоверный, близкий к реальному миру
вид. Такие модели разработаны еще в 60-х годах прошлого века для
систем автоматизированного проектирования и состоят из полигональных сеток. Количество многоугольников в полигональных
сетках определяется числом деталей объекта и необходимым качеством результирующего изображения. Чем больше детализируется
модель, тем большее количество многоугольников она содержит.
Однако необходимо учитывать, что, чем больше многоугольников
содержит модель, тем большие вычислительные мощности требуются для обработки такой модели.
7
Относительно новая область 3D-моделирования – NURBSмодели (Non-Uniform Rational B-Splines – неоднородные рациональные В-сплайны). Криволинейные поверхности, «склеенные»
из таких сплайнов, получаются плавными и гладкими (по крайней
мере, для человеческого глаза), в отличие от традиционных полигональных сеток. Сегодня подобные модели составляют относительно
небольшую часть общего числа графических систем, но, очевидно,
с ростом вычислительной эффективности алгоритмов, обрабатывающих такие модели, и мощностей персональных компьютеров их
число будет возрастать.
И, наконец, в последнее время в машинной графике на стадии моделирования стали использоваться методы фрактальной геометрии.
Фракталы применимы там, где требуется с помощью нескольких
коэффициентов задать линии и поверхности очень сложной формы.
С точки зрения машинной графики фрактальная геометрия незаменима при генерации искусственных облаков, гор, поверхности моря.
Фактически найден способ легкого представления сложных неевклидовых объектов, образы которых весьма похожи на природные.
1.1.1. Тесселяция
Итак, как уже отмечалось, первым этапом графического конвейера является процесс аппроксимации трехмерных объектов
пространственной сцены множеством плоских, чаще всего – треугольных граней (полигонов). Таким образом, тесселяция (или триангуляция, если полигоны представляют из себя треугольники) –
разделение сложного примитива на ряд простых.
Задача описания трехмерных объектов вообще достаточна сложна. Простейший способ описания, используемый в настоящее время в большинстве реализаций графического конвейера – это моделирование данных объектов из полигонов с помощью специальных
программ. Такие программы моделирования, как 3DStudio, Maya,
SoftImage, Mirai и другие, на выходе создают представление трехмерного объекта в виде совокупности полигонов самого простого
вида – треугольников. Таким образом, поверхность трехмерного
объекта покрывается сеткой, вычисляется необходимое количество
промежуточных точек и на основе этих точек поверхность трехмерного объекта представляется в виде набора покрывающих данный
объект треугольников.
8
Разбиение исходного объекта на треугольники имеет существенные преимущества, поскольку, во-первых, треугольник – выпуклый многоугольник самого простого вида, три вершины которого
однозначно определяют плоскость, а, соответственно, и грань; вовторых, любую поверхность можно всегда точно разбить на треугольники; в-третьих, вычислительная сложность алгоритмов разбиения поверхности на треугольники существенно меньше, чем
при разбиении ее на другие полигоны; и, наконец, в-четвертых,
реализация процедур рендеринга для области, ограниченной треугольником, выполняется наиболее просто.
Совершенно очевидно, что на результат данного процесса существенно влияет количество промежуточных точек (шаг сетки), а
также их расположение на исходном трехмерном объекте (равномерная или неравномерная сетка). При этом важно достаточно точно аппроксимировать внешний контур объекта. При небольшом
шаге сетки результирующее множество треугольников может быть
чрезмерно большим для дальнейшей их обработки последующими алгоритмами графического конвейера, что может привести к
значительному увеличению времени генерации изображения на
экране. С другой стороны, при большом шаге сетки, могут исчезать важные детали изображения. Однако следует отметить, что
даже достаточно грубая сетка полезна на практике, так как методы
сглаживания, применяемые в процессе отображения, могут значительно улучшить представление о кривизне поверхности. При
изображении сложных трехмерных объектов (например, рельефа
земной поверхности) чаще всего используется неравномерно расположенный набор точек (неравномерная сетка). При этом в некоторых местах трехмерного объекта сеть точек может быть гуще
(существенное изменение рельефа, например, горный массив), в
других (незначительное изменение рельефа, скажем, равнинный
ландшафт) – реже.
Любое множество точек, за исключением тривиальных случаев,
допускает несколько способов триангуляции. Методы триангуляции различаются по виду исходных данных: алгоритмы триангуляции многоугольников и триангуляция области на основе заданного
набора точек. Довольно часто используются алгоритмы, осуществляющие так называемую триангуляцию Делоне (в силу некоторых весьма полезных свойств триангуляции данного вида).
Алгоритмы триангуляции являются неотъемлемой частью
практически всех профессиональных графических пакетов 3D9
моделирования (в частности: 3D Studio MAX, OpenGL Optimizer,
LightWave и др.), постоянно ведутся работы по их усовершенствованию. Часть алгоритмов реализована аппаратно в графических
акселераторах.
Триангуляция многоугольника
Пусть имеется произвольный (не обязательно выпуклый) многоугольник, заданный набором координат своих вершин P0(x0, y0),
P1 (x1, y1), ..., Pn(xn, yn,), и пусть вершины многоугольника пронумерованы по часовой стрелке. Необходимо разбить заданный полигон на непересекающиеся треугольники, полностью покрывающие
площадь исходного многоугольника.
В том случае, если многоугольник выпуклый, т. е. такой, что
через каждое его ребро можно провести прямую так, чтобы все
вершины многоугольника лежали по одну сторону от этой прямой
(включая саму эту прямую), то задача разбиения данного полигона на треугольники тривиальна. Действительно, соединив первую
вершину прямыми со всеми несмежными с ней вершинами, мы получим искомое множество треугольников, ограниченных сторонами многоугольника и построенными хордами (рис. 1.1).
Если многоугольник не является выпуклым, задача несколько усложняется. Существует ряд алгоритмов, решающих задачу
триангуляции для данного случая. Один из наиболее очевидных
алгоритмов состоит в предварительной разбивке невыпуклых многоугольников на выпуклые с последующей тривиальной триангуляцией полученных выпуклых многоугольников. Проще всего это
можно сделать последовательным
переносом и поворотом многоуголь1
7
ника так, чтобы одна из его вершин
2
совпадала с началом координат, а
исходящая из нее сторона – с осью
ОХ. При расположении какой-либо
6
части многоугольника ниже оси аб3
сцисс, происходит ее отсечение, и
алгоритм рекурсивно повторяют для
полученных полигонов, пока они не
станут выпуклыми. Процесс разбие5
4
ния исходного невыпуклого многоугольника (левый верхний угол риРис. 1.1
10
сунка) на множество выпуклых многоугольников (правый нижний
угол) схематически показан на рис. 1.2.
В качестве еще одного алгоритма триангуляции невыпуклых
многоугольников рассмотрим алгоритм, выложенный на http://
alglib.sources.ru/geometry/triangulatepolygon.php.
В указанном алгоритме авторы предлагают следующий порядок разбиения исходного многоугольника на множество треугольников. На каждом шаге алгоритма от многоугольника отсекается
один треугольник Pi–1 Pi Pi+1, а вершина Pi исключается из дальнейшего рассмотрения. Для того чтобы определить, можно ли использовать диагональ Pi–1 Pi+1 для отсечения треугольника, вначале проверяется знак синуса угла Pi–1 Pi Pi+1, учитывая при этом
последовательность обхода вершин. Например, для многоугольника (рис. 1.3) при i = 0, 1, 2, 4, 5 синус соответствующих углов будет
отрицателен, а при i = 3 – положителен.
Найдя номер вершины i, для которой синус соответствующего угла отрицателен, проверяется, не входят ли в треугольник
Pi–1 Pi Pi+1 какие-либо точки из текущего многоугольника (естественно кроме самих вершин треугольника Pi–1 Pi Pi+1). Если таких
вершин нет – треугольник отсекается от многоугольника, иначе –
выполняется поиск следующей вершины с отрицательным синусом
угла и для нее выполняется аналогичная проверка. На рис. 1.3 показан процесс последовательного отсечения треугольников от исходного невыпуклого многоугольника.
Для проверки принадлежности точки треугольнику, заданному
своими вершинами, рекомендуется использовать один из тестов
принадлежности, информацию о которых можно найти далее.
И, наконец, в заключение данного раздела, приведем еще один
универсальный алгоритм триангуляции произвольного многоугольника (рис. 1.4).
В исходном многоугольнике выбирается крайняя левая вершина (обозначим эту вершину A – для нее координата xi минимальна
среди всех вершин многоугольника), и между двумя смежными ей
вершинами (обозначим их для определенности B и C) проводится
отрезок прямой. Если построенный отрезок BC – хорда (полностью
лежит внутри многоугольника) – полученный треугольник ABC
отсекается от многоугольника и алгоритм рекурсивно обрабатывает оставшийся полигон до тех пор, пока он не выродится в треугольник. В противном случае (построенный отрезок BC – не хорда)
внутрь треугольника ABC попадает одна или несколько вершин
11
многоугольника. Тогда среди всех вершин, попавших в треугольник ABC, выбирается наиболее удаленная от стороны AC (обозначим ее D), и она соединяется отрезками прямых с вершинами A и
C. Вновь полученный треугольник проверяется на наличие внутри
него других вершин многоугольника и так далее до тех пор, пока
внутри некоторого треугольника не будет других вершин многоугольника. Тогда полученный треугольник отсекается от многоугольника и алгоритм рекурсивно обрабатывает оставшийся полигон до тех пор, пока он не выродится в треугольник. На рис. 1.4
стрелками показана последовательность разбиения исходного
многоугольника на треугольники (красные треугольники последовательно отсекаются).
Триангуляция области, заданной набором точек
Кроме триангуляции многоугольника (полигона) в компьютерной графике часто рассматривается задача триангуляции набора
точек. Задание некоторой поверхности набором точек применяется
часто в тех случаях, когда поверхность имеет сложный не гладкий
рельеф, но детальное представление геометрических особенностей
ее важно с практической точки зрения. К поверхностям такого рода
можно отнести участки земной поверхности, формы небесных тел и
другие образования со сложной формой.
В приведенном далее алгоритме (источник – ресурс http://alglib.
sources.ru/geometry/triangulatearea.php), итоговая триангуляция
получается путем наращивания текущей триангуляции очередным
треугольником на каждом шаге алгоритма.
Итак, предположим, что некоторая область на плоскости задана
набором точек P1, …, Pk. Каждая точка задана своими координатами (Pi (xi, yi), i = 1, ..., k). Предлагаемый алгоритм осуществляет
разбиение области на треугольники таким образом, что область
полностью покрывается непересекающимися треугольниками с
вершинами в узловых точках и любой выпуклый четырехугольник
разбивается по кратчайшей диагонали.
Вначале работы алгоритм находит такие две точки P1 и P2, чтобы все остальные заданные точки лежали по одну сторону от прямой P1 P2 (наиболее просто в качестве точек Pi и Pj выбрать две точки из набора с наименьшими значениями координаты x). Вводится
фиктивная точка P0, лежащая по другую сторону от прямой P1 P2
(например, точку с координатой x<min(x1, x2) и координатой y = y1
12
или y = y2). Запоминаем упорядоченную тройку точек (P1, P2, P0)
в стек. Затем последовательно обрабатываем стек до тех пор, пока
он не станет пустым, с помощью следующей последовательности
шагов:
(1) – Извлекается из стека тройка P1, P2, P3. Выполняется поиск точки M, которая находится по противоположную сторону от
прямой P1 P2 относительно точки P3, причем такую, чтобы угол
P1 MP2 был максимальный. Если такой точки нет, то выполняется
переход на метку (3).
(2) – Если треугольник P1 MP2 не был построен в результате
предыдущих шагов, он запоминается, и в стек помещаются тройки
P1, M, P2 и P2, M, P1.
(3) – Если стек не пуст, выполняется переход на метку (2).
Следует обратить внимание на то, что в стек помещаются упорядоченные тройки точек.
На рис. 1.5 схематически показан процесс построения триангуляции для области, заданной набором точек.
Следует отметить, что поскольку процедура триангуляции является подготовительным этапом стадии рендеринга, к итоговому
множеству треугольников могут предъявляться определенные требования. Например, при многопроцессорной обработке целесообразно выполнять триангуляцию таким образом, чтобы площадь
составляющих многоугольник треугольников была примерно одинаковой. В этом случае будет обеспечена одинаковая степень вычислительной загрузки аппаратуры. В этой связи полезно познакомиться с так называемой триангуляцией Делоне. Триангуляция Делоне
Для определения триангуляции Делоне, необходимо ввести в
рассмотрение ряд понятий. Будем называть набор точек круговым, если существует некоторая окружность, на которой лежат
все точки набора (окружность будет описанной для данного набора
точек). Таким образом, для треугольника такая окружность проходит через все три его вершины. Далее, будем называть окружность
свободной от точек в отношении к заданному набору точек, если
внутри этой окружности нет ни одной точки из заданного набора.
Тогда триангуляция некоторого набора точек будет триангуляцией Делоне, если описанная окружность для каждого треугольника
свободна от точек в отношении к данному набору.
13
Для триангуляции Делоне добавление новой точки в набор осуществляется с использованием следующего алгоритма:
− для каждой новой точки находится треугольник, в который
она попала;
− новая точка соединяется с каждой из трех вершин найденного
треугольника;
− для каждого вновь образованного треугольника проверяется
круговой критерий (описанная окружность для треугольника свободна от точек) и, если необходимо, делается переброска ребер для
удовлетворения кругового критерия Делоне.
При удалении точки из первоначального набора рассматриваются все треугольники с вершинами в этой точке. Внешние ребра
этих треугольников образуют некоторый многоугольник. При этом
учитывается важное свойство кругового критерия – свойство симметричности. Это свойство состоит в том, что если некая точка D
лежит вне окружности, описанной вокруг точек A, B и C, то точка
А лежит вне окружности, описанной вокруг точек B, C и D. Таким
образом, триангуляции внутри и вне многоугольника независимы
(свойство локальной независимости). Это значит, что можно просто
удалить требуемую точку, а перестройка триангуляции сведется
только к триангуляции соседних с ней точек.
Из свойства локальной независимости следует еще одно важное
свойство – при склейке двух уже подвергнутых триангуляции наборов точек необходимо повторно выполнить триангуляцию только
для точек, которые принадлежат области пересечения двух первоначальных наборов точек.
Триангуляция Делоне обычно генерируется с использованием
либо инкрементных алгоритмов, либо с помощью алгоритмов типа
«разделяй и властвуй».
Инкрементные алгоритмы строят триангуляцию, начиная с любой внутренней точки или от границы области, и поочередно добавляют оставшиеся точки к текущей триангуляции (добавление новой точки производится в соответствии с описанным алгоритмом).
Алгоритмы «разделяй и властвуй» рекурсивно разбивают множество исходных точек на подмножества равного размера до элементарных примитивов (трех точек), а затем склеивают результирующую сеть попарно.
Приведем алгоритмы, относящиеся к каждому из перечисленных видов.
14
Инкрементный алгоритм генерации триангуляции Делоне
Итак, исходными данными является множество опорных точек,
заданных, например, на проекции трехмерного объекта.
Сначала введем ряд понятий, которые будут использоваться для
описания алгоритма. Ребром будем называть отрезок, соединяющий две опорные точки. Спящее ребро – ребро, еще не обработанное алгоритмом. Живое ребро – ребро, обработанное алгоритмом,
но идентифицирована только одна область, примыкающая к нему.
Мертвое ребро – ребро, обработанное алгоритмом, и идентифицированы обе примыкающие к нему области. Граница – множество живых ребер. Сопряженная точка – точка, находящаяся в неизвестной области живого ребра, обладающая лучшей характеристикой
для описываемого алгоритма.
На первом шаге алгоритма текущая триангуляция состоит из
единственного ребра выпуклой оболочки множества исходных точек, т. е. ребра, слева от которого нет опорных точек (если мы строим триангуляцию слева направо). На каждой из последующих итераций алгоритм ищет новый треугольник, который подключается
к границе текущей триангуляции. По окончании работы алгоритма
текущая триангуляция является триангуляцией Делоне.
В начале работы алгоритма живым объявляется единственное
ребро, принадлежащее выпуклой оболочке множества опорных
точек. К этому ребру примыкает неограниченная плоскость. Все
остальные ребра – спящие. По мере работы алгоритма ребра из спящих становятся живыми, а затем мертвыми. Граница на каждом
этапе состоит из набора живых ребер.
На каждой итерации алгоритма выбирается одно из ребер границы (обозначим его R), которое и подвергается обработке. Обработка
R заключающейся в поиске неизвестной области, которой принадлежит ребро R. Если область окажется треугольником ∆, определяемым концевыми точками ребра R и некоторой третьей вершиной V,
то ребро становится мертвым, так как теперь известны обе примыкающие к нему области. Каждое из двух других ребер треугольника ∆
переводится в следующие состояния (из спящего – в живое, а из живого, соответственно, в мертвое). Вершина V называется сопряженной с ребром R. Если неизвестная область – бесконечная плоскость
(сопряженной точки не существует), ребро R становится мертвым.
Алгоритм заканчивает свою работу, когда все ребра станут мертвыми. Для триангуляции Делоне характерно то, что формируемые
15
треугольники стремятся к равноугольности. Исходя из этого, поиск
сопряженной точки осуществляется с учетом того, что чем меньше
радиус окружности, описанной вокруг треугольника с вершинами
в концевых точках обрабатываемого ребра и в некоторой третьей
точке, выбираемой из тех, что лежат справа от ребра, тем ближе
этот треугольник к равноугольному.
Следовательно, для каждой точки справа от ребра необходимо
посчитать расстояние от центра описанной вокруг вершин ребра и
этой точки окружности до ребра. Причем, если центр окружности
лежит слева от ребра, то расстояние берется с минусом (это условие необходимо для того чтобы внутрь образуемых треугольников
не попадали опорные точки). Тогда в качестве сопряженной точки
выбирается та, для которой это расстояние минимально.
Пример реализации этого алгоритма представлен на рис. 1.6.
Здесь сплошной линией изображаются мертвые ребра, а пунктирной – живые. Стадии развития процесса триангуляции пронумерованы.
Алгоритм «разделяй и властвуй»
Алгоритм «разделяй и властвуй» (Divide-and-Conquer или D&C
алгоритм) вычисляет триангуляцию Делоне только для выпуклой
оболочки набора точек.
Сначала все точки располагаются в порядке увеличения координаты х (если две точки имеют одинаковую х координату, их порядок определяется у координатой). После того, как на множестве точек установлен порядок, это упорядоченное множество разбивается на два подмножества. Этот процесс разбиения на подмножества
продолжается до тех пор, пока мощность подмножеств не станет ≤3
(в каждом подмножестве не более трех точек). На этих подмножествах провести триангуляцию элементарно: в случае двух точек в
подмножестве они просто соединяются отрезком прямой, а в случае
трех точек – образуется треугольник.
Затем триангулированные подмножества рекурсивно «склеиваются» со своими прежними половинами. В итоге каждого «склеивания» образуется триангуляция, состоящая из LL-ребер – ребер,
первоначально присутствующих в левой триангуляции, имеющих
конечные точки в левом подмножестве; RR-ребер – ребер, первоначально присутствующих в правой триангуляции, имеющих конечные точки в правом подмножестве; и LR-ребер – новых ребер между
16
Описание сцены в трехмерном приложении
Стадия геометрических прелюразований
Генерация
треугольников
Модельные
преобразования
Проверка
гшлубины
Освещение
Стадия Рендеринга
Сортировка по
Zбуферу и
смешение текстур
Наложение
текстур
Закраска
треугольников
Сглаживание
Вывод изображения сцены на дисплей
Рис. 1
Y
Y
0
X
X
0
Y
X
0
Рис. 1.2
B
A
0
3
5
0
2
4
2
4
3
2 0
0
1
3
3
1
2
1
1
0
Рис. 1.3
B
C
2
A
D
1
D
D
A
B
C
D
C D
E
C
B
A
D
E
A
CE
0
B
B
D
E
C
D
C
B E
A
D
A
Рис. 1.4
17
P1
P0
P3
P2
P5
P6
P7
P8
P2
P7
P5
P4
P2
P6
P3
P4
P5
P7 P8
P4
P7
P8
P3
P6 P2
P4
P7 P8
P3
P1
P3
P2
P6
P5
P5
P8
P6
P1
P1
P1
P3
P1
P5
P4
P2
P6
P4
P7
P8
Рис. 1.5
1)
5)
2)
3)
6)
7)
4)
Рис. 1.6
Две первоначальные
триангуляции
Базовое LRребро
Новое LRребро
Новое LRребро
Рис. 1.7
18
Новое LRребро
левой и правой триангуляциями, имеющими одну конечную точку из левого подмножества, а вторую – из правого. Для того чтобы
новая триангуляция удовлетворяла критерию Делоне, иногда приходится удалять некоторые LL или RR-ребра. Но новые LL или RRребра при «склеивании» никогда не создаются.
На первом шаге процедуры склеивания двух триангуляций низшего уровня производится вставка базового LR-ребра. Базовое LRребро – это самое нижнее LR-ребро, не пересекающее ни одного LL
или RR-ребра.
Затем определяется следующее добавляемое LR-ребро прямо
над базовым LR-ребром. Такое ребро будет иметь в качестве одной
из конечных точек левую (правую) конечную точку базового LRребра. Другая конечная точка будет соответственно из правого (левого) подмножества точек. Пусть потенциальный кандидат (точка,
которая может быть выбрана в качестве концевой точки добавляемого LR-ребра и не являющаяся концевой точкой базового LRребра) сначала ищется в правом подмножестве точек. Тогда сначала рассматривается точка, соединенная с правой точкой базового
LR-ребра RR-ребром, которое определяет самый маленький по часовой стрелке угол от базового LR-ребра (назовем эту точку потенциальным кандидатом).
Затем проверяется удовлетворяет ли потенциальный кандидат
следующим критериям:
1. Угол по часовой стрелке от базового LR-ребра до выбранной
точки (потенциального кандидата) должен быть <180°.
2. Окружность, определяемая двумя конечными точками базового LR-ребра и выбранной точкой (потенциальным кандидатом)
не должна содержать следующей точки, которая может быть выбрана (следующий потенциальный кандидат).
Если оба критерия выполняются, то потенциальный кандидат
становится окончательным кандидатом для правой стороны добавляемого LR-ребра. Если первый критерий не выполняется, то для
правой стороны нет кандидата. Если первый критерий выполняется, а второй нет, то RR-ребро от потенциального кандидата к правой
конечной точке базового LR-ребра удаляется.
Данная процедура повторяется со следующим потенциальным
кандидатом (следующий потенциальный кандидат определяется
следующим наименьшим по часовой стрелке углом от базового LRребра) до тех пор, пока последний правый кандидат не выбран или
не установлено, что кандидатов больше нет.
19
При выборе потенциального кандидата из левого подмножества
точек процесс совершенно аналогичен (с учетом того, что вместо
RR-ребер используются LL-ребра, а углы считаются против часовой
стрелки).
Если подходит только один кандидат (либо из левого, либо из
правого подмножества), то это автоматически определяет LR-ребро
для добавления (добавляемое LR-ребро проводится от единственной точки-кандидата до концевой точки базового LR-ребра, лежащей в другом (относительно точки-кандидата) подмножестве точек). В случае, когда подходят оба кандидата, соответствующее LRребро выбирается в результате следующей процедуры: если правый
кандидат не содержится внутри окружности, определенной двумя
концевыми точками базового LR-ребра и левым кандидатом, тогда
левый кандидат определяет LR-ребро и наоборот.
Когда новое LR-ребро добавлено, процесс повторяется с вновь
добавленным LR-ребром, которое становится базовым. Алгоритм
завершается, когда «склеиваются» последние два подмножества
точек (те, что получились в результате первого деления исходного
множества точек). На рис. 1.7 приведен пример работы данного алгоритма.
1.1.2. Моделирование с использованием кривых и поверхностей
Моделирование криволинейной поверхности совокупностью
плоских граней-полигонов, которые, соединяясь друг с другом,
образуют сложные трехмерные сетки, имеет отчетливо выраженный недостаток. Действительно, реализованные с помощью полигональных моделей изображения выглядят угловатыми и недостаточно реалистичными. Улучшить качество подобных изображений можно, увеличивая количество полигонов (делая эти полигоны все более мелкими) при моделировании объекта с помощью
полигональных сеток. Однако увеличение числа полигонов существенно замедляет обработку изображения моделируемого объекта. Кроме того, даже при достаточно большом числе полигонов
полностью избавиться от недостатка, присущего полигональным
моделям, невозможно, поскольку в точках сопряжения полигонов
разрывы появляются уже в первых производных (говорят, что моделирование с использованием полигонов имеет нулевой порядок
непрерывности).
20
Единственный путь устранения этого недостатка – повышение
порядка непрерывности используемых моделей. Для этого в последнее время в графических конвейерах применяются методы
моделирования гладких поверхностей, использующие формализм кривых и поверхностей Безье, а также сплайнов. Криволинейные поверхности, построенные на основе таких методов, для
человеческого глаза кажутся идеально плавными и гладкими.
Поскольку человеческий глаз не в состоянии обнаружить разрывы в третьей производной, достаточно использовать кубические
сплайновые поверхности, имеющие непрерывные первую и вторую производные, что обеспечивает непрерывность и гладкость
сопряжения кусочных полиномов в узловых точках кривой или
поверхности.
При использовании полиномиальных функций для моделирования объектов классическими являются следующие две задачи:
1. Задача интерполяции. Дано множество точек-ориентиров,
требуется построить кривую (или поверхность), точно проходящую
через заданное множество точек-ориентиров.
2. Задача аппроксимации. Дано множество точек-ориентиров,
требуется построить кривую (или поверхность), проходящую вблизи заданного множества точек-ориентиров.
Решению этих задач и посвящен материал, изложенный далее.
Сначала обратимся к решению задачи аппроксимации с использованием кривых и поверхностей Безье [17,19].
Кривые и поверхности Безье
Рассмотрим задачу представления кривой, аппроксимирующей
исходные данные. При решении этой задачи методом Безье многочлены задаются в параметрической форме x = px(t), y = py(t). Сначала рассмотрим решение поставленной задачи на плоскости.
Пусть задано множество точек-ориентиров (x0,y0), ..., (xm,ym).
Многочлен Безье задается выражением
m
m
i=0
i=0
m-i
i i
i i
px (t) = å Cm
t (1 – t)m-i xi , py (t) = å Cm
t (1 – t)
i =
где C m
yi ,
m!
и 0 £ t £ 1.
i !× (m - i)!
Переходя к векторной форме записи, получим
21
m
éx ù
é P x(t)ù
i i(1 - t) m-iP .
ú ; P i = ê i ú Þ P(t) = å C m
P(t) = êê
t
i ê
ú
ú
y
(
t
)
ë iû
i=0
ëPy û
(1.1)
i (t) = i i(1 - t) m-i называется базиСовокупность функций Â m
C mt
сом Бернштейна. Если несколько отвлечься от излагаемой задачи и
i (t) есть функция плотности
вспомнить теорию вероятностей, то Â m
i (t) – веровероятности для биномиального распределения, т. е. Â m
ятность того, что при m независимых испытаниях некое событие
наступит ровно i раз, если вероятность наступления этого события
i (0) = 0 для любого
0 (0) = 1,
t. Таким образом, очевидно, что Â m
Âm
i (1) = 0 для любого i ¹ m. Учитывая
i ¹ 0; кроме того, Â m
(
1
)
=
1
,
Âm
m
все сказанное, нетрудно заметить, что P(0) = P0, P(1) = Pm, т. е.
кривая Безье точно проходит через первую (P0) и последнюю (Pm)
точки-ориентиры.
Для иллюстрации еще одного важного свойства кривых Безье
получим выражение для производной многочлена Безье:
P ¢(t) = -m(1 - t)
m-1
P0 +
m-1
å éêëCmi (iti-1 (1 - t)m-i - (m - i)ti (1 - t)m-i-1ùúû ´
i=0
´P i + mtm Pm .
Несложный анализ этого выражения позволяет сделать вывод о
том, что
P′(0) = m(P1 – P0); P′(1) = m(Pm – Pm–1),
т. е. при t→0 и t→1 соответствующий многочлен Безье совпадает с
прямыми, соединяющими точки P1 и P0 и точки Pm и Pm–1. Иными словами, касательные к кривой Безье в начальной и конечной
точках совпадают с направлением векторов P1 – P0 и Pm – Pm–1.
Отметим также, что многочлен Безье расположен внутри выпуклой
оболочки множества точек-ориентиров.
Вычислять значения многочлена Безье при конкретном значении t можно, используя (1.1). Однако подсчет числа сочетаний и
возведение параметра t в большие степени требует значительных
вычислительных затрат. В связи с этим на практике при построении кривой Безье используют так называемый геометрический алгоритм построения этой кривой. Для обоснования этого алгоритма
перепишем (1.1) в виде
P(t) = (1 - t)mP0 +
22
m-1
å Cmi ti (1 - t)m-i Pi + tm Pm .
i=1
i = i
i-1 , получим
Учитывая, что C m
C m-1 + C m
-1
m-1
é
ù
i
i
m-i-1 ú
P(t) = (1 - t) êê(1 - t)m -1P0 + å Cm
Pi ú +
-1t (1 - t)
i=1
ëê
ûú
ém-1
ù
i-1 i-1(1 - t) m-iP + m-1
+t êê å C m
P múú .
i t
-1t
ëê i=1
ûú
В первых квадратных скобках представлен многочлен Безье для
точек P0, P1, ..., Pm–1, а во вторых – для точек P1, P2, ..., Pm. Обозначим многочлен Безье для точек Pk, Pk+1, ..., Pl через Pk,l(t). Тогда последнее уравнение перепишется в виде
P0,m (t) = (1 - t) P0,m-1 (t) + tP1,m (t) = P0,m-1 (t) + t éëê P1,m (t) - P0,m-1 (t)ùûú .
Таким образом, многочлен Безье можно построить на основе двух
других многочленов этого типа, соединив точки, соответствующие
одному и тому же значению t, прямой линией и разделив последнюю пропорционально t. Обозначим через Ri и Qi старые и новые
точки-ориентиры, соответственно. Тогда геометрический алгоритм
построения многочленов Безье можно представить следующим образом:
P(0) = Po
for t = T to 1-T step T
for i = 0 to m
Ri = Pi
next i
n=m
while (n > 0) do
for i = 0 to n-1
Qi = Ri + t. (Ri+1 – Ri)
n = n-1
next i
for i = 0 to n
Ri = Qi
next i
endwhile
P(t) = Ro
next t
P(1) = Pm
stop.
23
а)
P1
Точка, через б)
P1 = P2
которую
пройдет
кривая
Безье при
t = 0,5
P2
P0
P3
P0
Рис. 1.8
Выбирая шаг алгоритма (T) достаточно маленьким, получим
большое число точек, которые и образуют требуемую кривую Безье,
аппроксимирующую заданное множество точек-ориентиров.
Пример 1.1. Пусть имеются три точки-ориентира: P0, P1, P2,
и пусть t = 0,5. Точка, через которую пройдет кривая Безье при
t = 0,5, и примерный вид этой кривой показаны на рис. 1.8, а. Если
в одном месте поместить несколько точек-ориентиров (сделать точку кратной), то можно «заставить» кривую Безье пройти ближе к
этой точке (рис. 1.8, б).
Таким образом, многочлен Безье можно представить как некоторую намагниченную металлическую эластичную ленту, закрепленную в первой и последней точках-ориентирах. Во всех остальных
точках-ориентирах закреплены магниты. Лента притягивается
к каждой точке, причем, чем больше напряженность магнитного
поля в точках-ориентирах (т. е. чем больше их кратность), тем ближе будет притянута лента к ним. При стремлении кратности точек
к бесконечности многочлен Безье стремится к ломаной, точками
сопряжения для которой служат точки-ориентиры.
Для построения составных кривых Безье, которые наиболее часто
используются в графических приложениях, необходимо объединить
несколько элементарных кривых Безье: Ρ (t) = P(1) (t) ...  P(k) (t).
Это означает, что концевая точка кривой P(i)(t), i = 0, …, k – 1 совпадает с начальной точкой кривой P(i + 1)(t), i = 0, …, k – 1 (рис. 1.9).
Для того чтобы составная кривая Безье была гладкой, необходимо
выполнение ряда условий. Предположим, мы хотим построить составную кривую Безье, состоящую из двух кривых P(t) и Q(t), одна
из которых задана вершинами A0, A1, ..., An, а вторая – вершина24
(2)
(1)
P1
P1
(1)
P2
(1)
P0
P (32)
( 2)
=P 0
Первая элементарная
кривая Безье
(2)
=P 2
Вторая элементарная
кривая Безье
Рис. 1.9
ми B0, B1, ..., Bm. Для того чтобы составная кривая выглядела
гладкой, необходимо условие непрерывности первой производной
в точке соединения кривых Безье, которое выражается соотношением P′(1) = kQ′(0), где k – некоторый числовой коэффициент.
Пользуясь условием поведения кривой Безье в начальной и конечных точках, получим Q′(0) = m(B1 – B0) = P′(1) = n(An – An–1) и
n
B1 - B0 = ( An - An-1 ). Результирующая кривая Безье должна
m
n
быть непрерывной, т. е. An = B0. Тогда B1 = ( An - An-1 ) + An .
m
Отсюда следует, что направления касательных в точке склеивания
двух соседних кривых Безье совпадают, если три точки An–1, An
= B0, B1 коллинеарны (An лежит на прямой, соединяющей точки
An–1 и B1). Если n = m, то B1 – B0 = An – An–1 = B0 – An–1 или B1 +
An–1 = 2B0 = 2An. Таким образом, точка An = B0 является серединой отрезка от An–1 до B1. Пример кривой Безье, составленной из
двух кубических кривых Безье, приведен на рис. 1.10.
A1
A2
B2
B3
B0
A3
Первая кубическая
кривая Безье
A0
B1
Вторая кубическая
кривая Безье
Рис. 1.10
25
P2
P1
P3
P0 =P6
P5
P4
Рис. 1.11
Для построения замкнутой кривой
Безье по точкам-ориентирам P0, P1,
..., Pm–1, Pm необходимо, чтобы точки P0 и Pm совпадали (P0 = Pm) (рис.
1.11).
Если промежуток изменения параметра t не ограничен интервалом [0,
1], т. е. a £ t £ b, то уравнение кривой Безье записывается в виде:
i
m-i
m
t - a ö÷
i æç t - a ö÷ æç
P(t) = å Cm
Pi .
1
÷
÷
ççè b - a ÷ø èçç
b - a ÷ø
i=0
Рассмотрим теперь поверхности Безье в трехмерном пространстве, учитывая то, что они обладают свойствами, подобными свойствам плоских кривых Безье.
Пусть задан массив точек-ориентиров в трехмерном пространстве P = {Pij} i = 0, 1, …, m; j = 0, 1, …, n. Точки Pij являются вершинами задающей полигональной сетки, т. е. эти точки условно расположены в виде m + 1 ряда по n + 1 точек в каждом ряду. Таким
образом, точка Pij находится на j-м месте в i-м ряду полигональной
сетки. Тогда поверхность Безье для заданного множества точек
определяется следующим образом:
m
n
i i
P(u,v) = å å Cm
u (1 - u)m-i Cnj v j (1 - v)n-j Pij ; 0 £ u £ 1, 0 £ v £ 1.
i=0 j=0
Говорят, что в направлении u поверхность Безье имеет порядок
m, а в направлении v – порядок n. Предположим, что на базе каждых четырех точек Pij, Pij+1, Pi+1j и Pi+1 j+1 построена билинейная
поверхность. В этом случае все множество точек-ориентиров P являются вершинами многогранника, который называется характеристическим. Подобно тому, как плоская кривая Безье проходит
точно через первую и последнюю точки-ориентиры, поверхность
Безье точно проходит только через угловые точки полигональной
сетки (это точки P(0,0) = P00, P(0,1) = P0n, P(1,0) = Pm0 и P(1,1) =
Pmn). Если рассечь поверхность Безье вдоль линий u = const или
v = const, то в сечении получим кривые Безье. Граничные кривые
поверхности Безье представляют собой элементарные кривые Безье соответствующих степеней, их опорные ломаные образуют границу характеристического многогранника. Пример характеристи26
Рис. 1.12
ческого многогранника и поверхность Безье, аппроксимирующая
вершины этого многогранника, представлены на рис. 1.12.
Если число точек-ориентиров велико, то и степень поверхности Безье также велика, поэтому с вычислительной точки зрения
практическое использование таких поверхностей неэффективно.
В этом случае используют составные поверхности Безье более низких степеней, подобно тому, как использовались составные кривые
Безье. Вдоль стыкуемых краев отдельные поверхности Безье должны иметь одинаковые степени. Для того чтобы поверхности Безье
гладко стыковались друг с другом, необходимо чтобы ребра характеристического многогранника, прилегающие к углам стыкуемых
поверхностей, были компланарны, т. е. лежали в одной плоскости.
Если область изменения параметров u и v является произвольным прямоугольником вида P = {(и,v)|a ≤u≤b, c≤v≤,d}, то уравнение
поверхности Безье принимает следующий вид:
m n
i æç u - a ö÷ j æç v - c ö÷
P(u,v) = å å Bm
÷B ç
÷P .
çç
è b - a ø÷ n èç d - c ø÷ ij
i=0 j=0
Практически интересным случаем является элементарная бикубическая поверхность Безье (m = n = 3), определяемая следующим
множеством вершин:
P00, P01, P02, P03,
P10, P11, P12, P13,
P20, P21, P22, P23,
P30, P31, P32, P33.
Используя базис Бернштейна, эту поверхность можно задать
следующим образом:
æ 3
ö÷
3
ç
P(u,v) = å B3i (u)çç å B3j (v) Pij ÷÷÷, 0 £ u £ 1, 0 £ v £ 1
çç
÷÷ø
è j=0
i=0
27
или в матричной форме:
é 0 ù
P 03ùú ê Â 3(v)ú
ê
ú
P13úú ê Â13(v)ú
×ê
ú.
P 23úú ê Â23(v)ú
ê
ú
P 33úûú êê Â 3(v)úú
ë 3 û
Теперь остановимся на построении составных бикубических поверхностей Безье, поскольку именно такой вид поверхности Безье
наиболее часто используется на практике. Составные поверхности
Безье более высоких степеней строятся аналогично.
Пусть R(1)(u, v) и R(2)(u, v) (u, v)∈[0,1]´[0,1] – радиусы-векторы
двух элементарных поверхностей Безье S(1) и S(2)соответственно,
порожденные массивами P(1) = {Pij(1),
(1)
(2)
R ( 1 , v ) = R ( 0 , v)
i = 0, 1, ..., т, j = 0, 1, ..., n} и P(2) = {Pij(2),
i = 0, 1, ..., m, j = 0, 1, ..., n}, такими,
(1)
что Pmj(1) = P0j(2), j = 0, …,n. Последнее
S
(2)
S
условие означает, что поверхности S(1)
и S(2) имеют общую граничную кривую
R(1)(1, v) = R(2)(0, v) 0 £ v £ 1 (рис. 1.13).
Как уже отмечалось, гладкость составной поверхности Безье обеспечиваРис. 1.13
ется коллинеарностью всех троек вида
Pm–1,j(1), Pmj(1) = P0j(2), P1j(2) и выполнением условия
é P 00
ê
ê P10
0
1
2
3
é
ù
ê
P(u,v) = ê Â3 (u) Â3 (u) Â3 (u) Â3 (u)ú ê
ë
û P 20
ê
êP
ëê 30
P 01
P11
P 21
P 31
P 02
P12
P 22
P 32
(1)
P mj - P1m-1,j
(2)
(2)
P1 j - P 0 j
= const
для всех j. Последнее условие говорит о том, что касательная плоскость к составной поверхности при переходе через общую граничную кривую стыкуемых фрагментов изменяется непрерывно.
Обобщением элементарных поверхностей Безье являются рациональные поверхности Безье. Элементарная рациональная поверхность Безье определяется уравнением следующего вида:
m
n
å å wij Bmi (u)Bnj (v)Pij
P(u,v) =
i=0 j=0
m n
åå
i=0 j=0
28
,0 £ u £ 1, 0 £ v £ 1,
i
wij Bm
(u) Bnj (v)
где неотрицательные числа wij называются весовыми коэффициентами (или просто весами); причем сумма всех весов положительна.
Понятно, что в частном случае, когда все веса wij равны между собой, имеем элементарную поверхность Безье.
Практически интересным случаем является элементарная бикубическая рациональная поверхность Безье (m = n = 3), определяемая следующим множеством вершин:
P00, P01, P02, P03,
P10, P11, P12, P13,
P20, P21, P22, P23,
P30, P31, P32, P33.
Указанная поверхность описывается уравнением
3 3
1
P(u,v) =
å
å wij B3i (u)B3j (v)P ij, 0 £ u £ 1, 0 £ v £ 1,
w(u, v) i=0 j=0
3
3
где w(u,v) = å å wij B3i (u)B 3j (v).
i=0 j=0
Практическая важность рациональных бикубических поверхностей Безье объясняется ее следующими свойствами.
1. Данная поверхность является гладкой.
2. Граничными кривыми элементарной бикубической поверхности Безье являются элементарные рациональные кубические
кривые Безье (управляемые, правда, разными наборами весовых
коэффициентов); их опорными ломаными являются границы опорной многогранной поверхности (опорного графа). В частности, граничная кривая, описываемая радиусом-вектором R(u, v), является
элементарной рациональной кривой Безье с опорным массивом
вершин Р00, Р01, Р02, Р03. Все 4 угловые вершины опорного многогранника Р00, Р03, Р30 и Р33 лежат на поверхности Безье, т. е.
R(0,0) = P00, R(1,0) = P30, R(0,1) = P03, R(1,1) = P33, и поверхность
касается угловых граней опорного многогранника.
3. Элементарная рациональная бикубическая поверхность Безье
лежит в выпуклой оболочке, порожденной массивом Р.
4. Если все вершины массива Р лежат в одной плоскости, то
определяемая этим массивом элементарная рациональная бикубическая поверхность Безье представляет собой плоский криволинейный четырехугольник, лежащий в этой плоскости.
5. Поведение рациональной бикубической поверхности Безье
определяется не только массивом вершин P, но и набором свобод29
ных параметров – весовых множителей wij. Таким образом, при
заданном наборе вершин формой элементарной рациональной бикубической поверхности Безье можно управлять, меняя весовые
коэффициенты.
6. Изменение хотя бы одной вершины в массиве приводит к заметному изменению всей элементарной рациональной поверхности
Безье.
В заключение следует отметить, что при построении составной
рациональной бикубической поверхности Безье необходимо иметь
в виду, что, во-первых, определяющий ее массив P = {Pij} i = 0, 1, …,
m; j = 0, 1, …, n не может быть произвольным: числа т и п должны
удовлетворять условию вида: т = 3k + 1, п = 3l + 1 (выполнения
этого условия легко добиться добавлением в исходный массив новых вершин). Во-вторых, следует понимать, что хотя подбором весов можно влиять на форму составной поверхности, однако в общем
случае она будет всего лишь непрерывной, и кривые стыка элементарных фрагментов будут на этой поверхности ребрами.
По аналогии с плоскими кривыми Безье можно строить замкнутые поверхности Безье.
Построение кривых по точкам с помощью сплайнов
Предположим, что Вы построили кривую по точкам-ориентирам,
поведение которой на некоторых участках Вас не устраивает, т. е.
Вы хотите внести изменения в некую часть кривой, не затрагивая ее
остальные участки. Говорят, что схема построения кривой по точкам
локальна, если локальные изменения не распространяются на другие
части изображения. Очевидно, что многочлен Безье обладает лишь
квазилокальностью, поскольку изменение расположения или кратности одной из точек-ориентиров требует пересчета всей кривой, несмотря на то, что указанные изменения могут слабо влиять на вид кривой при достаточном удалении от соответствующей точки-ориентира.
Одним из средств реализации локальной схемы построения кривой
являются кусочно-полиномиальные функции. В общем виде кусочнополиномиальные функции представляются таким образом:
p(x) = pi(x), xi≤x≤ xi+1, i = 0, ..., k – 1;
pi(j)(xi) = p(j) i+1(xi), j = 0,... r – 1, i = 1,... k – 1;
(1.2)
здесь точки x1, ..., xk–1, которые делят сегмент [a, b] на k подсегментов, называются точками склеивания, а точки p(xi) – узлами;
30
x0 = a, xk = b; pi(x) – многочлены степени ≤m; pi(j) – j-я производная
полинома pi(x) (j > 0), pi(°) = pi(x).
Случай, когда r = 3 и m = 3, имеет особое значение, так как именно для обозначения соответствующих кусочно-полиномиальных
функций впервые был предложен термин “сплайн″ [14]. Этот термин появился задолго до возникновения машинной графики, когда
чертежник, чтобы провести гладкую кривую через заданное число
точек, часто использовал грузики, помещая их в заданных точках
и придавая с их помощью необходимую искомую форму гибкой линейке, которая и называлась сплайном. Если обратиться к теории
упругости, то можно доказать, что результирующая кривая представляет собой кусочно-кубический многочлен, который является
непрерывным, а также имеет непрерывную первую и вторую производные. Эта кривая имеет постоянную кривизну и разрывы возникают лишь в третьей производной. Кроме того, если вдоль сплайна совершается механическое движение, то непрерывность второй
производной предполагает непрерывность ускорения и, следовательно, отсутствие резких изменений прилагаемой силы. Эти свойства оказываются весьма важными для применения сплайнов при
решении многих прикладных задач конструирования.
Простым сплайном называется кусочно-полиномиальная функция, задаваемая уравнениями (1.2) при r = m [13]. Термины “линейный″, “квадратичный″ и “кубический″ сплайн относятся соответственно к кусочно-полиномиальной функции при m, равных 1, 2 и 3.
Сплайном называется кусочно-полиномиальная функция, задаваемая уравнениями (1.2) при r < m [13].
Некоторые авторы вместо терминов “простой сплайн″ и “сплайн″
используют соответственно термины “сплайн с простыми узлами″ и
“сплайн с кратными узлами″, так как кратный узел (xi = xi+1) снижает число ограничений на 1 и при этом r становится меньше m.
На практике вместо формул (1.2) чаще используют другую
форму представления сплайнов: они задаются в виде сумм других
сплайнов, в частности сплайнов специального вида – В-сплайнов
[14, 19]. В-сплайн j-й степени, отличный от нуля, начиная с точки
xi, будем обозначать Bi,j(x).
В-сплайн с постоянным значением на i-м подсегменте задается
выражением
ì
ï1, ïðè xi £ x £ xi+1;
(1.3)
Bi,0 (x) = ï
í
ï
x .
ï
î0, ïðè äðóãèõ
31
Графики нескольких соседних В-сплайнов нулевой степени
представлены на рис. 1.14.
В-сплайн m-й степени на сегменте [xi, xi+m+1] определяется выражением
x
-x
x - xi
Bi,m (x) =
Bi,m-1 (x) + i+m+1
Bi+1,m-1 (x). (1.4)
xi+m - xi
xi+m+1 - xi+1
Таким образом, В-сплайн – это сплайн, равный 0 на всех подсегментах, за исключением m плюс одного.
Используя (1.3) и (1.4), можно задать в явном виде В-сплайны
любой степени. В частности, линейный В-сплайн:
ìï
x - xi
ïï
, ïðè xi £ x £ xi+1,
ïï xi+1 - xi
ïï
-x
ï x
Bi,1 (x) = ïí i+2
, ïðè xi+1 £ x £ xi+2 ,
ïï xi+2 - xi+1
ïï
0, ïðè äðóãèõ x.
ïï
ïï
ïî
Графики нескольких соседних линейных В-сплайнов представлены на рис. 1.15.
Аналогично, квадратичный В-сплайн можно получить на основе двух соседних линейных В-сплайнов:
ì
ï
(x - xi )2
ï
ï
, ïðè xi £ x £ xi+1,
ï
(
x
x
)(
x
x
)
ï
i
i
i
i
2
1
+
+
ï
ï
ï
ï
(x - xi )(xi+2 - x)
ï
+
ï
ï
(xi+2 - xi )(xi+2 - xi+1 )
ï
ï
ï
(x - xi+1 )(xi+3 - x)
Bi,2 (x) = ï
í+
, ïðè xi+1 £ x £ xi+2 ,
ï
ï
(xi+3 + xi+1 )(xi+2 - xi+1 )
ï
ï
ï
ï
ï
(x - xi+3 )2
ï
ï
, ïðè xi+2 £ x £ xi+3 ,
ï
ï
(xi+3 - xi+1 )(xi+3 - xi+2 )
ï
ï
ï
ï
ï
î0, ïðè äðóãèõ x.
Графики нескольких соседних квадратичных В-сплайнов представлены на рис. 1.16.
Наибольший интерес представляют кубические B-сплайны.
Дело в том, что у этих кривых разрывы возникают лишь в третьей
32
производной, а человеческий глаз не может обнаружить эти разрывы. Поэтому такие кривые человеку кажутся абсолютно гладкими.
Кубический В-сплайн можно получить на основе двух соседних
квадратичных В-сплайнов. И так далее… Таким образом, построить B-сплайн m-й степени можно, имея выражения для двух соседних B-сплайнов (m – 1)-й степени.
Если предполагать, что точки склеивания размещаются на сегменте длиной L равномерно, то приведенные выражения существенно упрощаются. В этом случае разумно допустить, что xi = iL
и, введя новую переменную u = (x – xi)/L, получим:
равномерно-линейный В-сплайн:
ìïu, ïðè 0 £ u £ 1,
ïï
Ui,1 ((i + u)L) = ïí2 - u, ïðè 1 £ u £ 2,
ïï
ïïî0, ïðè äðóãèõ u ,
равномерно-квадратичный В-сплайн:
ïìïu2 /2, ïðè 0 £ u £ 1,
ïï
2
ïï3 / 4 - (u - 3 / 2) , ïðè 1 £ u £ 2,
Ui,2 ((i + u)L) = í
ïï
2
1
/
2
(
3
u
)
,
ïðè
2
£
u
£
3
,
ïï
ïï0, ïðè äðóãèõ u.
ïî
(1.5)
Графики равномерно-линейных, равномерно-квадратичных и
равномерно-кубических В-сплайнов представлены соответственно
на рис. 1.17, рис. 1.18 и рис. 1.19.
Произвольный сплайн можно получить, используя в качестве
базиса В-сплайны:
p(x) =
k-1
å
i=-m
ai Bi,m (x), (1.6)
где k – число сегментов.
Этот сплайн обладает свойством локальности, поскольку изменение любого из коэффициентов ai в уравнении (1.6) приводит к изменению кривой только на m плюс одном сегментах, следовательно, пересчитывать всю оставшуюся часть кривой не надо.
Пример 1.2. Построить интерполяционный равномерноквадратичный сплайн по точкам-ориентирам с координатами (0;0),
(1;1), (2;0), (3; – 1), (4; – 1), (5; – 1), (6;0), (7;1), (8;0).
33
В данном случае L = 1. Подставляя выражение из (1.5) в (1.6), и
учитывая, что u = (x – xi)/L = x/L – i и L = 1, получим
p(x) = 1/2ai(x – i)2 + ai–1(3/4 – (x – (i + 1/2))2) + 1/2ai–2 ×
× (i + 1 – x)2, при i≤ x ≤ i + 1.
Выражение для производной в этом случае примет вид
p′(x) = ai(x – i) – 2ai–1(x – (i + 1/2)) – ai–2(i + 1 – x).
Эти два уравнения справедливы при i = 0, 1, ..., n – 1, где n –
число точек-ориентиров (в нашем случае n = 9). Таким образом, в
точках склеивания имеем p(i) = 1/2(ai–1 + ai–2), p′(i) = ai–1 – ai–2.
Следовательно, для нахождения неизвестных коэффициентов ai
для этого примера получим следующую систему уравнений:
ìa-1 + a-2 = 0
ï
ï
ï
ï
a0 + a-1 = 2
ï
ï
ï
a1 + a0 = 0
ï
ï
ï
ï
a2 + a1 = -2
ï
ï
ïa + a = -2 .
í 3
2
ï
ï
a
a
+
ï
4
3 = -2
ï
ï
ï
a5 + a4 = 0
ï
ï
ï
ï
a6 + a5 = 2
ï
ï
ï
ï
ï
îa7 + a6 = 0
Система содержит 9 уравнений и 10 переменных. Для определенности необходимо задать касательную в одной из точек-ориентиров
(тем самым можно влиять на вид итогового интерполяционного
сплайна). Действительно, давайте рассмотрим два случая.
Сначала, заметив, что исходные точки-ориентиры расположены
симметрично относительно точки с координатами (4; – 1), попытаемся построить кривую, симметричную относительно этой точки.
Для этого положим p′(4) = 0, т. е. в средней из симметрично расположенных точек-ориентиров зададим горизонтальную касательную. В результате представленная система уравнений будет дополнена уравнением a3 – a2 = 0. Теперь число уравнений равно числу
неизвестных. Решив эту систему, получим значения всех коэффициентов ai:
a–2 = – 1, a–1 = 1, a0 = 1, a1 = –1, a2 = –1, a3 = –1, a4 = –1,
a5 = 1, a6 = 1, a7 = –1.
34
Теперь можно приступить к построению кривой. Поскольку
сплайн – кусочно-полиномиальная функция, необходимо определить ее вид на каждом интервале i≤x≤i + 1. Для примера рассмотрим интервал 0 ≤ x ≤ 1 (т. е. i = 0). В этом случае
p(x) = 1/2(x)2 + (3/4 – (x – (1/2))2) + 1/2( –1)(1 – x)2 = 2x – x2.
Следовательно, на участке 0 £ x £ 1 искомый интерполяционный сплайн описывается параболой p(x) = 2x – x2. Последовательно
задавая значения i от 1 до 7, получим в явном виде выражения для
искомого сплайна на всех заданных участках. Окончательный вид
интерполяционного сплайна представлен на рис. 1.20 сплошной
линией.
Теперь изменим направление касательной в одной из заданных
точек-ориентиров. Пусть, например, p′(0) = 1. Тогда представленная система уравнений будет дополнена уравнением
a–1 – a–2 = 1.
Соответственно, неизвестные коэффициенты будут иметь другие
значения:
a–2 = –0,5, a–1 = 0,5, a0 = 1,5, a1 = –1,5, a2 = –0,5,
a3 = –1,5, a4 = – 0,5, a5 = 0,5, a6 = 1,5, a7 = –1,5.
В этом случае интерполяционный сплайн становится асимметричным, и его вид представлен на рис. 1.20 пунктирной линией.
Таким образом, задание касательной в одной из точек существенно влияет на форму итогового интерполяционного сплайна. Определить значение В-сплайна в точке x можно с помощью уравнения
(1.4). Напомню, что каждому сегменту [xi, xi+1] соответствуют лишь
m + 1 ненулевых сплайнов m-й степени, т. е. Bi,m(x) зависит лишь
от Bi,m–1(x), так как Bi+1,m–1(x) на Bi,0
этом сегменте равен нулю, а Bi–n,m(x)
(0< n ≤ m) зависит от Bi–n+1,m–1(x) и от
Bi–n,m–1(x). Проиллюстрируем вы- Bi,1 Bi1,1
числительную схему определения
значения В-сплайна в точке x (рис.
1.21). Здесь стрелками указывает- Bi,2
Bi1,2
Bi2,2
ся направление вычислительного
процесса. Вертикальные стрелки
определяют умножение на первый
Bi,3
Bi1,3
Bi2,3
Bi3,3
множитель формулы (1.4), а диагональные – умножение на второй
Рис. 1.21
35
множитель той же формулы. Таким образом, для определения значения В-сплайна m-й степени необходимо пройти (m – 1) предшествующих уровней этой схемы и на каждом из них определить значения В-сплайна от Bi,j(x) до Bi–n,j(x), где j – степень В-сплайна на
соответствующем уровне и n пробегает значения от 0 до j.
Алгоритм вычисления всех В-сплайнов в точке x∈ [xi, xi+1] можно описать следующим образом:
Bi,0(x) = 1
for j = 1 to m
for n = 0 to j
a = ((x – xi–n)/(xi–n+j – xi–n)) * Bi–n,j–1
b = ((xi–n+j+1 – x)/(xi–n+j+1 – xi–n+1)) * Bi–n+1,j–1
Bi–n,j = a + b
next n
next j
stop.
Аппроксимация с помощью сплайнов
В-сплайны можно использовать для аппроксимации кривых
аналогично тому, как это делалось с помощью многочленов Безье
[13, 18]. Пусть pi ( i = 0, k ) – множество точек-ориентиров. Сплайн
можно определить следующим образом:
k
p(t) = å pi Bi,m (t), (1.7)
i=0
Здесь t уже не ограничивается сегментом [0; 1] и точки склеивания t1, ..., tk–1 должны задаваться иначе, чем в случае многочленов
Безье. Следует помнить, что В-сплайны обеспечивают значительно более точное управление формой воспроизводимой кривой, чем
многочлены Безье. Наличие кратных точек-ориентиров вынуждает синтезируемую кривую проходить ближе к точкам-ориентирам
(как это было и в многочленах Безье).
Обозначим Bi, m, j(t) – значения Bi,m (t) при ti+j≤ t ≤ ti+j+1; j = 0,m.
В этом случае (1.7) принимает вид:
m
p(t) = å pi-j Bi-j,m,j (t), ti £ t £ ti+1. (1.8)
j=0
Для того чтобы сплайн m-й степени точно проходил через концевые точки множества точек-ориентиров, эти точки должны иметь
36
кратность, равную m. Если точки склеивания располагаются на
интервале равномерно, то можно перейти к нормированной переменной u. Тогда выражение (1.8) примет вид:
p(L(i + u)) = upi + (1 – u)pi–1, при m = 1;
p(L(i + u)) = 1/2u2pi + (3/4 – (u – 1/2)2)×
×pi–1 + 1/2(1 – u)2pi–2, при m = 2.
(1.9)
Следует отметить, что сплайн p(t) лежит внутри выпуклой оболочки самое большее m плюс одной точки-ориентира [14]. Отсюда следует, что, если m + 1 точка-ориентир лежит на прямой, то
значение искомого сплайна также будет лежать на этой прямой.
Для построения замкнутых кривых достаточно задать p–1 = pk;
p–2 = pk–1 и т. д. и t–1 = tk, t–2 = tk–1 и т. д., где k – число точекориентиров pi.
Пример 1.3. Построить равномерно-квадратичный сплайн, аппроксимирующий следующее множество точек-ориентиров:
p1 = (1;2), p2 = (2;4), p3 = (3;6), p4 = (4;4), p5 = (5;2),
p6 = (6;0), p7 = (4;0), p8 = (2;0), p0 = (0;0).
Пусть u = 0, тогда, согласно формуле (1.9), pi(0) = 0,5(pi–1 +
pi–2). Следовательно,
p0(0) = 0,5(p8 + p7),
p1(0) = 0,5(p0 + p8),
p2(0) = 0,5(p1 + p0),
p3(0) = 0,5(p2 + p1),
p4(0) = 0,5(p3 + p2),
p5(0) = 0,5(p4 + p3),
p6(0) = 0,5(p5 + p4),
p7(0) = 0,5(p6 + p5),
p8(0) = 0,5(p7 + p6).
Пусть u = 0,5, тогда pi(0,5) = 0,5(0,25pi–2 + 0,75pi–1) + 0,5×
×(0,75pi–1 + 0,25pi). Следовательно,
p0(0,5) = 0,5(0,25p7 + 0,75p8) + 0,5(0,75p8 + 0,25p0),
p1(0,5) = 0,5(0,25p8 + 0,75p0) + 0,5(0,75p0 + 0,25p1),
p2(0,5) = 0,5(0,25p0 + 0,75p1) + 0,5(0,75p1 + 0,25p2),
p3(0,5) = 0,5(0,25p1 + 0,75p2) + 0,5(0,75p2 + 0,25p3),
p4(0,5) = 0,5(0,25p2 + 0,75p3) + 0,5(0,75p3 + 0,25p4),
p5(0,5) = 0,5(0,25p3 + 0,75p4) + 0,5(0,75p4 + 0,25p5),
p6(0,5) = 0,5(0,25p4 + 0,75p5) + 0,5(0,75p5 + 0,25p6),
p7(0,5) = 0,5(0,25p5 + 0,75p6) + 0,5(0,75p6 + 0,25p7),
p8(0,5) = 0,5(0,25p6 + 0,75p7) + 0,5(0,75p7 + 0,25p8).
37
Геометрический смысл приведенных выражений состоит в том,
что точки в левой части выражений представляют собой середины отрезков, соединяющих точки, координаты которых заданы в
скобках в правых частях выражений. Если u пробегает все множество значений от 0 до 1, то получаем кривую, которая показана на
рис. 1.22.
Рациональные кубические B-сплайновые кривые и поверхности
Как уже отмечалось, в последнее время в графических конвейерах для моделирования трехмерных объектов все чаще используется формализм неоднородных рациональных B-сплайнов (чаще
всего кубических) или NURBS кривых (NURBS – Non-Uniform
Rational B-Splines). Сначала рассмотрим задачу построения гладкой кривой, проходящей вблизи некоторого множества вершин.
Пусть имеется множество точек P0, P1, P2, P3. Тогда рациональная кубическая B-сплайновая кривая для этого множества точек
определяется следующим уравнением [16]:
3
å wini (t)Pi
R (t) = i=03
,
0 £ t £ 1.
å wini (t)
i=0
Здесь wi ³ 0 – некоторые весовые коэффициенты, сумма которых строго больше нуля;
(1 - t)3
3t3 - 6t2 + 4
; n1 (t) =
;
6
6
-3t3 + 3t2 + 3t + 1
t3
n2 (t) =
; n3 (t) =
6
6
n0 (t) =
(1.10)
– функциональные множители, которые носят универсальный характер (не зависят от точек массива P0, P1, P2, P3) и в сумме равны
единице.
Если все весовые коэффициенты wi одинаковы, получаем стандартную элементарную кубическую B-сплайновую кривую. Неравномерные значения весовых коэффициентов wi порождают неоднородные рациональные B-сплайновые кривые. Причем, чем больше
значение некоторого коэффициента wi по отношению к другим
38
весовым коэффициентам, тем ближе к i-й точке пройдет результирующая кривая.
Если требуется построить рациональную кубическую B-сплай
новую кривую Â(t), определяемую множеством точек P0, ..., Pm,
m≥3, то используется метод построения составной кривой, которую
можно представить в виде объединения элементарных рациональных кубических B-сплайновых кривых
Â(t) = R1 (t)
 ... 
R m-2 (t).
Причем кривая Ri(t) строится по подмножеству Pi–1, Pi, Pi+1,
Pi+2 (i = 1, …, m – 2) исходного множества точек.
На рис. 1.23, а представлена составная рациональная кубическая B-сплайновая кривая, определяемая следующим множеством
точек на плоскости:
P0 = (1, 0), P1 = (2, 4), P2 = (3, 4), P3 = (4, 0),
P4 = (5, –2), P5 = (6, 0).
При этом все весовые коэффициенты wi равны единице. Куски
(элементарные рациональные кубические B-сплайновые кривые)
здесь отличаются друг от друга цветом. Если же задать значения
коэффициентов w3 = 0,1, w5 = 7, оставив остальные значения весовых коэффициентов без изменения, то получим составную неоднородную рациональную кубическую B-сплайновую кривую, представленную на рис. 1.23, б.
При построении гладкой кривой в трехмерном пространстве все
расчеты производятся также по приведенным формулам с учетом
того, что точка задается тремя координатами (Pi (xi, yi, zi)).
Теперь рассмотрим задачу построения гладкой поверхности по
заданному множеству вершин, используя формализм неоднородных рациональных B-сплайнов. Причем результирующая поверхность должна проходить вблизи заданного множества вершин.
Пусть имеется множество точек
P00, P01, P02, P03
P10, P11, P12, P13
P20, P21, P22, P23
P30, P31, P32, P33.
Тогда рациональная бикубическая B-сплайновая поверхность
для этого множества точек определяется следующим уравнением
[17]:
39
3
3
å å wijni (u)nj (v)Pij
R (u,v) =
i=0 j=0
3 3
, 0 £ u £ 1, 0 £ v £ 1,
å å wijni (u)nj (v)
i=0 j=0
где wij ³ 0 – веса, сумма которых строго больше нуля; ni(u),
nj(v) – функциональные множители, которые носят универсальный характер (не зависят от точек массива Pij) и, кроме того,
3
3
i=0
j=0
å ni (u) = å nj (v) =1. Формулы для множителей ni(u), nj(v) отлича-
ются от выражений (1.10) только тем, что в них вместо переменной
t фигурируют переменные u или v, соответственно.
Если все веса wij равны между собой, получаем стандартную элементарную бикубическую B-сплайновую поверхность. Неравномерные значения весовых коэффициентов wij порождают неоднородные рациональные B-сплайновые поверхности.
Если требуется построить рациональную бикубическую
B-сплайновую поверхность Â(u,v), определяемую множеством точек P = {Pij}
i = 0,1, ... m, j = 0,1, ..., n, m ³ 3, n ³ 3,
то используется метод построения составной поверхности, которую
можно представить в виде объединения элементарных рациональных бикубических B-сплайновых поверхностей
Â(u,v) =
m-2 n-2
  R (i,j) (u,v).
i=1 j=1
Причем кривая R(i,j)(u,v) описывается параметрическим уравнением вида
3
R
(i,j)
3
å å wk-1+i,l-1+jnk (u) × nl (v)Pk-1+i,l-1+j
(u,v) =
k=0 l=0
3
3
å å wk-1+i,l-1+jnk (u)nl (v)
k=0 l=0
где 0 £ u £ 1, 0 £ v £ 1, 1 £ i £ m = 2, 1 £ j £ n = 2.
40
,
1
Bi–1,0 (x) Bi,0(x) Bi+1,0(x)
Xi–1
X
Xi+1 Xi+2
Xi
Рис. 1.14
1
Bi–1,1(x) Bi,1(x)
Bi+1,1(x)
Xi –1
Xi+1
Xi
Xi+2
Xi+3
X
Рис. 1.15
0,9
0,8
0,7
0,6
0,5
0,4
0,3
0,2
0,1
0,0
–0,1
Xi–1
Bi–1,2 (x)
Bi,2 (x)
Bi+1,2 (x)
X
Xi
Xi+2
Xi+3
Xi+4
Рис. 1.16
Ui–1,1
–1
1 Ui,1 Ui+1,1
0
1
2
3
Рис. 1.17
41
Ui –1,2
U i+1,2
U i,2
0,8
0,7
0,6
0,5
0,4
0,3
0,2
0,1
0,0
–1
–0,1
0
1
2
3
4 X
Рис. 1.18
Ui –1,3
–1
0,8
0,7
0,6
0,5
0,4
0,3
0,2
0,1
0,0
–0,1 0
Ui, 3
1
Ui+1,3
2
3
4
5
X
Рис. 1.19
P(X)
1,0
0,5
0,0
0
1
2
3
4
–0,5
–1,0
–1,5
Рис. 1.20
42
5
6
7
X
8
7,00
6,00
5,00
4,00
3,00
2,00
1,00
0,00
0,00
1,00
2,00
3,00
4,00
5,00
6,00
7,00
Рис. 1.22
а) 5
б) 5
4
4
3
3
2
2
1
1
0
0
1
2
3
4
5
6
7
0
–1
–1
–2
–2
–3
–3
0
1
2
3
4
5
6
7
Рис. 1.23
–10
X
3
Y
0
3
Z
Рис. 1.24
43
На рис. 1.24 представлена составная рациональная бикубическая B-сплайновая поверхность, определяемая следующим множеством точек на плоскости:
P00 = (0,0,0), P01 = (1,0,0), P02 = (2,0,0), P03 = (3,0,0)
P10 = (0,2, – 2), P11 = (1,2, – 2), P12 = (2,2, – 2), P13 = (3,2, – 2)
P20 = (0,0, – 4), P21 = (1,0, – 4), P22 = (2,0, – 4), P23 = (3,0, – 4)
P30 = (0,3, – 6), P31 = (1,3, – 6), P32 = (2,3, – 6), P33 = (3,3, – 6)
P40 = (0,0, – 8), P41 = (1,0, – 8), P42 = (2,0, – 8), P43 = (3,0, – 8)
P50 = (0,4, – 10), P51 = (1,4, – 10), P52 = (2,4, – 10), P53 = (3,4,10).
При этом все весовые коэффициенты wij равны единице. Куски
(элементарные рациональные бикубические B-сплайновые поверхности) здесь отличаются друг от друга цветом. Система координат
развернута так, чтобы было лучше видно поведение результирующей поверхности в пространстве.
В заключение данного раздела необходимо обсудить вопрос о
целесообразности использования того или иного метода моделирования при изображении конкретного объекта. По-видимому к помощи полиномов Безье или сплайнов следует прибегать при моделировании крупных монолитных объектов, которые мало подвергаются трансформациям (элементы окружающего ландшафта, архитектурные сооружения, предметы интерьера и т. п.) и при этом
имеют криволинейную природу. Соответственно, если создаваемая
модель предусматривает возможность анимации, то использование
в ее создании B-сплайновых поверхностей чрезмерно увеличит требования к аппаратуре для обработки картинки в реальном времени,
поскольку в случае использования сплайнов каждый раз приходится пересчитывать системы сложных параметрических уравнений.
1.1.3. Моделирование с использованием методов
фрактальной геометрии
Довольно часто генерируемые в трехмерной графике изображения настолько сложны и нерегулярны, что использование для их
моделирования перечисленных методов нерационально с вычислительной точки зрения. В частности, для моделирования различных
нелинейных природных ландшафтов, облаков, водной поверхности
и т. п. предпочтительнее использовать технологию фрактальной
геометрии. Действительно, если внимательно посмотреть практически на любой природный объект, начиная с обычного листа дере44
ва и заканчивая горным массивом, то станет очевидно, что описать
или смоделировать его форму со всеми присущими объекту подробностями можно только весьма приблизительно. Для моделирования подобных объектов используют, как правило, фракталы.
Очень коротко познакомимся с фрактальной геометрией. Для
более подробного знакомства можно обратиться, например, к [7,
10].
Понятия фрактал и фрактальная геометрия являются результатом научных исследований последней трети ХХ века. Термин
фрактал образован от латинского fractus и означает состоящий
из фрагментов. Этот термин впервые был предложен Бенуа Мандельбротом в 1975 году для обозначения нерегулярных, но самоподобных структур. Таким образом, одним из основных свойств
фракталов является самоподобие. Определение фрактала, данное
Мандельбротом [10], звучит так: «Фракталом называется структура, состоящая из частей, которые в каком-то смысле подобны
целому». Таким образом, в простейшем случае некоторая часть
фрактала содержит информацию о всем фрактале в целом.
Другим интересным свойством фракталов является то, что некоторые из них обладают дробной размерностью (хотя это и не является непременным атрибутом фрактала). В повседневной жизни
мы привыкли иметь дело с объектами, имеющими целую размерность, которая может быть определена следующим образом: для
n-мерного объекта увеличение в n раз его линейных размеров приводит к увеличению «размера» самого объекта в 2n раз (здесь под
«размером» объекта понимается длина для одномерных, площадь
для двумерных, объем для трехмерных объектов соответственно).
Если обозначить через R увеличение «размера» объекта, а через L
увеличение его линейных размеров, то в этом случае размерность
log(R)
D можно определить как D =
; оказывается, что фракталы
log(L)
очень часто имею дробную размерность. Для иллюстрации этого
любопытного факта рассмотрим фрактал, известный как снежинка
Коха. Для построения этой кривой необходимо взять равносторонний треугольник (рис. 1.25 при n = 0), затем среднюю треть каждой
стороны треугольника заменить на два отрезка такой же длины (рис.
1.25 n = 1). Тем самым мы получим следующее поколение снежинки Коха. Для очередного поколения проделываются те же действия
для каждого звена кривой (на рис. 1.25 кривые для n = 3 и n = 4 увеличены для лучшего восприятия). Кривая n-го поколения при лю45
n = 0
n = 1
n =3
n = 2
n = 4
Рис. 1.25
бом конечном n называется предфракталом. При n ® ¥ снежинка
Коха становится фракталом. Определим размерность этой кривой.
Очевидно, что увеличение стороны первоначального треугольника в три раза приведет к увеличению длины кривой в четыре раза.
log(4)
Таким образом, размерность снежинки Коха D =
» 1,2618.
log(3)
Кроме этого, удивительно также то, что при n ® ¥ длина кривой
становится также бесконечной, т. е. конечная площадь ограничивается кривой бесконечной длины! На самом деле в этом, казалось
бы, удивительном факте нет ничего загадочного.
Для демонстрации подобного свойства фракталов Б. Мандельброт в своей книге «The Fractal Geometry of Nature» («Фрактальная
геометрия природы») приводит ставший уже классическим пример
об измерении длины береговой линии Британии. Представим себе,
что некто задался целью ответить на этот вопрос и занялся измерениями, вооружившись линейкой определенной длины. Предположим, что использовалась линейка стометровой длины. Потратив
изрядное количество времени на измерения, некто получит вполне определенное значение искомой длины. Однако в процессе измерения некто заметил, что вынужден был пропускать много небольших полуостровов и заливов, которые по размеру оказывались
меньше его измерительного инструмента. Учитывая это, некто
повторил измерения, но уже с использованием линейки метровой
46
длины. Полученная в результате его измерений длина береговой
линии, естественно, возросла. Однако и на этот раз некто вынужден
был пропускать объекты (валуны и скалы), меньшие, чем его метровая линейка. Неунывающий некто уменьшил размер линейки,
например, до 1 сантиметра и снова повторил измерения. Полученная длина опять возросла, поскольку при измерении были учтены
объекты, большие, чем длина сантиметровой линейки, но меньшие
метровой. И так далее… Таким образом, уменьшая длину линейки
до бесконечно малой величины, мы получим, что длина берега Британии бесконечно велика.
Фракталы с большой точностью описывают многие физические
явления и природные образования: облака, турбулентные течения,
ветви деревьев, кровеносные сосуды. Мандельброт в свое время заметил: “Почему геометрию часто называют холодной и сухой?
Одна из причин заключается в ее неспособности описать форму облака, горы, дерева или берега моря. Облака – это не сферы,
горы – не конусы, линии берега – это не окружности, и кора не является гладкой, и молния не распространяется по прямой. Природа демонстрирует нам не просто более высокую степень, а совсем
другой уровень сложности″.
 В машинной графике сегодня фрактальная геометрия используется при компьютерной генерации облаков, гор, поверхности моря,
деревьев, других сложных «неевклидовых» объектов, образы которых напоминают природные.
Мир фракталов достаточно широк и многообразен. Для краткого знакомства с этим миром обратимся к общепринятой классификации фракталов.
Геометрические фракталы
Фракталы этого класса получаются в результате простых геометрических построений на основе некоторой исходной фигуры.
Пример геометрического фрактала был рассмотрен в предыдущем
разделе (снежинка Коха).
Рассмотрим еще один пример построения геометрического фрактала. Для него «заготовкой» служат два равных отрезка, соединенные под прямым углом (рис. 1.26). В нулевом поколении заменим
каждый из двух отрезков на уменьшенную «заготовку» так, чтобы
она опиралась на «свой» отрезок и угол «заготовки» был у левого
отрезка снизу, а у правого – сверху. При построении следующих
47
n =0
n =1
n =2
n =3
n =4
Рис. 1.26
поколений выполняется несложное правило:
самое первое слева звено заменяется на «заготовку» так, чтобы середина звена смещалась
влево от направления движения, а при замене следующих звеньев, направления смещения середин отрезков должны чередоваться.
Несколько первых поколений кривой, построенной по такому принципу, показаны на
рис. 1.26. На рис. 1.27 – одиннадцатое поколение кривой.
Рис. 1.27
Предельная фрактальная кривая (при n
стремящемся к бесконечности) называется драконом ХартераХейтуэя.
Другим примером геометрического фрактала является так называемый треугольник Серпинского. Три первых шага в построении
этого фрактала показаны на рис. 1.28, а сам фрактал – на рис. 1.29.
Рис. 1.28
Число треугольников белого цвета все меньшего и меньшего масштаба в нем бесконечно. Число черных
треугольников в этом построении
растет как 3n, где n – номер шага, а
длина их стороны уменьшается как
Рис. 1.29
48
2n. Поэтому фрактальная размерlog(3)
ность равна D =
» 1,5849.
log(2)
Весьма загадочно с точки зрения
обывателя выглядит размерность
еще одной фрактальной кривой –
а)
б)
в)
Рис. 1.30
кривой Пеано. Действительно мы привыкли, что линия – одномерный объект. Алгоритм построения этой кривой (рис. 1.30) достаточно прост: на первом шаге берем прямую линию и заменяем ее
на 9 отрезков длиной в 3 раза меньшей, чем длина исходной линии
(рис. 1.30, а, 1.30, б). Затем выполняем ту же процедуру с каждым
отрезком получившейся линии (рис. 1.30, в). Если продолжать алгоритм до бесконечности – получим фрактал – кривую Пеано. Попробуем посчитать размерность этой кривой. Поскольку исходную
линию, состоящую из трех отрезков, мы заменяем на 9 отрезков
втрое меньшей длины, то при увеличении минимального отрезка
log(9)
в 3 раза длина всей линии увеличивается в 9 раз и D =
= 2.
log(3)
Таким образом, кривая Пеано – двумерный объект!
Уникальность этой кривой в том, что она заполняет всю плоскость. Доказано, что для каждой точки на плоскости можно найти
точку, принадлежащую линии Пеано. Итак, взяв за основу одномерную линию, в результате построения получим плоскость!
Примером геометрических фракталов являются также следующие широко известные кривые: кривая Гильберта, первые пять
итераций которой показаны на рис. 1.31; кривая Минковского (ее
вид после четырех итераций приведен на рис. 1.32); и кривая Леви
(ее вид после двенадцати итераций показан на рис. 1.33).
Рис. 1.31
Рис. 1.32
Рис. 1.33
49
В машинной графике геометрические фракталы часто используются при получении изображений деревьев, кустов, горных массивов, береговой линии и других подобных объектов.
В качестве примера моделирования природных объектов с использованием геометрических фракталов рассмотрим имитацию
дерева (источник – http://www.ntpo.com/physics/archive/7.shtml).
Для этого используем фрактал, называемый «деревом Пифагора» –
разновидность фрактала, основанная на общеизвестной фигуре
«Пифагоровы штаны» (на сторонах
прямоугольного треугольника расположены квадраты). Первые стадии построения дерева Пифагора
представлены на рис. 1.34.
После восьми итераций полуРис. 1.34
чим следующую модель дерева
(рис. 1.35). Однако в реальной жизни положение веток и листьев на
дереве не столь регулярно, а подчиняется вероятностным законам.
Используем броуновское движение
для создания некоторой случайной
беспорядочности, которая измеРис. 1.35
няет числа, округляя их до семи
разрядов. Результат (рис. 1.36) все
равно не похож на реальное дерево.
Однако видно, что левая сторона
(содержащая все нечетные числа)
более похожа на реальный объект.
Поэтому случайные беспорядочности, произведенные броуновским
Рис. 1.36
движением, применим дважды
ко всем числам с левой стороны и
только один раз к числам справа.
Если при этом числа округлять
до 24 разрядов, то в результате получим вполне приемлемую компьютерную имитацию реального
Рис. 1.37
дерева (рис. 1.37).
50
В заключение раздела для заинтересованных читателей рекомендую весьма полезную ссылку на учебное пособие «Введение в
теорию фракталов» А. Д. Морозов, Изд-во Нижегородского государственного университета, 1999. (http://www.truba.nnov.ru/
fractals/contents.html).
Стохастические фракталы
Рассмотренные ранее фракталы обладают очевидным недостатком, ограничивающим их применение для моделирования природных объектов, а именно: детерминированностью (об этом шла речь
в последнем примере предыдущего раздела). Ясно, что рассмотренная снежинка Коха очень похожа на снежинку, однако в природе
любые две снежинки не будут в точности совпадать, поскольку неотъемлемым свойством реального мира является случайность. Указанный недостаток детерминированных фракталов устраняется,
если в итерационном процессе случайным образом менять какиелибо его параметры. При этом получаются объекты очень похожие
на природные – несимметричные деревья, изрезанные береговые
линии и т. д. (в разделе «Геометрические фракталы» при моделировании дерева было использовано случайное изменение параметров
построения).
Наиболее известным фракталом данного класса является фрактал «Плазма» (рис. 1.38). Для построения этого фрактала берется
произвольный прямоугольник и для каждого его угла определяется цвет. Затем найденный центр прямоугольника и центр каждой
из его сторон окрашивается в цвет, равный среднему арифметическому цветов углов прямоугольника плюс некоторое случайное
число, пропорциональное размеру текущего прямоугольника.
После этого текущий прямоугольник разбивается на 4 равных
прямоугольника, к каждому из которых применяется та же процедура. Здесь следует учитывать, что чем больше используемое
случайное число, тем более неравномерным по окраске получится
итоговый рисунок.
Если предположить, что цвет точки – это высота над уровнем
моря, то вместо плазмы получим горный массив. Именно на этом
принципе моделируются горы в большинстве программ. С помощью алгоритма, похожего на плазму, строится карта высот, к ней
применяются различные фильтры, накладывается текстура и т. д.
51
Алгебраические фракталы
Рассматриваемая в этом разделе группа фракталов, по существу,
является «визитной карточкой» фрактальной геометрии. Алгебраические фракталы или фракталы с временным порогом получают с
помощью нелинейных процессов в n-мерных пространствах. Наиболее изучены в настоящее время двумерные процессы. Поскольку
в данном случае нелинейный итерационный процесс интерпретируется как дискретная динамическая система, то используют и соответствующую терминологию теории этих систем: фазовый портрет, установившийся процесс, аттрактор и т. д.
Известно, что нелинейные динамические системы обладают несколькими устойчивыми состояниями. То состояние, в котором
оказалась динамическая система после некоторого числа итераций, зависит от ее начального состояния. Поэтому каждое устойчивое состояние (или как говорят – аттрактор) обладает некоторой
областью начальных состояний, из которых система обязательно
попадет в рассматриваемые конечные состояния. Таким образом,
фазовое пространство системы разбивается на области притяжения аттракторов. Если фазовым является двумерное пространство,
то окрашивая области притяжения различными цветами, можно
получить цветовой фазовый портрет этой системы (итерационного процесса1). Другими словами, фрактальные области в этом случае изображаются цветными точками на комплексной плоскости.
Причем цвет точки соответствует времени, которое требуется на
то, чтобы орбита (путь) данной точки перешла определенную изначальную границу. Меняя алгоритм выбора цвета, можно получить
сложные фрактальные картины с причудливыми многоцветными
узорами. Наиболее известными фракталами данного типа являются множества Жюлиа и Мандельброта.
Определимся сначала с множеством Жюлиа. Возьмем произвольное комплексное число c. Затем для любого комплексного числа k рассмотрим числовую последовательность {Zn (k)}, такую, что
Z0 = k; Zi+1 = Zi2 + c, где i – номер положения точки. Спрашивается, где будет находиться точка k после достаточно большого числа шагов n? Ответ очевиден только в одном случае – при c = 0: все
точки k, лежащие внутри единичного круга, стремятся к точке 0,
1 Итерационный процесс – числовая последовательность {x }n≥0, полученная по
n
правилу xn+1 = f(xn) при заданном x0
52
точки, изначально находящиеся вне единичного круга, стремятся
к бесконечности, а лежащие на окружности – движутся по ней в
хаотическом порядке. Если заданное значение c отлично от нуля,
то граница между областями притяжения к конечным точкам и к
бесконечности становится сильно изрезанной. Эта граница и есть
множество Жюлиа (J). Наполненным множеством Жюлиа называют множество точек, для которых последовательность {Zn (k)} не
уходит в бесконечность, а остается ограниченной по модулю. Если
наполненное множество Жюлиа не имеет внутренних точек, то оно
совпадает со своей границей и множество Жюлиа совпадает со своим наполненным множеством Жюлиа. Понятно, что вид множества Жюлиа зависит от выбора параметра c. Поэкспериментировав
с выбором c, можно получить невероятное разнообразие множеств
Жюлиа.
Все множества Жюлиа либо состоят из несвязных между собой
кусков, либо представляют собой цельное множество. Такие цельные множества называются связными, если любые две их точки
можно соединить линией, не выходящей из данного множества. На
рис. 1.39 представлены связное (рис. 1.39, а), наполненное связное
(рис. 1.39, б) и несвязное (рис. 1.39, в) множества Жюлиа. Свойство
связности части множеств Жюлиа приводит к определению множества Мандельброта.
Множеством Мандельброта М называется множество тех значений параметра с, для которых соответствующее множество Жюлиа
связно.
Как получить изображение множества Мандельброта? Для этого
берем любое множество Жюлиа J, и комплексное число c, которое
его породило. Если J содержится в M (т. е. связно), то изобразим
точку с черным цветом на комплексной плоскости, в противном
случае – белым цветом. В этом случае, однако, придется для каждого числа c строить множество Жюлиа и определять, связно ли
а)
б)
в)
Рис. 1.39
53
оно. Существует, к счастью, более простой алгоритм построения
множества Мандельброта (см., например, http://algolist.manual.
ru/graphics/mandelbrot.php), который очень похож на построение
множеств Жюлиа.
Для любого комплексного числа k рассмотрим числовую последовательность {Zn (k)}, такую, что Z0 = 0; Zi+1 = Zi2 + c, и выясним, сходится ли она к нулю. В данном случае c уже не является
константой. Любой точке комплексной плоскости c присваиваем
значение k и выполняем достаточно большое число итераций. Алгоритм выглядит следующим образом:
For each point k on the complex plane do:
let x=0.
repeat infinite times:
x=x^2+k.
end repeat
if x goes to infinity,
k is not
in the set. Color is white.
else
k is in the set. Color is black.
Совершенно ясно, что бесконечные циклы практически не реализуемы. Поэтому на практике в качестве границ циклов выбирают достаточно большое (но все же ограниченное) число. Чем большее число в качестве границы мы выберем, тем более качественное
изображение множества Мандельброта получим. Как показывает
практика, граница в 4000 итераций дает довольно хороший результат. Но реализация цикла в 4000 итераций для каждого пикселя изображения весьма затратна. К счастью, результаты работы
математиков в этой области показали, что, если в любой конкретный момент вычислений для числа k расстояние от Zi(k) до начала
координат больше 2, то можно принять, что последовательность
{Zn(k)} уйдет в бесконечность. С учетом сказанного алгоритм будет
выглядеть так:
For each point k in the complex plane do:
let x=0.
repeat 4000 times
let x=x^2+k
if x^2 > 4 then Color is white
Break.
end repeat
if we reached 4000 then Color is black.
54
Приведенный алгоритм дает черно-белое изображение множества Мандельброта (рис. 1.40, а). Необходимо понимать, что этот
алгоритм дает лишь приближение к множеству Мандельброта.
Множеству Мандельброта принадлежат точки, которые в течение
бесконечного числа итераций не уходят в бесконечность (точки
имеющие черный цвет). Точки принадлежащие границе множества (именно там возникают сложные структуры) уходят в бесконечность за конечное число итераций, а точки, лежащие за пределами множества, уходят в бесконечность через несколько итераций
(белый фон).
Для того чтобы изобразить множество Мандельброта в цвете,
обычно поступают следующим образом (рис. 1.40, б). Если точка
принадлежит множеству Мандельброта, то ее цвет – черный. Выбор цвета для точек, не принадлежащим множеству Мандельброта,
зависит от того, как быстро {Zn(k)} стремится к бесконечности (на
какой итерации мы ее исключаем из рассмотрения). И последнее
замечание: обычно, все множество Мандельброта расположено в
интервалах от – 2 до 0,5 по действительной оси и от – 1,25 до 1,25
по мнимой оси. Следовательно, программа не должна тестировать
точки далеко за пределами этой области.
Еще более красочные фантастические картины получаются при
построении гиперкомплексных множеств Жюлиа и Мандельброта
(рис. 1.41).
В этом случае вместо пространства обычных комплексных чисел
используется четырехмерное пространство гиперкомплексных чисел (кватернионов). Кватернион можно определить, как формальную сумму q = r + ai + bj + ck, где r, a, b, c – четвёрка вещественных
чисел; i, j, k – «мнимые единицы» со следующими свойствами:
i2 = j2 = k2 = –1; ij = k; jk = i; ki = j ; ji = -k; kj = -i; ik = -j .
Модуль кватерниона вычисляется подобно модулю комплексного числа:
q = r 2 + a 2 + b 2 + c 2.
Таким образом, гиперкомплексные множества Жюлиа и Мандельброта – объекты, определенные в четырехмерном пространстве. Для того чтобы увидеть эти объекты на экране, необходимо
выполнить проекцию из четырехмерного пространства в трехмерное, а затем в двумерное (на экран монитора). Обычно эти изо55
бражения строятся путем фиксации значений одной из координат
(проекция), с последующим вычислением значений в узлах трехмерной решетки и получением изображения методом трассировки
лучей (подробней с указанным алгоритмом можно ознакомиться,
например, в [11]).
Системы итерируемых функций
Метод «Системы Итерируемых Функций» (Iterated Functions
System – IFS) появился в середине 80-х гг. прошлого века как простое и достаточно эффективное средство получения фрактальных
структур.
IFS представляет собой систему функций из некоторого фиксированного класса, отображающих одно многомерное множество в
другое. Наиболее простая IFS состоит из аффинных преобразований плоскости:
X′ = A.X + B.Y + C;
Y′ = D.X + E.Y + F.
Для построения IFS применяют кроме аффинных и другие классы простых геометрических преобразований, которые задаются небольшим числом параметров. Например, проективные:
X′ = (A1.X + B1.Y + C1)/(D1.X + E1.Y + F1);
Y′ = (A2.X + B2.Y + C2)/(D2.X + E2.Y + F2);
или квадратичные:
X′ = A1.X2 + B1.X.Y + C1.Y2 + D1.X + E1.Y + F1;
Y′ = A2.X2 + B2.X.Y + C2.Y2 + D2.X + E2.Y + F2;
преобразования на плоскости.
В качестве примера использования IFS для построения фрактальных структур, рассмотрим кривую Коха и «дракона» ХартераХейтуэя. Выделим в этих структурах подобные части и для каждой
E из них вычислим коэффициенты
B
аффинного преобразования.
Построим IFS для «дракона»
Хартера-Хейтуэя. Для этого рассмотрим первое поколение этого
фрактала (рис. 1.42). Обозначим
A
D
C точки получившейся ломаной A,
B, C. По правилам построения у
Рис. 1.42
56
этого фрактала имеются две части, подобные целому (на рис. 1.42
это ломаные ADB и BEC). Зная координаты концов этих отрезков,
можно вычислить коэффициенты двух аффинных преобразований,
переводящих ломаную ABC в ADB и BEC:
X′ = – 0.5.X – 0.5.Y + 490
Y′ = 0.5.X – 0.5.Y + 120
X′ = 0.5.X – 0.5.Y + 340
Y′ = 0.5.X + 0.5.Y – 110
Задавшись начальной стартовой точкой (например, X = 0 Y = 0)
и итерационно действуя на нее этой IFS, после десятой итерации на
экране получим фрактальную структуру, показанную на рис. 1.27.
Кодом (сжатым описанием) данного фрактала является набор коэффициентов двух аффинных преобразований.
Аналогично можно построить
C
IFS для кривой Коха. Нетрудно видеть, что эта кривая имеет четыре
части, подобные целой кривой. Для
нахождения IFS опять рассмотрим A
B
D
E
первое поколение этого фрактала
(рис. 1.43). Нетрудно заметить, что
Рис. 1.43
для построения указанной кривой
нам потребуется следующий набор аффинных преобразований:
X′ = 0.333.X + 13.333
Y′ = 0.333.Y + 200
X′ = 0.333.X + 413.333
Y′ = 0.333.Y + 200
X′ = 0.167.X + 0.289.Y + 130
Y′ = –0.289.X + 0.167.Y + 256
X′ = 0.167.X – 0.289.Y + 403
Y′ = 0.289.X + 0.167.Y + 71
Результат применения этого аффинного преобразования после
десятой итерации можно увидеть на рис. 1.44.
Наибольший интерес для моделирования природных объектов
в компьютерной графике представляет рандомизированный алгоритм реализации IFS. Суть его состоит в следующем. Во-первых,
на каждом шаге данного алгоритма из некоторого множества наперед заданных аффинных преобразований случайным образом ис57
Рис. 1.44
пользуется только одно. Ну, например, пусть изначально заданы
следующие аффинные преобразования:
X′ = a1.X + b1.Y + e1
Y′ = c1.X + d1.Y + f1
X′ = a2.X + b2.Y + e2
Y′ = c2.X + d2.Y + f2
.
.
.
.
X′ = an X + bn.Y + en
Y′ = cn.X + dn.Y + fn
Тогда имеет смысл производить выбор на каждом шаге алгоритма i-е преобразование в соответствии с вероятностями, пропорциональными детерминантам соответствующих матриц аффинных
éa b i ù
ú . Для этого определим веса p1, р2, … pn
преобразований Ai = ê i
ê c i d iú
ë
û
следующим образом:
pj =
| det( Aj ) |
n
, j = 1, …, n.
å det( Ai )
i=1
Нетрудно заметить, что p1 + р2 + … + pn = 1, т. е. определенные
таким образом веса являются, по сути, вероятностями. Итак, в рассматриваемом рандомизированном алгоритме i-е преобразование
выбирается с вероятностью pi. Для этой цели в приведенном далее
алгоритме используется подпрограмма Pick, которая в качестве
входного параметра использует вектор P = [p1 р2 … pn], а возвращает одно из чисел 1, 2, …, n, причем число i возвращается с вероятностью рi. В приведенном далее алгоритме все вычисления и вывод на
экран производятся в мировых координатах:
58
Входные данные:
C – аффинные коэффициенты
n – количество аффинных отображений
P = [p1 р2 … pn] – вероятности
a, b, c, d – координаты окна [a, b]x [c, d]
(x0, y0) – начальная точка (выбирается произвольно)
Iter – количество итераций (порядка нескольких тысяч)
Выходные данные:
Изображение фрактала.
Инициализация окна вывода [a, b]x [c, d]
For j = 1 to 100
k = Pick(P)
x = [C(k,1)x0 + C(k,2)y0 + C(k,5)
y = [C(k,3)x0 + C(k,4)y0 + C(k,6)
x0 = x
y0 = y
end for
For j = 1 to Iter
k = Pick(P)
x = [C(k,1)x0 + C(k,2)y0 + C(k,5)
y = [C(k,3)x0 + C(k,4)y0 + C(k,6)
отобразить точку (x, y)
x0 = x
y0 = y
end for
Используя системы итерируемых функций, можно получать
более сложные структуры, по реалистичности приближающиеся
к природным объектам. Например, если воспользоваться механизмом рандомизированного IFS, задав набор аффинных преобразований следующим образом (см. также [7]):
X′ = 0.195.X – 0.488.Y + 0.34
Y′ = 0.433.X + 0.4431.Y + 0.2452
X′ = 0.462.X + 0.414.Y – 0.252
Y′ = 0.361.X + 0.2511.Y + 0.5692
X′ = – 0.058.X – 0.07.Y + 0.453
Y′ = – 0.11.X + 0.5976.Y + 0.0969
X′ = – 0.035.X + 0.07.Y – 0.469
Y′ = – 0.022.X + 0.4884.Y + 0.5069
59
X′ = – 0.637.X
Y′ = 0.501.X + 0.8562.Y + 0.2513,
то после порядка 2000 итераций получим такой вот корявый…, ну,
скажем, саксаул (рис. 1.45). Если же вам потребуется быстро получить изображение дерева, распространенного в более северной
климатической зоне (скажем, елочки), то можно воспользоваться
следующим набором аффинных преобразований:
X′ = 0.29.X + 0.4.Y – 0.4
Y′ = 0.3.X + 0.28.Y + 0.44
X′ = 0.33.X – 0.34.Y + 0.39
Y′ = 0.4.X + 0.41.Y
X′ = 0.42.X
Y′ = 0.63.X + 0.29.Y + 0.36
X′ = 0.61.X
Y′ = 0.61.X + 0.19.Y + 0.23
X′ = 0.01.X
Y′ = 0.29.X + 0.5.Y + 0.13
И после порядка 2000 итераций вы сможете получить примерно
такое изображение (рис. 1.46).
В заключение данного раздела приведены примеры моделирования виртуальных природных ландшафтов с помощью свободно распространяемой программы Fractal Explorer (http://www.angelfire.
com/art/fe/index.html, рис. 1.47).
60
Рис. 1.38
а)
б)
Рис. 1.40
Рис. 1.41
61
Рис. 1.45
Рис. 1.46
Рис. 1.47
62
1.2. Модельные преобразования
1.2.1. Преобразования изображений
Графическая система должна давать возможность различных
преобразований изображений. Например, увеличение масштаба
необходимо для лучшего представления мелких деталей, а уменьшение размеров изображения полезно для рассмотрения более
значительной части изображения. Сдвиг части изображения позволяет рассмотреть расположенные за этой частью детали, а поворот, в свою очередь, позволяет рассмотреть предмет с различных сторон.
Далее рассмотрим следующие элементарные преобразования:
сдвиг, поворот, масштабирование и перспективу (для сцен в трехмерном пространстве). Все эти геометрические преобразования совершенно не затрагивают прежнюю структуру изображения и, следовательно, тип примитива не влияет на выполнение геометрического преобразования. Например, для отрезка прямой достаточно
применить преобразование к концевым точкам отрезка и провести
прямую между двумя преобразованными точками.
В начале данного раздела нелишне будет напомнить некоторые
основные положения аналитической геометрии, которые наиболее
часто используются в рассматриваемых далее алгоритмах графического конвейера.
Итак, очень коротко…
Точка в двумерном пространстве задается парой координат M(x,
y) или радиус вектором r = [x y]. Пусть заданы две точки на плоскости M1(x1,y1) и M2(x2,y2), тогда выражение вида Ax + By + C = 0 является уравнением прямой, проходящей через эти две точки, где
A = (y1 – y2), B = (x2 – x1), C = (x1 – x2)y1 + (y2 – y1)x1.
Точку пересечения двух прямых можно определить, если заданы уравнения этих прямых
Ax + By + C = 0,
A′x + B′y + C′ = 0.
A B
= 0, то
A ¢ B¢
прямые параллельны. Если A/A′ = B/B′ = C/C′, то прямые совпада-
Если определитель этой системы уравнений ∆ =
63
ют. В остальных случаях имеется единственная точка пересечения
этих прямых с координатами (x′,y′):
x′ = (B.C′ – B′.C)/(A.B′ – A′.B),
y′ = (C.A′ – C′.A)/(A.B′ – A′.B).
Пусть заданы две прямые G и G′ в двумерном пространстве. На
прямых заданы точки P1, P2 и P1′, P2′. Отрезок P1P2 лежит на
прямой G, P1(x1,y1), P2(x2,y2); отрезок P1′P2′ лежит на прямой G′,
P1′(x1′,y1′),P2′(x2′,y2′). Пусть G и G′ пересекаются в точке I (x,y).
Тогда отрезки P1P2 и P1′P2′ пересекаются в точке I, если истинно
следующее логическое высказывание:
(max[min(x1,x2),min(x1′,x2′)] ≤ x ≤min[max(x1,x2),max(x1′,x2′)]) &
(max[min(y1,y2),min(y1′,y2′)] ≤ y ≤ min[max(y1,y2),max(y1′,y2′)]).
Смысл данного логического выражения очевиден. Действительно, отрезки будут пересекаться в точке I(x,y) тогда и только тогда,
когда по оси X у обоих отрезков найY
G
P
дутся точки, лежащие левее точки x,
1
P1¢
I
и одновременно у обоих отрезков найy
дутся точки, лежащие правее точки
P2
P2¢
x. Соответственно, по оси Y у обоих
G¢
отрезков найдутся точки, лежащие
X
ниже точки y, и одновременно у обоx
их отрезков найдутся точки, лежаРис. 1.48
щие выше точки y (рис. 1.48).
Точка двумерного пространства в однородных координатах
определяется вектором-строкой p = [wx wy w]; прямая в двумерном
пространстве представляется вектором-столбцом
éaù
ê ú
L = êê b úú .
êcú
ë û
Уравнение прямой в этом случае имеет вид pL = 0. Если скалярное произведение pL = D и D = 0, то точка p лежит на прямой L.
В противном случае знак D указывает, с какой стороны от прямой
лежит точка. Расстояние от точки до прямой есть величина
S=
64
ax + by + c
a2 + b2
.
Прямая Lpq, проходящая через точки p = [p1 p2 p3] и q = [q1 q2 q3],
представляется вектором-столбцом
éq3 p2 - q2 p3 ù
ê
ú
L pq = êê q1 p3 - q3 p1 úú .
êq p -q p ú
ë 2 1 1 2û
Точка пересечения двух прямых L и L′ определяется вектором
pLL′ = [(c′b – b′c)(ca′ – ac′)(b′a – a′b)].
В трехмерном пространстве в однородных координатах точка
описывается вектором-строкой p = [wx wy wz w]. Плоскость представляется вектором-столбцом
éaù
ê ú
êbú
P = êê úú .
êcú
êd ú
êë úû
Прямая, проходящая через точки M1(x1,y1,z1) и M2 (x2,y2,z2) в
трехмерном пространстве, задается уравнением: (x – x1)/(x2 – x1) =
(y – y1)/(y2 – y1) = (z – z1)/(z2 – z1).
Пусть заданы три неколлинеарные (не лежащие на одной прямой) точки в трехмерном пространстве M0 (x0,y0,z0), M1 (x1,y1,z1) и
M2 (x2,y2,z2). Эти точки не лежат на одной прямой, если матрица
é x1
ê
ê x2
M = êê
ê x3
ê0
ëê
y1
y2
y3
0
z1
z2
z3
0
1ù
ú
1ú
ú
1úú
1úûú
имеет обратную матрицу.
Для получения уравнения плоскости по трем неколлинеарным
точкам необходимо приравнять нулю следующий определитель
третьего порядка:
x - x0
x1 - x0
x2 - x0
-(y - y0 )
y - y0
y1 - y0
y2 - y0
x1 - x0
x - x0
z - z0
y1 - y0
z1 - z0 = (x - x0 )
y2 - y0
z2 - z0
z1 - z0
x1 - x0
+ (z - z0 )
z2 - z0
x2 - x0
z1 - z0
z2 - z0
y1 - y0
= 0.
y2 - y0
65
После упрощения уравнение примет вид A.x + B.y + C.z + D = 0, где
A = (y1 – y0)(z2 – z0) – (z1 – z0)(y2 – y0);
B = – [(x1 – x0)(z2 – z0) – (z1 – z0)(x2 – x0)];
C = (x1 – x0) (y2– y0) – (y1 – y0)(x2 – x0);
D = [– x0[(y1 – y0)(z2 – z0) – (z1 – z0)(y2 – y0)] + y0[(x1 – x0)(z2 – z0) –
– (z1 – z0)(x2 – x0)] – z0[(x1 – x0)(y2 – y0) – (y1 – y0)(x2 – x0)]].
Уравнение плоскости (условие того, что точка p лежит в плоскости P) может быть записано в виде p·P = 0. Расстояние от p до P есть
величина
S=
ax + by + cz + d
2
2
a +b +c
2
.
Уравнение плоскости, проходящей через точку, заданную в декартовых координатах M0(x0, y0, z0), перпендикулярно заданному
вектору N = [A B C]:
A(x – x0) + B(y – y0) + С(z – z0) = 0 (рис. 1.49).
Уравнение нормали к плоскости, заданной уравнением Ax + By + Cz + D = 0, в
точке M0(x0, y0, z0) имеет вид (x – x0)/A =
= (y – y0)/B = (z – z0)/C. Здесь A, B и C –
коэффициенты уравнения плоскости,
P
они же – направляющие коэффициенты
нормали. Таким образом, направляющий
Mo (xo , yo , zo )
вектор нормали: N = (А B C).
Пусть заданы уравнения двух плоскоРис. 1.49
стей:
a1x + b1y + c1z + d1 = 0,
a2x + b2y + c2z + d2 = 0.
a
b
c
d
Эти плоскости параллельны, если 1 = 1 = 1 ¹ 1 . Плоскости
a2 b2 c2 d2
a
b
c
d
совпадают, если 1 = 1 = 1 = 1 . В других случаях плоскости пеa2 b2 c2 d2
ресекаются вдоль прямой, коэффициенты направляющего вектора
которой (вектора, лежащего на этой прямой) можно найти, выполнив векторное произведение
N = ( A , B, C )
[a1
66
b1
c1 ]´[a2
b2
æ b1
c2 ]= ççç
çè b2
c1
c2
c1
c2
a1
a2
a1
a2
b1 ÷ö
÷ = (l ¢ m ¢ n ¢).
b2 ÷÷ø
Косинус угла между этими двумя прямыми L = (l m n) и L′ =
= (l′ m′ n′) определяется из выражения
ll ¢ + mm ¢ + nn ¢
cos(α) =
.
2
2
l + m + n2 l ¢2 + m ¢2 + n ¢2
Пусть задана плоскость, проходящая через точки Pi(xi,yi,zi),
Pj(xj,yj,zj) и Pk(xk,yk,zk), причем эти точки неколлинеарны и удовлетворяют уравнению
A.x + B.y + C.z + D = 0.
И пусть задана прямая, проходящая через точки P1 (x1,y1,z1) и
P2 (x2,y2,z2). Прямая может быть представлена уравнением
(x – x1)/cos(a) = (y – y1)/cos(b) = (z – z1)/cos(c),
где cos(a) = (x2 – x1)/d, cos(b) = (y2 – y1)/d, cos(c) = (z2 – z1)/d,
d = (x2 - x1 )2 + (y2 - y1 )2 + (z2 - z1 )2.
Тогда, если A.cos(a) + B.cos(b) + C.cos(c) = 0, то прямая параллельна плоскости; если A.cos(a) + B.cos(b) + C.cos(c) = 0 и A.x1 + B.y1 +
+ C.z1 + D = 0, то прямая лежит в плоскости.
В остальных случаях имеется точка пересечения x′ = x1 – tcos(a),
y′ = y1 – tcos(b), z′ = z1 – tcos(c), где t = (Ax1 + By1 + Cz1 + + D)/
/(Acos(a) + Bcos(b) + Ccos(c)).
Три плоскости P1, P2, P3 пересекаются в точке p, когда p.P1 =
.
p P2 = p.P3 = 0.
é a1 ù
ê ú
êb ú
Пусть P1 = êê 1 úú ,
ê c1 ú
êd ú
ëê 1 ûú
é a2 ù
ê ú
ê b2 ú
P2 = êê úú ,
ê c2 ú
êd ú
ëê 2 ûú
é a3 ù
ê ú
ê b3 ú
P3 = êê úú .
ê c3 ú
êd ú
ëê 3 ûú
é a1 a2 a3 0ù
ê
ú
ê b1 b2 b3 0ú
ê
ú.
Обозначим M = ê
ú
c
c
c
0
1
2
3
ê
ú
ê d d d 1ú
ëê 1 2 3 ûú
Тогда точка пересечения этих трех плоскостей (точка p) задается
нижней строкой обратной матрицы M–1. Если M не имеет обратной
матрицы, то три эти плоскости не пересекаются в одной точке.
Пусть заданы два выпуклых многоугольника в плоскости изображения (это могут быть проекции двух граней трехмерных объ67
ектов). Каждый многоугольник определяется множеством своих
вершин, т. е., если мы обозначим многоугольники, как F1 и F2, то
F1 = {P11, P12, ..., P1m} и F2 = {P21, P22, ..., P2n}, где Pij(xij, yij) – j-я
вершина i-го многоугольника. F1 и F2 не перекрывают друг друга в
плоскости изображения, если справедливо:
max(x1j) < min(x2k) или max(x2k) < min(x1j) или max(y1j) < min(y2k)
или max(y2k) < min(y1j) для всех j от 1 до m, k от 1 до n.
На практике важно не просто установить факт перекрытия двух
многоугольников, но и определить точки пересечения этих двух
граней. Эти точки пересечения можно найти с помощью формул,
представленных ранее.
Теперь рассмотрим тест принадлежности, который применяется
к объектам в экранной плоскости и проверяет, лежит ли точка P
внутри многоугольника F или нет. Рассмотрим две процедуры, позволяющие выполнить эту проверку.
1. Вычисление суммы углов. Пусть F = {P1, ..., Pn} – многоугольник в плоскости экрана с вершинами Pi(xi, yi), i = 1, ..., n и
P1 = Pn; Pt – точка, для которой необходимо проверить принадлежит ли она F; PtPi – отрезок, соединяющий Pt и Pi. Точка Pt соединяется отрезками прямой со всеми вершинами многоугольника.
Обозначим ai – угол между PtPi и PtPi+1. Тогда точка Pt лежит вне
F, если
å ai = 2π, и внутри F, если å ai = 0.
i
i
Графическая иллюстрация этого метода приведена на рис. 1.50,
a (при суммировании углов необходимо учитывать не только их величину, но и направление – знак).
2. Подсчет числа пересечений. Пусть R – луч, начинающийся в
точке Pt и проходящий через F, но не содержащий ни одной вершины многоугольника. Тогда Pt внутри F, если число пересечений
a)
p1 = p5
a1
p2
p1=p5
a2
pt
a 4 a3
p3
R
a1
pt a4
p4
б)
p2
a2
a3
R
p4
Рис. 1.50
68
pt
p3
pt
R со сторонами F нечетно,и вне F,
P¢
если число пересечений четно (см.
рис. 1.50, б). Данный тест примеPt
ним к любым многоугольникам (не
обязательно выпуклым).
P
Теперь рассмотрим процедуры,
получившие название «тесты глуO
бины». Эти тесты применяется к
двум перекрывающимся графичеdp
ским элементам и определяют, каdt
кой из элементов заслоняет второй.
Сравниваемыми элементами могут
Рис. 1.51
быть точка и грань или две грани.
Под глубиной точки будем понимать расстояние между элементом
и экранной плоскостью или между элементом и точкой наблюдения. Рассмотрим три теста глубины.
1. Сравнивается глубина грани (F) и точки (Pt) с целью определить, заслоняет ли грань точку или нет (рис. 1.51). Для этого
определяется точка, в которой грань пересекается с линией визирования, т. е. линией, проходящей через проверяемую точку Pt и
точку наблюдения O. Затем вычисляется расстояние от точки наблюдения до проверяемой точки (dt) и точки пересечения P (dp).
Если dt > dp, то точка закрывается гранью; в противном случае –
не закрывается. Поскольку в данной процедуре точка наблюдения
должна находиться не в бесконечности (чтобы была возможность
сравнить расстояния dt и dp), то этот тест можно использовать для
центральной проекции и нельзя – для ортогональной. Если линия
визирования не протыкает грань, то проверяемая точка гранью не
закрыта (например, точка P′).
2. Приоритетный тест. Этот тест применим для параллельной проекции. Проверяемыми элементами являются либо две
грани, либо точка и грань. Рассмотрим сначала случай двух граней F1 и F2. Пусть Pr(F1) и Pr(F2) – проекции граней на экранную
плоскость, и пусть p12 – некоторая точка, которая принадлежит
пересечению Pr(F1) и Pr(F2) (например точка пересечения некоторого ребра Pr(F1) с ребром Pr(F2)). Определим точки p1 в F1 и p2
в F2, которые проецируются в p12. Для нахождения p1(xp,yp,z1) и
p2(xp,yp,z2) необходимо координаты xp, yp точки p12 подставить в
уравнения плоскостей, содержащих грани F1 и F2, и разрешить эти
уравнения относительно координаты z. Полученные значения z1 и
69
F1
F1
Рис. 1.52
z2 сравниваются и определяется относительный приоритет F1 и F2.
Если z1 = z2, то надо найти другую точку, принадлежащую пересечению Pr(F1) с Pr(F2), и для которой z1 не равно z2. С помощью
подобного теста определяется монотонное упорядочение граней. В
тесте точка/поверхность строится уравнение плоскости, содержащей грань, и в него подставляются x и y координаты проверяемой
точки. Это уравнение разрешается относительно переменной z и полученное значение сравнивается со значением z-координаты проверяемой точки, устанавливая тем самым относительный приоритет
между точкой и гранью. Данный тест усложняется, если допускается существование проникающих граней и циклического перекрытия (рис. 1.52).
В этом случае результат теста зависит от местонахождения проверяемой точки. Для разрешения этой неоднозначности необходимо разделить грань F1 вдоль штриховой линии на 2 части и выполнить тест глубины отдельно для каждой части (см. рис. 1.52).
3. Самый простой тест глубины. Он применяется в алгоритмах
сканирующей прямой, один из которых будет рассмотрен дальше.
На отрезках сканирующей прямой, внутри которых никакие два
ребра проекций не пересекаются со сканирующей прямой и никакие две грани не проникают друг в друга в объектном пространстве
(такой отрезок называют пробным интервалом), видимость может быть определена простым сравнением z-координат сегментов
проекций на пробном интервале. Видим тот сегмент, наименьшая
z-координата которого в пробном интервале больше или равна наибольшему значению z-координат всех других сегментов. Видимый
сегмент образует полоску видимой проекции грани (подробнее об
этом тесте см. в описании алгоритма сканирующей прямой Уоткинса).
70
И, наконец, рассмотрим проY
цедуру, носящую название «тест
видимости» (рис. 1.53). Этот тест
может применяться только к отF2
дельным геометрическим телам.
F1
α > 90 ο
Он определяет, является ли грань
тела видимой или нет. Если имеL
N
ется несколько трехмерных объекO
N
X
тов, которые могут заслонять друг
друга, то данный тест определяет Z α < 90ο
только заведомо невидимые грани,
Рис. 1.53
т. е. скрытые телом, которому они
принадлежат. В этом тесте сначала определяется нормаль N к грани, затем строится линия визирования L, проходящая через точку
наблюдения O и основание нормали, и определяется угол α между
N и L. Грань потенциально видима (потенциально в том смысле,
что грань, возможно, будет закрыта от наблюдателя другим телом),
если угол α меньше или равен 90° (на рис. грань F1), и невидима,
если угол α > 90° (грань F2). Поскольку критическим углом является угол 90°, то достаточно вычислить скалярное произведение
LN = |L||N|cos(α) и проверить его знак, так как cos(α) меняет знак
при α = 90°. Таким образом, если тело выпукло и одно, то этот тест
определяет видимость всех его граней. Если тело не одно, то этот
тест можно применять для определения заведомо невидимых граней (тех, что заслоняются от наблюдателя собственным телом).
К потенциально видимым граням необходимо применять дополнительные тесты, с помощью которых можно обнаружить взаимное
затенение граней, принадлежащих различным телам или одному
невыпуклому телу (подробнее эти тесты будут рассмотрены далее).
Вернемся теперь к элементарным преобразованиям и рассмотрим операции сдвига, поворота, масштабирования и перспективы
(для сцен в трехмерном пространстве).
Операция поворота
Сначала рассмотрим поворот системы координат XY в декартовой плоскости относительно центра вращения, совпадающего с центром координат, в математически положительном направлении на
угол α, т. е. против часовой стрелки (рис. 1.54). В результате этого
преобразования, примененного к точке P с координатами (x,y), по71
Y
Y
y
α
¢
xsin(α)
y¢
α
P
α
x¢
X¢
лучим точку с координатами (x′,y′),
которые вычисляются исходя из
следующих соотношений:
x′ = xcos(α) + ysin(a)
y′ = – xsin(a) + ycos(a).
ycos(α)
Такой поворот в XY-плоскости
можно представить как частный
X
0
случай поворота в трехмерном проysin (α) xcos (α)
странстве, а именно как плоский
поворот относительно оси Z (ось Z
Рис. 1.54
проходит через центр вращения
перпендикулярно плоскости XY). Следовательно, z′ = z. Таким образом, можно записать 
x′ = xcos(a) + ysin(a)
y′ = – xsin(a) + ycos(a)
z′ = x·0 + y·0 + z·1,
α
x
или в матричном виде
é cos(α) -sin(α) 0ù
ê
ú
ê
ú
é
ù
ë x ¢ y ¢ z ¢û = [x y z ]ê sin(a) cos(α) 0ú . ê 0
ú
0
1û
ë
(1.11)
Аналогично, можно получить соотношение для новых координат точки, полученных в результате поворота относительно оси Y
на угол β:
é cos(β) 0 -sin(β)ù
ê
ú
ê
é
ù
(1.12)
1
0 úú . ë x ¢ y ¢ z ¢û = [x y z ]ê 0
ê sin(β) 0 cos(β) ú
ë
û
или в результате поворота относительно оси X на угол γ:
é1
0
0 ù
ê
ú
ê
ú
é
ù
ë x ¢ y ¢ z ¢û = [x y z ]ê0 cos(γ ) sin(γ ) ú . ê0 -sin(γ ) cos(γ )ú
ë
û
(1.13)
Преобразование общего поворота в трехмерном пространстве относительно трех ортогональных осей с центром вращения, совпадающим с началом координат, можно получить как суперпозицию
трех плоских поворотов, т. е. с помощью перемножения трех ма72
триц (1.11 – 1.13). Поскольку матричное умножение не является
коммутативной операцией, необходимо задать порядок выполнения поворотов.
Обозначим матрицы (1.11 – 1.13) через Rz(a), Ry(b) и Rx(g). Пусть
сначала необходимо осуществить поворот относительно оси X на
угол a, затем относительно Y на угол b и, наконец, относительно
Z на угол g. Тогда координаты точки после общего поворота будут
следующие:
[x′ y′ z′] = [x y z] Rx(g)Ry(b)Rz(a).
Чтобы осуществить обратное преобразование, т. е. от точки (x′ y′
z′) вернуться к точке (x y z), надо осуществить повороты относительно осей в обратном порядке, учитывая, что значения соответствующих углов должны иметь противоположный знак. Таким образом,
для функции поворота R(g,b,a) = Rx(g)Ry(b)Rz(a) имеется обратная
функция R –1 (g,b,a) = Rz(– a)Ry(– b)Rx(– g), которая определяет
преобразование, аннулирующее первоначальный поворот.
Операция сдвига
Сдвиг точки производится путем добавления к каждой координате точки положительной или отрицательной константы: x′ = x + Tx,
y′ = y + Ty, z′ = z + Tz, где Tx, Ty и Tz – величины сдвига по осям
X, Y и Z соответственно. Записать данные выражения в матричном
виде, используя для обозначения точек обычные декартовы координаты, весьма затруднительно, а точнее – невозможно. Матричное же преобразование понадобится нам при объединении элементарных графических преобразований в общее аффинное преобразование. Выход здесь находится за счет использования вместо декартовых однородных координат.
В качестве однородных координат реально существующей
точки (x,y,z) трехмерного пространства определяют четверку
(r,s,t,u). Соотношение между однородными и декартовыми координатами следующие: x = r/u, y = s/u, z = t/u, u ¹ 0. Поскольку
единственное ограничение u ¹ 0, то для сокращения вычислений
проще всего задать u = 1. Таким образом, любая точка трехмерного пространства, представленная в однородных координатах,
есть четырехкомпонентный вектор. При помощи четверок однородных координат и матриц четвертого порядка можно описать
любое аффинное преобразование в трехмерном пространстве. Так,
73
перейдя к однородным координатам, легко можно записать операцию сдвига в матричном виде:
é1
0
0 0ù
ê
ú
ê0
1
0 0ú
ê
ú.
¢
¢
¢
[x y z 1] = [x y z 1] ê
0
1 0úú
ê0
êTx Ty Tz 1ú
ëê
ûú
Переход от однородных координат к обычным декартовым в
данном случае осуществляется простым отбрасыванием четвертой
компоненты результирующего вектора.
Операция масштабирования
Преобразование масштабирования можно выполнить с помощью операции:
é Sx 0
0ù
ê
ú
[x ¢ y ¢ z ¢] = [x y z] êê 0 Sy 0 úú ,
ê0
0 Szúû
ë
где Sx, Sy и Sz – масштабные множители соответственно в X-, Y- и
Z-направлениях. Если изображение необходимо увеличить вдвое, то
Sx = Sy = Sz = 2, если требуется уменьшить в том же соотношении, то, соответственно, Sx = Sy = Sz = 0,5. Следует отметить, что
масштабирование производится относительно начала координат.
Например, при Sx = Sy = 2 результирующее изображение не только увеличится пропорционально в два раза по каждой из осей, но
и сдвинется относительно начала координат (рис. 1.55). Если масштабный множитель меньше 1, то изображаемый объект сжимаY
Y
Исходный
объект
Sx = –1; Sy =1
Результат
масштабирования
X
X
Исходный
объект
Рис. 1.55
74
Sx = Sy = –1
Sx =1; Sy = –1
Рис. 1.56
ется, если больше 1, то, естественно, расширяется. Если Sx, Sy,
Sz различны, то это приводит к искажению изображения за счет
неодинакового изменения размеров по различным осям. Если Sx,
Sy, Sz задавать отрицательными, то можно получать зеркальные
изображения исходного объекта (рис. 1.56).
Перспективное изображение трехмерных объектов
Поскольку экран дисплея – двумерное пространство, то мы
можем изображать только проекции трехмерных объектов. С вычислительной точки зрения преобразования проецирования очень
дороги. Чтобы время, затрачиваемое на построение изображения,
было приемлемым, обычно ограничиваются использованием лишь
центральной проекции, а иногда даже и более простой – параллельной или ортогональной проекции.
 В случае центральной проекции точка зрения или центр проекции находится на одной из главных осей 3-мерной ортогональной
системы координат, чаще всего на оси Z. В этом случае оптическая
ось совпадает с осью Z координатной системы, плоскость экрана
дисплея перпендикулярна оптической оси или параллельна XYплоскости системы координат (рис. 1.57).
Пусть (X,Y) – координаты точки в двумерной системе координат на экранной плоскости; z′ – расстояние от экранной плоскости
до начала пространственной системы координат; z² – расстояние
от точки зрения до начала координат (рис. 1.57). Тогда из подобия
треугольников следует, что
X = ((z″ – z′)/(z″ – z))x, Y = ((z″ – z′)/(z″ – z))y.
Y
(x,y,z)
(X,Y)
Z
0
z¢
P
z ¢¢
X
Рис. 1.57
75
Полагая z′ = 0, т. е. поместив экран в XY-плоскость пространственной системы координат, получим
X = (z″/(z″ – z))x = (1/(1 – (z/z″)))x,
Y = (z″/(z″ – z))y = (1/(1 – (z/z″)))y.
(1.14)
Упрощая, поместим точку P в бесконечность. При этом
1
1. Следовательно, X = x, Y = y. Такая проекция
®
1 - z / z ¢¢ z¢¢®¥
называется ортогональной или параллельной, поскольку при помещении точки наблюдения в бесконечность прямая, соединяющая
исходную точку и точку наблюдения (линия визирования), становится параллельна оси Z.
Недостаток формул (1.14) – нелинейность преобразований, так
как для построения точного перспективного образа надо выполнить
деление на координату глубины каждой точки. Устранить этот недостаток можно, если точки объекта представить в однородных координатах. В этом случае матрица вида
é1 0 0
0 ù
ê
ú
ê0 1 0
0 ú
ê
ú
P=ê
¢¢ú
0
0
0
1
/
z
ê
ú
ê0 0 0
1 úûú
ëê
является линейным преобразованием, отображающим точку объекта в точку проекции (обе эти точки заданы в однородных координатах). Данное утверждение нетрудно проверить, умножив вектор
точки, представленной в однородных координатах, на матрицу P,
а затем поделив первые две компоненты результирующего вектора
на четвертую. Убедиться, что при этом получим те же выражения
(1.14), несложно.
Совмещение элементарных преобразований
Последовательности перечисленных преобразований можно
свести к одному преобразованию с помощью процесса совмещения.
Например, поворот относительно не начала координат, а относительно произвольной точки, можно выполнить как последовательность трех простых преобразований: сдвига, поворота и еще одного
обратного сдвига. Следует помнить, что при совмещении не должен
быть нарушен порядок преобразований.
Пример 1.4. Пусть имеется прямоугольник, заданный вершинами (3,0), (3,2), (6,0), (6,2) (на рис. 1.58. закрашен желтым цве76
том). Необходимо повернуть исходную фигуру на 90 градусов относительно оси Z и сдвинуть по оси X на – 5 единиц. В результате
получим прямоугольник, закрашенный красным цветом. Если же
выполнить преобразования в обратном порядке, то получим прямоугольник, залитый на том же рисунке зеленым цветом.
Основная цель совмещения – представить последовательность преобразований как одно преобразование. Приведенная
последовательность поворота с последующим сдвигом состоит из следующих преобразований: x′ = y; y′ = –x, затем следует x″ = x′ – 5; y″ = y′. Cовместив эти два преобразования, получим x″ = y – 5; y″ = –x. Если же выполнить сначала сдвиг, а затем требуемый поворот, то преобразования примут иной вид:
x″ = y; y″ = 5 – x.
Применение совмещения имеет ряд преимуществ. Его можно
представлять более компактно, чем последовательность нескольких преобразований. Причем, обычно вычисления для совмещенного преобразования можно выполнить при меньшем числе арифметических операций, чем для последовательного выполнения
отдельных преобразований. Правила составления уравнений для
совмещенных преобразований достаточно сложны, но они значительно упрощаются, если для описания преобразований использовать матричные представления.
Пример 1.5. Рассмотрим следующую последовательность преобразований: масштабирование точки в двумерном пространстве при
Sx = Sy = 3 и ее сдвиг на Tx = – 1, Ty = 3. При этом имеем
é 3 0 0ù
ê
ú
ê
ú
é
ù
é
ù
ë x ¢ y ¢ 1û = [x y 1]ê0 3 0ú è ë x ¢¢ y ¢¢ 1û =
ê 0 0 1ú
ë
û
é 1 0 0ù
ê
ú
= ëé x ¢ y ¢ 1ûù êê 0 1 0úú
ê-1 3 1ú
ë
û
или
é 3 0 0ù é 1 0 0ù
é 3 0 0ù
ê
úê
ú
ê
ú
ê
ú
ê
ú
ê
ú
é
ù
ë x ¢¢ y ¢¢ 1û = [x y 1]ê0 3 0ú ê 0 1 0ú = [x y 1]ê 0 3 0ú .
ê0 0 1ú ê-1 3 1ú
ê-1 3 1ú
ë
ûë
û
ë
û
Независимо от количества преобразований всегда можно произвести совмещение таким образом, чтобы одна матрица 3 ×3 пред77
ставляла всю последовательность преобразований для двумерных
объектов. Для трехмерных объектов аналогичная матрица будет
иметь размер 4×4 (см. далее).
Теперь рассмотрим эффективность предложенных процедур.
Для генерации изображения может понадобиться произвести преобразования для большого числа точек. Этот процесс следует выполнять по возможности более эффективно. В случае двумерных
объектов при получении новой точки (x′,y′) необходимо умножить
é a d 0ù
ê
ú
вектор исходной точки [x y 1] на матрицу êê b e 0úú , т. е. требуетê c f 1ú
ë
û
ся 9 умножений и 6 сложений. Но третий столбец матрицы всегда
имеет вид (0 0 1) (для двумерных изображений). Следовательно,
вычисления для x′ и y′ сокращаются и имеют вид
x′ = ax + by + c; y′ = dx + ey + f,
т. е. всего 4 умножения и 4 сложения. В этом случае матрица имеет
éa dù
ê
ú
вид êê b e úú и ее размер 3×2. Однако следует иметь в виду, что нельзя
êc f ú
ë
û
выполнять совмещение преобразований, представленных матрицами размером 3×2, путем их перемножения. До перемножения их
следует вновь привести к матрицам размера 3×3, т. е. добавить третий столбец.
Преобразования типа масштабирования, поворота, сдвига и перспективы могут быть выполнены линейным способом при использовании однородных координат (умножением на матрицу). Для
получения координат точки в декартовой системе координат необходимо разделить первые две компоненты вектора результата на
четвертую компоненту (третья тождественно равна 0). Таким образом, избежать деления, обязательного в перспективном преобразовании, нельзя, но теперь деление выносится за пределы последовательности линейных преобразований. Для простоты будем считать,
что точка задается вектором вида (x y z 1). Матрица поворота в этом
случае будет иметь вид:
é A D G 0ù
ê
ú
ê B E H 0ú
ú,
R = êê
ú
ê C F I 0ú
ê 0 0 0 1ú
êë
úû
78
где элементы A, B, C, D, E, F, G, H, I определяются последовательностью плоских поворотов относительно осей координат и величиной углов поворотов. Преобразование поворота и масштабирования
можно объединить путем умножения матрицы поворота 3×3 на диагональную матрицу масштабирования
é Sx 0
0ù
ê
ú
ê 0 Sy 0 ú
ê
ú
ê0
ú
0
Sz
ë
û
и последующего расширения результирующей матрицы до размера
4×4. Такое совмещенное преобразование выполняется путем умножения вектора однородных координат точки на матрицу
é ASx DSy GSz 0ù
ê
ú
ê BSx ESy HSz 0ú
ê
ú.
RS = ê
ú
ê CSx FSy ISz 0ú
ê 0
0
0
1úûú
ëê
Аналогично, преобразование сдвига может быть выполнено поé1
0
0 0ù
ê
ú
ê0
1
0 0ú
ê
ú.
средством умножения точки на матрицу T = ê
ú
0
0
1
0
ê
ú
êTx Ty Tz 1ú
ëê
ûú
Для получения перевернутого, промасштабированного и сдвинутого образа точки на плоскости экрана, необходимо выполнить
умножение вектора однородных координат точки на матрицу
é A × Sx D × Sy G × Sz 0ù
ê
ú
ê B × Sx E × Sy H × Sz 0ú
ú,
RST = êê
ú
ê C × Sx F × Sy I × Sz 0ú
ê Tx
Ty
Tz
1úúû
êë
а для получения еще и проекции этой точки, необходимо выполнить умножение на матрицу RSTP = RST.P, где P – матрица перспективы:
é A × Sx D × Sy 0 -G × Sz / z ¢¢ ù
ê
ú
ê B × Sx E × Sy 0 -H × Sz / z ¢¢ú
ú,
RSTP = êê
ú
ê C × Sx F × Sy 0 -I × Sz / z ¢¢ ú
ê Tx
Ty
0 1 - Tz / z ¢¢ ûúú
ëê
79
Последняя матрица называется однородной матрицей поворота, масштабирования, сдвига и перспективы. Таким образом, весь
процесс поворота, масштабирования, сдвига и вычисления координат перспективной проекции можно подразделить на следующие
этапы:
1. Все точки объекта представляются в однородных координатах.
2. Точки преобразуются с помощью матрицы RSTP.
3. Две первые компоненты результирующего вектора делятся на
четвертую.
Результатом выполнения является перспективное изображение
точки. В случае ортогональной проекции деление не выполняется.
Таким образом, весь комплекс преобразований можно свести в одну
подпрограмму, на входе которой задаются значения координат точки, три угла поворота, три масштабирующих множителя, три параметра сдвига, а также параметр, определяющий центр перспективного преобразования. На выходе подпрограммы получим значения
координат перспективной проекции точки.
1.2.2. Алгоритмы удаления невидимых линий и поверхностей
Рассматриваемые в этом разделе алгоритмы предназначены для
решения задачи, которую в компьютерной графике принято называть «проблемой удаления невидимых линий и поверхностей».
Актуальность этой задачи иллюстрирует простой хрестоматийный
пример (рис. 1.59). Удаляя из первоначального каркасного изображения многогранника те или иные ребра, мы можем получить проекции многогранника, совершенно по разному ориентированного
в пространстве по отношению к наблюдателю. Таким образом, для
создания иллюзии непрозрачности изображаемой поверхности не-
Рис. 1.59
80
обходимо выделить те части объекта, которые скрыты от наблюдателя, и не изображать их на экране.
Задача удаления невидимых линий и поверхностей является
одной из самых сложных и трудоемких задач при реализации графического конвейера, что привлекло к ее решению ряд специалистов, создавших в свое время оригинальные алгоритмы ее решения.
Вопрос о том, какой из предложенных для решения этой задачи
алгоритмов является наилучшим с вычислительной точки зрения,
без учета специфических особенностей обрабатываемой тем или
иным алгоритмом пространственной сцены, совершенно некорректен. Скорость работы рассматриваемых в этом разделе алгоритмов
зависит не только (а иногда и не столько) от сложности обрабатываемой сцены (числа многогранников, граней, ребер и т. д. и т. п.),
но и от специфических особенностей пространственной сцены, которые определяются степенью взаимного «заслонения» тел. Пожалуй, сегодня невозможно отдать безусловное предпочтение одному
единственному алгоритму удаления невидимых линий. В каждом
конкретном случае выбор алгоритма удаления невидимых линий
зависит от специфики модели описания трехмерных объектов, вида
этих объектов, требуемой точности их представления, вычислительных ресурсов, требуемого объема памяти. Для решения одних
задач, например, для моделирования процессов в реальном времени, требуются достаточно быстрые алгоритмы. Для генерации
сложных реалистических изображений предпочтительнее иные
методы, решающие поставленные задачи значительно медленнее,
но порождающие более качественные изображения. Как и при решении многих других задач в вычислительной математике, здесь
существует взаимосвязь между эффективностью работы того или
иного алгоритма и качеством результата его выполнения (итогового изображения). И, как очень часто бывает, на данный момент нет
алгоритма решения «проблемы удаления невидимых линий», способного обеспечить одновременное достижение отличных результатов для этих двух показателей (скорости и качества работы).
Большинство алгоритмов удаления невидимых линий используют в своей работе сортировку объектов пространственной сцены по глубине (расстоянию от объекта до наблюдателя). Основная
идея такой сортировки состоит в том, что, чем дальше расположен
объект от наблюдателя, тем с большей вероятностью он будет полностью или частично заслонен от наблюдателя объектами, более
близко расположенными к точке наблюдения. Таким образом, ре81
шающим фактором, определяющим эффективность алгоритма удаления невидимых линий, является эффективность используемого в
алгоритме метода сортировки.
Все рассматриваемые далее алгоритмы удаления невидимых
линий (поверхностей) можно разделить на два класса, учитывая
размерность пространства, в котором, собственно, и выполняется
удаление невидимых линий (поверхностей) [13, 16, 18]. К первому
классу относятся алгоритмы, работающие в объектном пространстве (удаление невидимых частей объектов производится именно в
этом пространстве). Основным достоинством таких методов является высокая точность результата. Ко второму классу относятся алгоритмы, осуществляющие удаление невидимых частей объектов после выполнения операции проецирования, т. е. работают в экранной (картинной) плоскости. Поскольку точность результата при
этом, очевидно, определяется разрешающей способностью экрана,
то, например, подвергая результирующее изображение большому
увеличению, мы можем получить изображение, не совсем точно соответствующее исходной сцене.
Далее в этом разделе вниманию читателя предлагается ряд алгоритмов удаления невидимых линий (поверхностей), работающих как в объектном пространстве, так и в картинной плоскости.
Естественно, не следует считать, что здесь будет изложено все, что
создано в этой области. Однако каждый из предлагаемых вашему
вниманию алгоритмов иллюстрирует одну или несколько основополагающих идей решения задачи удаления невидимых линий и
поверхностей.
Метод количественной невидимости Аппеля
Данный алгоритм был одним из первых методов, решающих
«проблему невидимых линий». Метод оперирует в объектном пространстве, ориентирован на центральное проецирование, и может
обрабатывать сцены, состоящие из многогранников, причем не
обязательно выпуклых (при этом многогранники не должны протыкать друг друга). Грани многогранника – суть многоугольники.
В алгоритме Аппеля вершины каждого многоугольника упорядочиваются (нумеруются) по направлению, противоположному движению часовой стрелки.
Для определения видимости объектов сцены исследуется видимость ребер их граней. На первом этапе алгоритма удаляются все
ребра, заслоняемые телами, к которым они принадлежат. Для этого
82
используется тест видимости, рассмотренный в предыдущем разделе (считается, что ребро заслоняется собственным телом, когда оно
принадлежит граням, повернутым своей лицевой поверхностью от
наблюдателя). Все оставшиеся после этого в рассмотрении ребра,
ограничивающие потенциально видимую грань («потенциально» –
поскольку она может заслоняться от наблюдателя (полностью или
частично) «чужими» телами) Аппель называет вещественными ребрами (ВР). Часть вещественных ребер, а именно те, которые принадлежат одновременно потенциально видимой и невидимой граням, Аппель называет контурными ребрами (КР).
На втором этапе алгоритма определяется видимость всех потенциально видимых ребер. Для этого определяется так называемая
количественная невидимость точек на потенциально видимом ребре. Количественной невидимостью точек на потенциально видимом ребре Аппель называет число граней, заслоняющих данную
точку от наблюдателя. Соответственно, видны будут только те точки на вещественном ребре, количественная невидимость которых
нулевая. Поточечный тест для определения количественной невидимости можно и не применять, так как для вещественного ребра
количественная невидимость точек на нем может меняться только в тех случаях, когда это ребро уходит за контурное ребро или
выходит из-за него. В терминах проекции это значит, что количественная невидимость проекции ВР может меняться только в точке
пересечения с каким-либо КР. В этой точке количественная невидимость увеличивается на единицу, если ВР уходит за КР, и уменьшается на единицу, если ВР выходит из-за КР. Таким образом, ВР
разбивается на отрезки с различными значениями количественной
невидимости, и у двух соседних отрезков количественная невидимость отличается ровно на единицу.
Для получения своеобразной точки отсчета сначала определяется количественная невидимость начальной точки ВР. Для этого
необходимо получить уравнение прямой, проходящей через начальную точку ВР и точку наблюдения, а затем найти пересечения
этой прямой со всеми плоскостями, содержащими грани (для этого,
естественно, необходимо получить уравнения этих плоскостей, что
нетрудно сделать, имея координаты вершин граней). Для подсчета
количественной невидимости из всех этих найденных точек пересечения оставляют в рассмотрении те, что лежат на отрезке прямой
от точки наблюдения до начальной точки ребра (см. тест глубины
для центральной проекции). Затем среди оставшихся точек выби83
Вещественное ребро
F2
F1
O
I3
I1
I2
F3
P
Рис. 1.60
раются для дальнейшего учета те, которые принадлежат соответствующим граням (см. тест принадлежности). Число оставшихся
в рассмотрении точек и определяет количественную невидимость
начальной точки ребра. На рис. 1.60 прямая OP имеет три точки
пересечения с плоскостями, содержащими грани – I1, I2, I3; I1 принадлежит F1, I2 не принадлежит F2, I3 принадлежит F3. Точка I3
не рассматривается, так как лежит дольше от точки наблюдения,
чем начальная точка ВР. Таким образом, количественная невидимость начальной точки P равна единице.
Теперь рассмотрим предложенную Аппелем процедуру поиска
точек на ВР, где меняется количественная невидимость (это точки
пересечения ВР и КР в плоскости проекции). Для этого рассмотрим
треугольник, вершинами которого являются точка наблюдения и
вершины ВР. Некое КР меняет количественную невидимость рассматриваемого ВР только тогда, когда оно протыкает этот треугольник, т. е. когда точка пересечения КР с плоскостью, содержащей
треугольник, лежит внутри треугольника. Если это так, то количественная невидимость возрастает на 1 при положительном знаке
векторного произведения КР и ВР и уменьшается на 1 при отрицательном знаке. На рис. 1.61 точка
изменения невидимости – это точка
P1
q = q +(– ) 1 пересечения прямой OD с ВР.
КР
Итак, подводя итоги, коротко повторим основные этапы алгоритма:
q
− для каждой грани применяется
D
ВР
тест видимости (отбрасываются грани, а, соответственно, и ребра, заслоО
P2
няемые от наблюдателя собственныРис. 1.61
ми телами);
84
− для каждого ВР определяется количественная невидимость
его начальной точки;
− для каждого ВР каждого многогранника находятся точки
пересечения его с контурными ребрами (в плоскости проекции),
тем самым каждое ВР разбивается на участки с различной количественной невидимостью;
− строится проективное изображение на экранную плоскость
участков всех вещественных ребер, имеющих нулевую количественную невидимость.
Метод приоритетов
Этот алгоритм работает с объектами в экранной плоскости, может использоваться как для выпуклых, так и для невыпуклых
многогранников. В начале работы алгоритма все грани декомпозируются на треугольники (подвергаются триангуляции, эти алгоритмы обсуждались ранее), т. е. вводится определенное количество
ребер, которые помечаются как вспомогательные. Далее этот алгоритм оперирует с множеством треугольников (самых простых граней), которые определяются координатами своих вершин.
На первом этапе алгоритма осуществляется предварительное
упорядочение. Выделяются все треугольники, перпендикулярные
плоскости XY, которые на следующих этапах не рассматриваются,
так как не могут заслонять другие грани (грань перпендикулярна
экранной плоскости, если проекции ее вершин колинеарны).
Затем выполняется этап приписывания приоритетов. Пусть
имеется объект, разбитый на множество треугольных граней
S = {s1, ..., sm}, и пусть Pr(si) = ti – ортогональная проекция грани si. Обозначим через T = {ti} множество проекций треугольных
граней. В методе приоритетов формируется множество пар (ti,Ti),
i = 1, ..., M, где ti принадлежит T; Ti-подмножество множества
T – суть множество треугольников, имеющих больший приоритет,
чем ti (это множество определяется с помощью теста глубины 2).
Для определения множеств Ti с помощью минимаксного теста определяется, с какими объектами tj пересекается каждый из объектов
ti. Изолированные объекты ti исключаются из рассмотрения, так
как встречаются только в парах (ti,{Θ}), где Θ – пустое множество.
Для остальных L≤ M объектов должен быть определен приоритет,
что требует L(L – 1)/2 повторений теста глубины 2. Для нахождения точек пересечения двух треугольников сначала определяются
точки пересечения их ребер. В случае их отсутствия проверяется,
85
нет ли полного вложения одного треугольника в другой. Вследствие разбиения граней на треугольники циклическое перекрытие
невозможно, но треугольники могут проникать друг в друга. Эти
случаи требуют специального рассмотрения. Проникание может
иметь место только тогда, когда проекции двух граней имеют непустое пересечение. Обнаружить проникновение можно с помощью
приоритетного теста, выполненного для всех точек пересечения ребер проекций. Если результат теста постоянен для всех точек, то
проникновения нет.
Итак, в каждой паре (ti,Ti) Ti представляет собой множество
треугольников, покрывающих, хотя бы частично, треугольник ti.
Отсортировав полученные пары в порядке возрастания мощности
множества Ti, для получения результирующего изображения достаточно вывести треугольники ti, начиная с конца полученного
отсортированного списка. При этом первыми будут выведены треугольники, наиболее плотно покрытые другими треугольниками, а
последними, соответственно, наименее закрытые треугольники. В
результате получим изображение, в котором будут удалены невидимые поверхности (на самом деле они не удалены, а закрашены
теми треугольниками, которые имеют приоритет над закрытыми
частями изображения).
Пример 1.6. Пусть имеются две треугольные пирамиды, заданные координатами своих вершин (рис. 1.62):
A (3, 0, 1); B (5, 0, 0);
C (0, – 1, 1); D (2, 5, 0);
E (2, 0, – 2); F (6, 0, – 2);
G (4, 0, – 4); H (3, 6, – 3).
Y
D
Z
H
A
Рис. 1.62
86
G
E
C
B
F
X
В данном случае, триангуляцию
проводить не имеет смысла, поскольку и без этого все грани в пространственной сцене – треугольники.
Обозначим
∆ABC = S1; ∆ACD = S2;
∆ABD = S3; ∆CDB = S4;
∆EGF = S5; ∆EHF = S6;
∆EHG = S7; ∆FHG = S8.
Соответственно, проекции этих треугольников на экранную плоскость
обозначим t1, t2, t3, t4, t5, t6, t7,
Y
H
t8. Данные проекции образуют
D
множество T. Ортогональная проекция всех треугольников (без закраски граней) выглядит следующим образом (рис. 1.63).
E
На этапе предварительного упорядочения отбрасываем треугольX
A G B F
С
ник S5, поскольку проекции всех
трех его вершин (E, G и F) коллиРис. 1.63
неарны. Это нетрудно проверить
аналитически, построив уравнение прямой EG (очевидно, что это
прямая y = 0) и подставив в него координаты точки F. В итоге получим тождественное равенство, следовательно, E, G и F лежат на
одной прямой. Подобная проверка для остальных треугольников
покажет, что проекции их вершин неколлинеарны. Таким образом,
после предварительного упорядочения у нас осталось множество T,
состоящее из семи проекций треугольных граней: T = {t1, t2, t3, t4,
t6, t7, t8}.
Теперь с помощью минимаксного теста следует проверить, существуют ли треугольники, которые не перекрываются с другими
треугольниками в экранной плоскости? Данный тест был подробно
рассмотрен в подразд. 1.2.1, поэтому здесь не будем останавливаться на деталях этой процедуры. Очевидно, что проведенный анализ
покажет – из всего множества треугольников T лишь треугольник
t1 не перекрывается с остальными треугольниками в экранной
плоскости. Поэтому можно сразу сформировать пару (t1, {Θ}). Для
оставшихся шести треугольников необходимо провести 15 тестов
глубины для ортогональной проекции. Выполнив тесты глубины
для всех пар оставшихся в рассмотрении треугольников, получим
следующую картину:
t2 ≈ t3; t2  t4; t2  t6; t2  t7; t2  t8;
t3  t4; t3  t6; t3  t7; t3  t8;
t4  t6; t4  t7; t4  t8;
t6  t7; t6  t8;
t7 » t8;
87
здесь знаки ≈ и  обозначают равный и больший приоритет соответственно. Теперь сформируем пары вида (t i, Ti):
(t1, {Θ}); (t2, {Θ}); (t3, Θ); (t4, {t2, t3}); (t5, {t2, t3, t4});
(t6, {t2, t3, t4}); (t7, {t2, t3, t4, t6}); (t8, {t2, t3, t4, t6}).
После выполнения сортировки этих пар в порядке убывания
мощности множеств Ti осуществим вывод треугольников ti в соответствии с полученным порядком, начиная с tk, у которого соответствующее ему множество Tk наиболее мощное. После вывода
последнего треугольника получим картину с удаленными невидимыми линиями и поверхностями. Последовательность выводов
треугольников (считаем, что каждая грань закрашена в свой цвет)
и окончательный результат представлены на рис. 1.64.
В том случае, когда в пространственной сцене присутствуют
прозрачные или полупрозрачные грани, для формирования реалистичных сцен в области перекрытия такой грани с другими используется комбинация цветов перекрывающихся объектов (смешение
цветов).
При реализации алгоритма следует учесть, что для некоторых
пространственных сцен метод приоритетов принципиально неприменим, поскольку в любом случае не позволяет выполнить поставленную перед ним задачу корректно. Например, если обратиться к
рис. 1.65, то при любой последовательности выводимых треугольников невозможно получить требуемый рисунок.
Алгоритм Робертса
Данный алгоритм решает задачу удаления невидимых линий
для пространственных сцен, составленных из выпуклых многогранников. Исходными данными для алгоритма являются уравнения плоскостей граней многогранников и параметрические уравнения их ребер.
Каждая плоскость P описывается уравнением вида A.X + B.Y +
+ C.Z + D = 0. Зная однородные координаты некоторой точки
V = (wx wy wz w), легко определить, лежит V в P или нет. Если скалярное произведение V на P равно 0, то V принадлежит P. В противном случае, знак скалярного произведения указывает, с какой стороны от плоскости находится точка V. В своем алгоритме Робертс
так подбирает коэффициенты в уравнениях плоскостей, чтобы про88
изведение вектора однородных координат точки, лежащей внутри
многогранника, на вектор коэффициентов уравнения плоскости
грани этого же многогранника всегда было положительным.
é Aù
ê ú
ê Bú
Вектора плоскостей P = êê úú каждого многогранника заносятся
êCú
ê Dú
ëê ûú
в матрицу размером (4×n), где n – число граней в многограннике.
Эта матрица называется обобщенной матрицей описания многогранника: 
é a1
ê
ê b1
B = êê
ê c1
êd
ëê 1
a2
b2
c2
d2
.
.
.
.
an ù
ú
bn ú
ú.
cn úú
dn úûú
где ai , bi , ci ,di – коэффициенты уравнений плоскостей граней. Если
каждый элемент произведения V.B ≥ 0, то эта точка лежит внутри
многогранника, описанного матрицей B.
Как уже говорилось, ребра многогранников задаются параметрическими уравнениями. Параметрическое уравнение отрезка, заданного двумя граничными точками R (xR, yR) и S (xS,yS), имеет вид
x = xS + t(xR – xS)
y = yS + t(yR – yS),
или в векторной форме V = S + t(R – S), где параметр t лежит в диапазоне от 0 до 1 включительно.
Удаление невидимых линий в алгоритме Робертса осуществляется в два этапа.
На первом этапе определяются участки линий, закрываемые
от наблюдателя своим собственным объектом. Очевидно, что если
одна или обе грани, образующие ребро, обращены своей внешней
поверхностью к наблюдателю, то это ребро видимо.
В своем алгоритме Робертс предложил так подбирать коэффициенты в уравнениях плоскостей граней, чтобы произведение вектора
точки V, лежащей внутри многогранника, на обобщенную матрицу
описание этого же многогранника давало в результате вектор, состоящий из положительных компонент. Если наблюдатель находится
в бесконечности (ортогональное проецирование) на положительной
89
полуоси z, то его взгляд направлен в сторону отрицательной полуоси z. Вектор такого направления в однородных координатах равен
W = [0 0 – 1 0]. По существу, этот вектор представляет любую точку,
лежащую в плоскости z = – ∞. Следовательно, в случае отрицательного результата скалярного произведения вектора W на столбец,
соответствующий некоторой плоскости в обобщенной матрице описания многогранника, вектор W лежит по отрицательную сторону
этой плоскости, а, значит, эта плоскость невидима из любой точки
наблюдения, лежащей в плоскости z = ∞ (именно там находится наблюдатель). Нетрудно заметить, что в этом случае граням, обращенным внешней поверхностью от наблюдателя, будут соответствовать
уравнения плоскостей, в которых значение коэффициента при переменной z будет больше или равно нулю. Ребра таких граней, очевидно, не будут изображаться и исключаются из дальнейшего рассмотрения. Остальные ребра считаются потенциально видимыми и рассматриваются на втором этапе работы алгоритма.
На этом этапе проверяется положение потенциально видимых
ребер каждого многогранника относительно других многогранников, т. е. осуществляется проверка каждого отрезка прямой, считающегося потенциально видимым в результате работы первого
этапа алгоритма. Идея данной проверки следует все из того же оригинального способа подбора уравнений плоскостей граней, предложенного Робертсом. Напомним, что скалярное произведение любой
точки, лежащей внутри многогранника, на обобщенную матрицу
этого же многогранника, положительно.
Предположим, что рассматриваются все точки отрезка прямой
(потенциально видимого ребра грани), представленные различными значениями параметра t в уравнении прямой V = S + t·d, где
d = (R – S) – направление ребра (здесь R и S – граничные точки ребра). Через каждую такую точку можно провести прямую в положительном направлении оси Z, т. е. к глазу наблюдателя. Если эта
прямая не пересекает ни одного многогранника, то соответствующая точка на ребре видима. В противном случае многогранник закрывает эту точку. Эту прямую можно представить в параметрическом виде как U = S + t·d + e·Z, где Z = [0 0 1 0]. Интересующие нас
точки на прямой лежат в пределах 0≤t≤1, 0 ≤ e.
Для проверки видимости умножаем вектор текущей точки прямой поочередно на обобщенные матрицы каждого многогранника
и находим положительное решение для всех коэффициентов, отражающее прохождение прямой внутри многогранника: U·B ≥ 0 или
90
S·B + t·d·B + e·Z·B ≥ 0. Заметим, что Z·B = W, где W – третья строка
матрицы B. Если pi и qi – i-е столбцы соответственно матриц S·B и
d·B, то имеем pi + t·qi + e·wi ≥ 0, где 0≤t≤1, 0 ≤ e. Эти неравенства решаются для максимального и минимального значений t при любом
положительном e. Некоторые области значений дают очевидные
результаты. Например, при qi ≥ 0, pi ≥ 0 и wi ≥ 0 эти неравенства
удовлетворяются для любого t и любого e в заданных пределах. Это
значит, что отрезок прямой полностью закрыт объектом (невидим).
В том случае, если система неравенств несовместна, рассматриваемое ребро полностью видимо (не закрывается данным многогранником). В нетривиальных случаях метод решения близок к решению задач линейного программирования (практически, здесь для
каждой системы линейных неравенств необходимо решить пару задач линейного программирования с целевыми функциями t ® min
и t ® max и, естественно, с соответствующей системой линейных
неравенств).
Здесь, не вдаваясь в подробности методов решения задач линейного программирования, рассмотрим более наглядный метод. Каждое неравенство можно рассматривать как задание некоторой области в плоскости координат (t, e). Эта область ограничена прямыми
pi + t·qi + e·wi = 0. Если все эти прямые вместе с прямыми t = 0,
t = 1 и e = 0 провести в плоскости (t, e), то они определят область,
которая удовлетворяет системе линейных неравенств. Если система
неравенств несовместна, то отрезок прямой целиком видим. Если
же такую область удается получить, то необходимо вычислить минимальное и максимальное значения t для этой области. Эти значения и определят границы закрытых данным многогранником
участков рассматриваемого на данном шаге алгоритма ребра.
Пример 1.7. Рассмотрим пирамиду (на рис. 1.66, а). Здесь
A (2, 0, 0); B (1, 0, –2); C (4, 0, –2); D (2, 4, 0); S (0, 1, –1); R (4, 0, 0).
Выбираем точку внутри пирамиды, например, усреднив координаты ее вершин, и подбираем коэффициенты уравнений плоскостей
граней пирамиды так, чтобы в произведении вектора V на обобщенную матрицу пирамиды B все элементы были неотрицательны.
Обобщенная матрица пирамиды выглядит следующим образом:
é 0 2 -1 0 ù
ê
ú
ê1 0
0 -1ú
ê
ú.
B=ê
ú
0
1
1
2
ê
ú
ê 0 -4 2
4 úúû
ëê
91
а)
б)
Y
Y
D
D
S
B
Z
S
C
A
L
R
B
X
M
R
A
C
X
Рис. 1.66
На первом этапе алгоритма анализируется матрица B и грани, у
которых коэффициент при z в уравнении плоскости больше или равен 0, не изображаются. Ортогональная проекция этой пирамиды
на экранную плоскость приведена на рис. 1.66, б.
Рассмотрим теперь отрезок прямой, проходящий от точки S =
= (0, 1, –1) до R = (4, 0, 0). Запишем эти точки в виде векторов в
однородных координатах S = (0 1 –1 1); R = (4 0 0 1). Определим
вектор d = R – S = (4 –1 1 0), а также векторы p = S·B = (1 –3 3 2);
q = d.B = (–1 7 –5 3) и w = (0 –1 –1 2). Затем составляем систему неравенств pi + t·qi + e·wi ≥ 0
ì
ì
1- t + e × 0 ³ 0
t £1
ï
ï
ï
ï
ï
ï
ï
ï 7t - e ³ 3
ï -3 + t × 7 - e ³ 0
èëè ï
í
í
ï
ï
3-t×5- e ³ 0
5t + e £ 3
ï
ï
ï
ï
ï
ï
2
t
3
e
2
0
3
t
+
×
+
×
³
ï
ï
ï
ï + 2e ³-2
î
î
Добавляем сюда неравенства, где 0≤t≤1 и 0 ≤ e. Область, удовлетворяющая этой системе неравенств, показана на рис. 1.67 штриe
t≥ 0
t≤ 1
3
e≥ 0
7t–e ≥ 3
5t+e≤ 3
t
3/7 3/5
–1
3t+2e ≥ 2
–3
Рис. 1. 67
92
ховкой. Таким образом, при 3/7≤t≤3/5 отрезок прямой невидим, а
при 0 ≤ t < 3/7 и 3/5 < t ≤ 1 – видим. Два видимых отрезка при этом
определяются следующими четырьмя точками: первый отрезок видим от точки S + 0.d = S до точки L = S + 3/7.d = (12/7 4/7 – 4/7 1),
а второй – от точки M = S + 3/5.d = (12/5 2/5 –2/5 1) до точки
S + d = R = (4 0 0 1) (см. рис. 1.66, б).
Очевидно и понятно, что подобную задачу необходимо решить
для каждого потенциально видимого ребра каждого многогранника пространственной сцены по отношению ко всем «чужим» многогранникам.
Алгоритм сканирующей прямой Уоткинса
Данный алгоритм оперирует в экранной плоскости. Изображение представляет собой набор многоугольников, являющихся ортогональными проекциями плоских граней трехмерных объектов.
Для решения поставленной задачи (удаления невидимых линий
и поверхностей) сцена последовательно рассекается плоскостями,
перпендикулярными экрану (в терминах проекции эти секущие
плоскости представляют собой так называемые сканирующие прямые). Таким образом, сканирующие прямые параллельны оси X
(горизонтальны). Все сканирующие прямые обрабатываются алгоритмом одним способом, следовательно, достаточно рассмотреть
одну такую прямую.
Алгоритм Уоткинса состоит из двух основных частей: нахождения так называемых пробных интервалов и определения видимости.
При нахождении пробных интервалов определяются отрезки
сканирующей прямой, лежащие внутри одного из многоугольников. В результате  каждому многоугольнику в экранной плоскости приписывается множество отрезков сканирующей прямой (это
множество может быть и пустым).
Пример 1.8. Многоугольникам на рис. 1.68 приписываются следующие отрезки сканирующей прямой (здесь sij – отрезок номер
j i-го многоугольника, образованный пересечением Fi с заданной
сканирующей прямой): F1 приписаны s11 и s12; F2 приписан s21; F3
приписан s31.
Следует отметить, что изолированные (не перекрывающиеся в
плоскости XY) отрезки видимы. Отрезки s21 и s31 перекрываются
в плоскости XY. В этом случае необходимо сформировать пробные
93
Экранная
плоскость
Сканирующая
прямая
F2
s31
s11
s12
s21
F3
F1
Рис. 1. 68
интервалы. Пробным интервалом будем называть отрезок сканирующей прямой, на котором видимость не изменяется. Для нахождения пробных интервалов необходимо рассмотреть проекции граней
на плоскость XZ, поскольку только такая проекция позволит выяснить взаимное расположение граней в пространстве.
Пример 1.9. Рассмотрим проекции граней (рис. 1.69).
Здесь интервалы 1 – 8 являются пробными интервалами. Таким
образом, пробный интервал – это часть сканирующей прямой, для
которой справедливо: число отрезков, содержащих пробный интервал, постоянно и строго больше 1; проекции на плоскость XZ граней, соответствующих этим отрезкам, не пересекаются. Другими
словами, внутри пробного интервала никакие два ребра проекций
не пересекаются и никакие две грани не проникают друг в друга в
Сканирующая объектном пространстве.
Y
прямая
Вопрос о том, какой из сегментов
проекций видим на пробном интервале, разрешается с помощью следующего теста: видим тот сегмент, минимальная z-координата которого в пробном
интервале больше или равна максиX
мальной z-координате всех других
1 234 5 6 7
8
X
сегментов. Видимый сегмент при этом
образует полоску видимой проекции
грани на экранной плоскости.
Видимость пробного интервала необходимо проверять в следующих слуZ
чаях:
1. Число отрезков на текущей сканирующей прямой отличается от числа
отрезков на предыдущей прямой.
Рис. 1.69
94
2. Если изменилась связь крайних точек отрезков с ребрами проекций граней при переходе от предыдущей сканирующей прямой
к текущей (в этом случае между сканирующими прямыми произошло пересечение двух ребер).
Этот алгоритм можно ускорить, если предварительно упорядочить по максимальному (минимальному) значению y-координаты
ребер проекций (в зависимости от направления сканирования:
сверху–вниз или снизу–вверх). Как только в процессе вычисления
точек пересечения сканирующей прямой и ребер проекций встретиться объект, максимальная (минимальная) y-координата которого меньше (больше) значения y-координаты сканирующей прямой,
процесс вычисления прекращается (этот объект и вся оставшаяся
часть упорядоченного списка не обрабатывается).
Таким образом, в алгоритме Уоткинса рассматриваемая сцена
рассекается плоскостями, перпендикулярными плоскости экрана,
и в полученном сечении на определенных предварительно пробных
интервалах выполняется тест глубины. Если обработать все сканирующие прямые, соответствующие строкам развертки экрана, то в
результате получим изображение с удаленными невидимыми поверхностями. Это изображение получится подобно тому, как строчка за строчкой получается тканый узор при изготовлении ковров.
Алгоритм Варнока
Принципиально иной подход для решения проблемы удаления
невидимых линий и поверхностей предложил Варнок, который в
своем алгоритме исследует не видимость конкретного элемента
изображения, а фрагмент экрана на предмет наличия в нем видимых частей сцены. В основу алгоритма заложена особенность восприятия изображения человеком. Несложно провести простой эксперимент над самим собой, пытаясь до мельчайших подробностей
воспринять некоторую пространственную сцену, скажем, свой
собственный письменный стол. Та часть стола (его цвет, фактура),
на которой нет никаких предметов, воспринимается достаточно
быстро. Взгляд невольно задерживается на предметах, хаотично
расположенных в нерабочей части стола. Вы пытаетесь подробно
рассмотреть эти предметы, выяснить интересующие вас характеристики: цвет, фактуру, материал, из которого они сделаны, их
взаимное расположение и т. д. Если какой-либо из предметов вас
особенно заинтересует, вы повышаете уровень детализации, пытаясь рассмотреть этот предмет более внимательно… Примерно то
95
же самое происходит и при работе алгоритма Варнока: однородные
(по цвету, фактуре) области сцены обрабатываются быстро, более
сложные участки требуют более детального рассмотрения.
Итак, при работе алгоритма Варнока рассматривается часть
экрана, называемая окном (вначале окно – весь экран), и в нем производится анализ элементов сцены. Результатом анализа является
один из трех возможных вариантов решения:
− окно пусто (видимые элементы в нем отсутствуют);
− элемент в окне оценивается, как простой, и может быть изображен в окне;
− элемент или группа элементов в окне слишком сложны для непосредственного изображения и, следовательно, окно разбивается
на подокна, каждое из которых исследуется отдельно по аналогичному сценарию.
Разбиение окна на подокна производится до тех пор, пока его
размер не окажется равным одному пикселю. Естественно, что количество делений окна определяется тем критерием, по которому
можно классифицировать элементы в окне, как простые. Здесь рассмотрим один из многочисленных вариантов алгоритма Варнока, в
котором простой ситуацией считается либо пустое окно (тогда оно
полностью закрашивается цветом фона), либо в окне видим охватывающий всю площадь окна многоугольник, заслоняющий от наблюдателя все другие элементы сцены в этом окне (тогда окно заливается цветом этого многоугольника). Все остальные ситуации
будут считаться сложными и, следовательно, будут приводить к делению текущего окна на подокна. Примем для простоты также, что
первоначальное окно (весь экран) имеет квадратную форму с длиной стороны, равной 2n, где n – любое положительное целое число. Кроме того, условимся, что здесь мы будем рассматривать пространственные сцены, состоящие из многогранников, а поскольку
алгоритм Варнока работает в экранной плоскости, то он будет обрабатывать множество многоугольников (множество проекций граней многогранников).
На рис. 1.70 показан пример разбиения исходного экрана на подокна при анализе их алгоритмом. На третьем уровне разбиения
некоторые окна оказываются пустыми и заливаются цветом фона
(их дальнейшее деление прекращается), остальные окна продолжают разбиваться на подобласти. Для формирования окончательного
изображения все ветви этого дерева должны быть проанализированы алгоритмом.
96
Структурно алгоритм Варнока состоит из следующих основных
элементов: блока просмотра, блока принятия решения и блока
управления.
Не вдаваясь пока в детали, можно упрощенно описать работу
алгоритма следующим образом. Блок просмотра анализирует текущее окно и определяет положение каждого многоугольника из обрабатываемой сцены по отношению к этому окну. Подготовленные
блоком просмотра данные анализируются в блоке принятия решения, который определяет возможность непосредственного изображения элементов в текущем окне. В том случае, когда ситуация
для непосредственного изображения сложна, блок управления выполняет деление текущего окна на подокна и поочередно передает
вновь образованные области экрана на повторное исследование в
блок просмотра. Если блок принятия решения признает ситуацию
простой, окно заливается соответствующим цветом. Если ситуация
признается сложной даже для окна, размер которого не превышает одного пикселя, то данное окно (пиксель) окрашивается цветом
того многоугольника, который находится ближе всего к наблюдателю, находящемуся на прямой, соединяющей центр данного
пикселя с точкой наблюдения. Совершенно очевидно, что данный
алгоритм вполне универсален и может применяться для обработки
пространственных сцен любой сложности.
Теперь, имея общее представление о структуре данного алгоритма, давайте более детально ознакомимся с работой каждого из трех
основных блоков.
Внешний
Основная задача блока просмотра – определить взаимное расположение всех многоугольников сцены по отношению к текущему окну. В
итоге проведенного блоком анализа формируют- Вутренний
ся три списка многоугольников:
1) внутренние по отношению к текущему окну
(находятся целиком внутри окна) и пересекаю- Пересекающий
щие это окно многоугольники (пересекают хотя
бы одну границу окна);
2) охватывающие это окно многоугольники Охватывающий
(окно находится целиком внутри таких многоугольников);
3) внешние по отношению к текущему окну
многоугольники (находятся целиком вне окна)
Рис. 1.71
(рис. 1.71).
97
Для формирования таких списков необходимо уметь классифицировать перечисленные виды расположения многоугольника по
отношению к окну.
Сначала необходимо использовать тест с прямоугольной объемлющей многоугольник оболочкой для классификации внутренних
и части внешних по отношению к окну многоугольников. Обозначим через xл, xп, ун, ув, соответственно, левую, правую, нижнюю и
верхнюю границы окна, а через xmin, xmax, уmin, уmax–ребра прямоугольной объемлющей многоугольник оболочки. Тогда многоугольник будет внутренним по отношению к окну, если объемлющая его прямоугольная оболочка целиком лежит внутри окна, т. е.
если выполняется следующее условие: (xmin≥xл) & (xmax ≤ xп) &
(ymin≥yн) & (ymax ≤ yв) (рис. 1.72, а). Кроме этого, многоугольник
будет внешним по отношению к окну, если выполняется одно из
следующих условий: (xmin>xп), (xmax < xл), (ymin>yв), (ymax < yн)
(рис. 1.72, б).
Этот достаточно простой тест с прямоугольной объемлющей многоугольник оболочкой не позволяет, однако, идентифицировать
все виды внешних многоугольников. Действительно, если обратиться к рис. 1.72, в, то нетрудно заметить, что ни одно из условий
(xmin>xп), (xmax < xл), (ymin>yв), (ymax < yн) не является истинным,
хотя многоугольник внешний по отношению к окну. В подобных
случаях необходимо использовать тест с бесконечным лучом или
тест с подсчетом суммы углов.
1. Тест с бесконечным лучом. Пусть R – луч, начинающийся в
любой внутренней точке окна (скажем, в точке Pt) и проходящий
через тестируемый многоугольник, но не пересекающий ни одной
его вершины. Тогда многоугольник будет внешним по отношению
к окну, если число пересечений R со сторонами многоугольника
ув
у в б)
а)
у max
у min
xmin x max
xл
xп
у max
ун
xл
xп
ун
у max
у min
xmin x max
Рис. 1.72
98
ув
в)
xл
у min
xmin
x max
ун
xп
a)
R
P2
б) P3
R
a4
a2
Pt
a3
Pt
P4
P1 = P5
P1 =P5
a1
P2
a1
a4 a
2
Pt
a3
Pt
P4
P3
Рис. 1.73
четно, и многоугольник будет охватывать окно, если число пересечений нечетно (рис. 1.73, а).
2. Подсчет суммы углов. Пусть F = {P1, ..., Pn} – тестируемый
многоугольник с вершинами Pi( xi, yi), i = 1, ..., n и P1 = Pn; Pt –
произвольная точка внутри окна; Pt Pi – отрезок, соединяющий Pt
и Pi. Точка Pt соединяется отрезками прямой со всеми вершинами
многоугольника. Обозначим ai – угол между Pt Pi и Pt Pi+1. Тогда тестируемый многоугольник охватывает окно, если
å ai = 2π,
i
и является внешним по отношению к окну, если å ai = 0 (при сумi
мировании углов необходимо учитывать не только их величину, но
и направление – знак) (рис. 1.73, б).
Следует учесть, что перед проведением одного из этих тестов необходимо идентифицировать все внутренние и пересекающие окно
многоугольники.
Для идентификации пересекающих окно многоугольников необходимо выяснить пересекает ли хотя бы одно ребро многоугольника сторону окна. Эту проверку можно выполнить с использованием минимаксного теста для определения факта пересечения двух
отрезков прямых (см. подразд. 1.2.1).
Еще раз следует отметить, что для корректной идентификации
положения многоугольников по отношению к окну необходимо
строго соблюдать последовательность выполнения перечисленных
тестов. Сначала выполняется тест с прямоугольной объемлющей
многоугольник оболочкой, с помощью которого определяются все
внутренние и часть внешних многоугольников. Затем определяются все пересекающие окно многоугольники, а в заключение с помощью теста с бесконечным лучом (или с подсчетом суммы углов)
определяются оставшиеся внешние многоугольники и все охватывающие окно многоугольники. Таким образом, в блоке просмотра
99
формируются все три ранее заявленных списка (список внутренних
по отношению к текущему окну многоугольников и пересекающих
это окно многоугольников; список охватывающих это окно многоугольников и список внешних по отношению к текущему окну
многоугольников).
Теперь более детально рассмотрим блок принятия решения.
Напомню, что в описываемой интерпретации алгоритма Варнока
простой считается ситуация, когда блок принятия решения обнаружит, что анализируемое окно пусто (тогда оно полностью закрашивается цветом фона), либо в окне видим охватывающий всю
площадь окна многоугольник, заслоняющий от наблюдателя все
другие элементы сцены в этом окне (тогда окно заливается цветом
этого многоугольника).
Естественно, в тех случаях, когда подготовленный блоком просмотра список внутренних и пересекающих это окно многоугольников, а также список охватывающих текущее окно многоугольников пусты, то окно, соответственно, пустое и изображается цветом фона. Для выявления многоугольника, охватывающего окно и
заслоняющего от наблюдателя все другие многоугольники в этом
окне, в блоке принятия решения реализован тест глубины, в котором сравниваются глубины (координаты z) плоскостей многоугольников в четырех угловых точках текущего окна. В том случае, когда глубина охватывающего многоугольника во всех четырех угловых точках окна больше соответствующих глубин всех остальных
многоугольников из подготовленных списков, то охватывающий
многоугольник экранирует все остальные многоугольники в этом
окне. Следовательно, данное окно окрашивается цветом этого охватывающего многоугольника. Однако описанное условие является
достаточным, но не является необходимым. Для более подробного
рассмотрения этого условия обратимся к рис. 1.74. Здесь для про-
a)
Охвтывающий
многоугольник
О
К
Н
О
Z
X
б)
Пересекающий
многоугольник
О
К
Н
О
Несущая пересекающий
многоугольник плоскость
Z
Рис. 1.74
100
Охвтывающий
многоугольник
X
Пересекающий
многоугольник
Несущая пересекающий
многоугольник плоскость
стоты восприятия несущие все многоугольники плоскости перпендикулярны плоскости XZ (наблюдатель находится в бесконечности в положительном направлении оси Z). Когда определяются
глубины пересекающих окно многоугольников в углах окна, эти
многоугольники как бы продолжаются таким образом, чтобы они
покрывали все окно. В этом случае, если «продолженный» многоугольник экранируется охватывающим, то это справедливо и для
реального пересекающего многоугольника (рис. 1.74, а). Если же
несущая пересекающий многоугольник плоскость не экранируется
охватывающим окно многоугольником, то не ясно, будет или нет
закрыт от наблюдателя многоугольник, лежащий в этой плоскости
(рис. 1.74, б). Для разрешения подобных ситуаций текущее окно
подвергается разбиению на подокна. Понятно, что для вычисления
глубины несущей многоугольник плоскости в углу окна (величина
z0) необходимо в уравнение этой плоскости Ax + By + Cz + D = 0
подставить координаты угловой точки окна (x0, y0). Тогда искомая
глубина z0 = – (D + Ax0 + By0)/C.
Итак, первым в блоке принятия решения обрабатывается список охватывающих окно многоугольников с целью обнаружения
ближайшего к наблюдателю охватывающего многоугольника. Затем обрабатывается список пересекающих и внутренних многоугольников для того, чтобы проверить, не экранируются ли все они
охватывающим многоугольником. Список внешних многоугольников игнорируется, поскольку такие многоугольники не видны в
анализируемом окне.
Блок управления в тех случаях, когда в анализируемом окне
изображение классифицируется как сложное, выполняет деление
текущего окна на подокна и поочередно передает вновь образованные области экрана на повторное исследование в блок просмотра.
Кроме этого, блок управления учитывает информацию, полученную алгоритмом на предыдущих итерациях, запоминая номер
шага, на котором многоугольник впервые попадает в тот или иной
список. Действительно, если многоугольник охватывает окно, то
очевидно, что он охватывает и все подокна этого окна и его можно
сразу поместить в соответствующий список без дополнительного
тестирования. Если же многоугольник является внешним по отношению к окну, то он будет внешним и для всех его подокон, и его
можно также не тестировать при обработке этих подокон.
Эффективность описанного алгоритма Варнока можно увеличить, сократив число анализируемых на каждом шаге многоуголь101
Охватывающий
многоугольник
A
О
К
Н
О
Z
X
B
Z текmax
Z omin
Z текmax
Рис. 1.75
ников по отношению к текущему окну. Для этого необходимо провести сортировку многоугольников, поместив в начало отсортированного списка многоугольник, ближайшая к точке наблюдения
вершина которого находится ближе всех аналогичных вершин
других многоугольников. Если наблюдатель находится в положительном направлении оси Z, то многоугольник с максимальным
значением координаты z будет ближайшим к точке наблюдения (он
и будет помещен в начало списка). При обработке каждого окна алгоритм ищет охватывающий его многоугольник. Когда такой многоугольник будет обнаружен, запоминается значение координаты
z его самой удаленной от наблюдателя вершины (обозначим эту величину zomin). При обработке очередного многоугольника из отсортированного списка сравнивается координата z его ближайшей к
наблюдателю вершины (величина zтекmax) с zomin. Если выполняется условие zтекmax < zomin, то очередной многоугольник экранируется охватывающим и не должен больше учитываться. В противном случае он будет обрабатываться в дальнейшем. Таким образом,
анализ многоугольников из отсортированного списка можно прекратить досрочно. Следует учесть, что это условие является достаточным, но не является необходимым (рис. 1.75). Многоугольник А
больше можно не учитывать, а многоугольник, помеченный буквой
В, который также экранируется охватывающим многоугольником,
все еще будет учитываться.
Алгоритм, использующий Z-буфер
На сегодняшний день задача удаления невидимых линий и поверхностей в подавляющем большинстве графических конвейеров
(как в аппаратном, так и в программном исполнении) решается с
помощью алгоритма, использующего Z-буфер. Причины этого феномена заключаются в простоте реализации данного алгоритма и в
102
постоянном удешевлении памяти компьютеров, а, следовательно,
в ее все возрастающей доступности в необходимом для реализации
этого алгоритма объеме.
В этом алгоритме все полигоны, имеющиеся в пространственной сцене, сортируются по глубине, а затем, уже на стадии рендеринга, для получения более реалистичного изображения наиболее
удаленные полигоны из этого упорядоченного списка обрабатываются в первую очередь. Для учета взаимного расположения полигонов применяют так называемый Z-буфер – часть графической
памяти, в которой хранятся координаты Z каждого пикселя (отсюда название Z-буфер). Z-буфер определяет, какая из многих
перекрывающихся в области изображения точек наиболее близка к наблюдателю. Кроме Z-буфера в алгоритме используется буфер кадра. Этот буфер представляет собой матрицу ячеек памяти,
каждая из которых соответствует ячейке видеопамяти, хранящей
цвет одного пикселя (ячейка буфера кадра). В процессе рендеринга для очередного элемента (полигона) формируется его растровое
изображение (bitmap) и для каждого i-го пикселя этого полигона
вычисляется его глубина Zi. Если глубина Zi данного пикселя будет больше соответствующего значения в Z-буфере (т. е. обрабатываемый пиксель оказался ближе к наблюдателю, чем ранее обработанные), то в буфере кадра выполняется модификация соответствующего пикселя видеопамяти (цвета), а в соответствующую
ячейку Z-буфера видеопамяти помещается новая величина Zi. В
противном случае (т. е. если текущий пиксель полигона оказывается перекрытым прежде сформированными элементами) никакой модификации не производится. Первоначально буфер кадра
заполняется цветом фона, а Z-буфер – достаточно большим по
абсолютной величине отрицательным числом (можно взять значение координаты z самой удаленной от наблюдателя вершины
минус 1).
Для вычисления глубины (координаты z) пикселя необходимо
иметь уравнение плоскости, содержащей многоугольник:
A × x + B × y + C × z + D = 0.
Отсюда находим координату z пикселя по известным значениям
координат x и y:
A × x + B× y + D
z=.
C
103
Нетрудно заметить, что, если
в точке с координатами (x,y) получим с использованием предыдущей формулы значение z1, то в
G
точке (x + ∆x, y) имеем
D
A
A
0
z = z1 - × ∆x.
X
C
Z
A
А поскольку
= const, и
E
C
∆x обычно равняется 1, то, если
Рис. 1.76
известна глубина пикселя в
точке (x,y), для вычисления глубины пикселя в точке (x + 1, y) требуется выполнить лишь одно вычитание.
Пример 1.10. Рассмотрим сцену, состоящую из двух выпуклых многоугольников (рис. 1.76). Координаты точек следующие:
A (2,0,0); B (2,5,0); C (5,5,0); D (5,0,0); E (3,0,3); F (1,3,–3);
G (6,1,–1).
Для демонстрации работы алгоритма будем использовать
Z-буфер размером 8×8 элементов (разрядность каждого элемента –
16 бит), и буфер кадра размером 8×8 элементов (примем, что цвету
фона соответствует 0, цвету прямоугольника – 1 и цвету треугольника – 2).
1) Развернем в растр прямоугольник ABCD. При этом Z-буфер и
буфер кадра будут иметь следующий вид:
Здесь достаточно большое по абсолютной величине отрицательное число, которым в начале работы алгоритма заполняется
Z-буфер, не показано.
Y
F
B
7
6
5
4
3
2
1
0
C
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 1 2 3 4 5 6 7
Zбуфер
7
6
5
4
3
2
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0 0 0 0 0
0 0 0 0 0
1 1 1 1 0
1 1 1 1 0
1 1 1 1 0
1 1 1 1 0
1 1 1 1 0
1 1 1 1 0
2 3 4 5 6
Буфер кадра
0
0
0
0
0
0
0
0
7
2) Развернем в растр треугольник EFG. Уравнение плоскости, содержащей треугольник: 6 × x + 26 × y + 11× z - 51 = 0. Отсюда
51 - 6 × x - 26 × y
z=
. Уравнения прямых, содержащих стороны тре11
104
9 - 2× y
угольника: ребро EF: x =
; ребро EG: x = 3 × y + 3; ; ребро FG:
3
15 - 5 × y
x =1+
.
2
Найдем точки пересечения сканирующих прямых y = const со
сторонами треугольника:
Значение y
Ребро EF
0
Значение x
Ребро EG
3
1
2
3
1
3
6
6
2
3
3,5
1
1
1
2
Ребро FG
3
Таким образом, при подсчете глубины каждого пикселя, лежащего в пределах треугольника, переменные x и y будут меняться
в пределах
Значение y
Пределы изменения x
0
3£ x £3
1
2£ x £6
2
2£ x £4
3
1 £ x £1
Тогда найденные значения z для всех пикселей, расположенных
внутри треугольника, приведены в следующей таблице:
y=0
y=1
y=2
y=3
X=3
z=3
X=2
x=3
x=4
x=5
13
z=
11
7
z=
11
1
z=
11
5
z=11
X=2
x=3
x=4
13
z=11
19
z=11
z=-
x=6
z = -1
25
11
X=1
z = -3
В результате сравнения полученных значений z с соответствующими значениями в Z-буфере изменим содержимое Z-буфера и буфера кадра, которые примут вид:
105
7
6
5
4
3
2
1
0
0
0
0
0
0
0
0
0
13/11 7/11 1/11 0 –1
0 3 0 0
0 1 2 3 4 5 6 7
Zбуфер
0
0
0
0
0
0
0
0
7
6
5
4
3
2
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
2
0
0
0
1
0 0 0 0 0
0 0 0 0 0
1 1 1 1 0
1 1 1 1 0
1 1 1 1 0
1 1 1 1 0
2 2 2 1 2
1 2 1 1 0
2 3 4 5 6
Буфер кадра
0
0
0
0
0
0
0
0
7
Если полученный буфер кадра вывести на экран, имеющий разрешение 8×8 пикселей, получим картинку, представленную на
рис. 1.77.
Следует учитывать, что от разрядности Z-буфера зависит разрешающая способность графического конвейера по глубине.
При малой разрядности (например, 8 бит) для близко расположенных элементов рассчитанные значения Z могут практически
совпасть, в результате чего картина перекрытий исказится. С
другой стороны, большая разрядность буфера требует большого
объема памяти. Компромиссными на сегодняшний день являются следующие значения разрядности Z-буфера: минимальная
разрядность – 16 бит, что обеспечивает 65536 уровней задания
глубины пикселя, профессиональные графические системы используют 32 битный Z-буфер, обеспечивающий 4 294 967 296
уровней задания глубины.
В заключение данного раздела следует отметить, что помимо
рассмотренных здесь алгоритмов существует немало других способов удаления невидимых линий и поверхностей. Применение
конкретного алгоритма для решения поставленной задачи удаления невидимых поверхностей определяется рядом факторов,
в частности, таких как: тип объектов в пространственной сцене,
заданная степень реалистичности изображения, имеющийся в наличии объем памяти, вычислительная эффективность алгоритма,
простота его программной или аппаратной реализации. Таким
образом, для различных комбинаций перечисленных факторов
наиболее эффективным может быть тот или иной алгоритм. Выбор для изложения рассмотренных алгоритмов вызван желанием
показать различные (подчас весьма оригинальные) подходы к решению данной задачи.
106
Y
X
Рис. 1.58
a) Y
б)
t8
Y
в)
t8
Y
t6
t7
г) Y
д)
t6
X
X
X
Y
е)
t6
Y
t6
t4
t4
E
ж) Y
t2
E
t3
X
X
t3
t4
X
t6
t2
t3
t1
X
Рис. 1.64
107
Рис. 1.65
.
.
.
Прекращение
.
деления
.
(окно заливается .
цветом фона)
Прекращение
деления
(окно заливается
цветом фона)
.
.
.
.
.
.
Рис. 1.70
7
6
5
4
3
2
1
0
0
1
2
3
4
Рис. 1.77
108
5
6
7
1.3. Модели освещенности
Световая энергия, падающая на поверхность тела, может быть поглощена и, следовательно, превращена в тепло, отражена или пропущена поверхностью. Тело видимо только в том случае, если оно
отражает или пропускает свет. В случае поглощения телом всей падающей световой энергии, оно невидимо (абсолютно черное тело).
Если поглощается почти весь свет, то объект кажется черным, а если
только небольшая его часть – белым. Вообще говоря, количество поглощенной, отраженной или пропущенной световой энергии зависит от длины волны света, падающего на тело. При освещении белым
светом, в котором интенсивность всех длин волн снижена примерно
одинаково, тело выглядит серым. Если тело поглощает лишь определенные длины волн, то у света, исходящего от объекта, изменяется
распределение энергии и объект выглядит цветным.
Свойства отраженного света зависят от строения, направления и
формы источника света, от ориентации и свойств поверхности тела.
Отраженный от поверхности тела свет может также быть диффузным и зеркальным.
Диффузное отражение происходит, когда свет как бы проникает под поверхность тела, поглощается, а затем вновь испускается.
При этом положение наблюдателя не имеет значения, так как диффузно отраженный свет рассеивается равномерно по всем направлениям. Зеркальное же отражение происходит от внешней поверхности тела. Кроме этого, для изображения прозрачных или полупрозрачных объектов необходимо учитывать преломление света на
границе двух сред.
1.3.1. Диффузное отражение
Идеальное диффузное отражение предполагает наличие точечного источника света. Предполагается также, что тело идеально
рассеивает свет. Тогда, согласно закону косинусов Ламберта, интенсивность отраженного света пропорциональна косинусу угла
между направлением света и нормалью к поверхности.
Пусть Ii – интенсивность источника света; kd – коэффициент
диффузного отражения (0 ≤ kd ≤ 1 и зависит от материала поверхности тела и длины волны падающего света; в простых моделях освещения kd считается постоянным), a – угол между направлением
109
N
R
L
β
α
L¢
V
падающего света L и нормалью к поверхности тела N (рис. 1.78). Причем,
если a >π/2, то источник света расположен за телом. Тогда интенсивность
отраженного света I определяется выражением:
I = Ii × kd × cos(α).
Иными словами, поверхность будет освещена больше, если свет падает на нее перпендикулярно, и, соответственно, меньше, если свет падает
Рис. 1.78
на нее под любым другим углом (поскольку в этом случае увеличивается освещаемая площадь).
Следует отметить, что поверхность предметов, изображенных
при помощи данной модели освещения, выглядит блеклой и матовой, поскольку здесь не учитывается рассеянный свет, отраженный
от элементов окружающей обстановки. С учетом того, что используется точечный источник света, поверхности, на которые не падает прямой свет, кажутся черными. В связи с этим, для достижения
большей реалистичности изображения, необходимо учитывать неявное фоновое (рассеянное) освещение – это окружающее объект
освещение от удаленных источников, чье положение и характеристики неизвестны. Необходимость учета рассеянного освещения
обусловлена тем, что его вклад в общую интенсивность освещения
может быть достаточно велик (некоторые авторы приводят величину до 50% от общей освещенности). Считается, что рассеянное
освещение задает цвет и его интенсивность для каждого объекта в
отсутствии явных источников света или в тени (при этом цвет равномерно заливает объект).
Таким образом, на тела в реальных пространственных сценах
кроме света от точечного источника падает еще и рассеянный свет,
отраженный от окружающих предметов, например, от стен комнаты, от окружающих тел и т. п. Рассеянному свету соответствует
распределенный источник. Для расчета таких источников требуются большие вычислительные затраты. Поэтому, учитывая жесткие
требования к скорости формирования изображения, в машинной
графике распределенный источник упрощенно характеризуется
коэффициентом рассеяния. Тогда общая интенсивность отраженного света I определяется как
α¢
110
I = Ir × kr + Ii × kd × cos(α), (1.15)
где Ir – интенсивность рассеянного света; kr – коэффициент диффузного отражения для рассеянного света (0≤kr≤1).
При использовании формулы (1.15) для одинаково ориентированных относительно источника, но расположенных на разном
расстоянии от него поверхностей получим одинаковые значения
интенсивностей. Таким образом, если эти поверхности перекрываются, их невозможно различить. Это противоречит физическим законам оптики, согласно которым интенсивность света обратно пропорциональна квадрату расстояния от источника, и тело, лежащее
дальше от источника, должен быть темнее.
В компьютерной графике для решения этой задачи в качестве
коэффициента пропорциональности можно взять расстояние d от
центра проекции до объекта (в случае центрального проецирования). Но, если центр проекции лежит близко к объекту, то 1/d2 изменяется очень быстро, т. е. у поверхностей, лежащих примерно на
одинаковом расстоянии от источника света, значение интенсивностей будет значительно отличаться. Гораздо большей реалистичности изображения можно добиться при линейном затухании значения интенсивности при удалении от центра проецирования. В этом
случае модель освещения выглядит так:
I = Ir × kr +
Ii × kd × cos(α)
,
d + const
здесь const выбирается из эстетических соображений.
При ортогональной проекции, когда точка наблюдения находится в бесконечности, учет расстояния обеспечивается тем, что
поверхность, ближайшая к точке наблюдения, освещается полностью, далее расположенные – с уменьшенной освещенностью, и в
качестве d берется расстояние от поверхности, ближайшей к наблюдателю.
1.3.2. Зеркальное отражение
Очевидно, что свет, отраженный от идеального зеркала, виден
только в том случае, если угол между направлениями наблюдения
и отражения равен нулю. На практике, кроме чисто зеркального
отражения, которое имеют идеально отполированные поверхно111
сти, различают еще и распределенное зеркальное отражение – отражение не на один единственный угол, а в некотором створе углов.
Такое рассеяние света обусловлено микрорельефом («шероховатостью») поверхности (поверхность реального объекта не является
идеально гладкой, а состоит из большого количества микровыступов и впадин, которые зеркально отражают падающий свет под разными углами). Результатом распределенного зеркального отражения является яркий световой блик, размер которого определяется
степенью шероховатости поверхности. В связи с этим для большинства реальных материалов мы всегда видим зеркальную подсветку
в форме светового пятна, а не в форме яркой точки. Поэтому, для
расчета интенсивности зеркально отраженного света неидеальных
отражающих поверхностей используется формула, предложенная
Фонгом:
Is = Ii × W (λ, α) × cosn(β),
где Is – интенсивность зеркально отраженного света в точке на поверхности; b – угол между отраженным от поверхности лучом свеæ
ö
та и направлением на наблюдателя в данной точке çç- π £ β £ π ÷÷÷
è 2
2ø
(рис. 1.78); W (λ, α) – кривая отражения, зависящая от длины волны света источника λ и угла падения a; 1 £ n £ 200 – показатель
пространственного распределения зеркально отраженного света.
Необходимо учесть, что для металлических поверхностей значение
n достаточно велико (чем больше n, тем «металличестей» поверхность). Часто W (λ, α) заменяют константой ks–коэффициентом отражения, подбирая его таким образом, чтобы получаемое изображение было субъективно приемлемо. Следует отметить, что формула
Фонга не имеет физического смысла. Ее популярность обусловлена
тем, что использование данной модели дает вполне приемлемые
практические результаты.
1.3.3. Преломление света
В основных моделях освещения и алгоритмах удаления невидимых линий и поверхностей рассматриваются только непрозрачные
поверхности и объекты. Однако существуют и прозрачные объекты, пропускающие свет, например, вода, стеклянные предметы и
т. п. При переходе из одной среды в другую, например, из воздуха в
112
воду, световой луч преломляется. Преломление рассчитывается по
закону Снеллиуса, который утверждает, что падающий и преломляющий лучи лежат в одной плоскости, а углы падения и преломления связаны следующим образом:
η1 × sin(α) = η2 × sin(α ¢),
где η1 и η2 – показатели преломления двух сред; a – угол падения,
a′ – угол преломления (рис. 1.78). Ни одно вещество не пропускает
весь падающий свет, часть его всегда отражается; это также показано на рис. 1.78.
Так же, как и отражение, пропускание может быть зеркальным
(направленным) или диффузным. Направленное пропускание свойственно прозрачным веществам, например стеклу. Если смотреть
на объект сквозь такое вещество, то, за исключением контурных
линий криволинейных поверхностей, искажения происходить не
будет.
Если свет при пропускании через вещество рассеивается, то мы
имеем диффузное пропускание. Такие вещества кажутся полупрозрачными или матовыми. Если смотреть на объект сквозь такое вещество, то он будет выглядеть нечетким или искаженным.
Для того чтобы устранить влияние преломления, можно либо применять алгоритмы, работающие в пространстве объекта, либо пользоваться специальными преобразованиями между пространствами
объекта и изображения. Однако проще включить преломление в алгоритмы построения видимых поверхностей методом трассировки
лучей, использующих глобальную модель освещения (см. далее).
Простой алгоритм учета эффекта пропускание света можно
встроить в любой алгоритм удаления невидимых поверхностей,
кроме алгоритма с использованием z-буфера. Прозрачные многоугольники или поверхности помечаются, и если видимая грань прозрачна, то в буфер кадра записывается линейная комбинация двух
ближайших поверхностей. При этом интенсивность считается следующим образом:
I = I1t + (1 - t) I2 , 0 £ t £ 1,
где I1 – интенсивность в точке на видимой поверхности; I2 – интенсивность точки на поверхности, расположенной непосредственно
за видимой; t – коэффициент прозрачности видимой поверхности.
Если поверхность полностью прозрачна, то t = 0, а если непрозрачна, то t = 1. Если вторая поверхность тоже прозрачна, то алгоритм
113
применяется рекуррентно, пока не встретится непрозрачная поверхность или фон.
Для криволинейных поверхностей, например, таких, как ваза
или бутылка, линейной аппроксимации недостаточно, так как вблизи контурных линий прозрачность уменьшается из-за толщины материала. Чтобы точнее изобразить это явление, Кэй предложил несложную нелинейную аппроксимацию на основе z-составляющей
нормали к поверхности. В частности, коэффициент прозрачности:
p
t = tmin + (tmax - tmin )[1 - (1 - nz ) ],
где tmin и tmax – минимальная и максимальная прозрачность объекта; nz – z-составляющая единичной нормали к поверхности; р –
коэффициент степени прозрачности; t – прозрачность пикселя или
точки объекта.
Непосредственно в алгоритм, использующий z-буфер, эффект прозрачности ввести нельзя. Для того чтобы его учесть, необходимы отдельные буферы прозрачности, интенсивности и весовых коэффициентов, а также нужно отметить прозрачные многоугольники в структуре данных. Этот алгоритм более подробно будет описан далее.
Итак, для того чтобы включить преломление в модель освещения, нужно при построении видимых поверхностей учитывать
не только падающий, но и отраженный и пропущенный свет. Эффективнее всего это выполняется с помощью глобальной модели
освещения в сочетании с алгоритмом трассировки лучей для выделения видимых поверхностей. Обычно рассматриваются только
зеркально отраженные и пропущенные лучи, так как диффузное
отражение от просвечивающих поверхностей порождает бесконечное количество беспорядочно ориентированных лучей. Поэтому
моделируются только прозрачные вещества, для которых формула
расчета интенсивности является простым расширением описываемых далее моделей.
1.3.4. Модель освещенности Фонга
Интенсивность освещения произвольно взятой точки на поверхности, согласно модели Фонга, вычисляется следующим образом:
Io = Ir kr +
114
Ii
× (W (λ, α)cosn (β) + kd cos(α)),
d + const
где Io – общая (суммарная) интенсивность в точке на поверхности.
Остальные величины имеют тот же смысл, что и ранее. Как уже говорилось ранее, часто W(λ, α) заменяют константой ks – коэффициентом отражения, подбирая его таким образом, чтобы получаемое
изображение было субъективно приемлемо. Тогда:
Ii
Io = Ir kr +
(1.16)
(ks cosn (β) + kd cos(α)). d + const
Таким образом, в данной модели интенсивность в некоторой
точке складывается из фоновой интенсивности, интенсивности
собственно источника света, а также интенсивности рассеянного и
отраженного света от источника. Необходимо помнить, что данная
формула применяется к каждому из трех основных цветов.
Расчеты интенсивности по формуле (1.16) дают довольно реалистичный результат, но скорость вычисления этой величины для
каждой точки грани слишком низкая.
Если имеется несколько точечных источников света, то их составляющие суммируются:
Ii ( j)
Io = Ir kr + å
(ks cosn (β( j)) + kd cos(α( j))),
d
+
const
j
где j – количество источников.
Итак, модель освещенности Фонга довольно проста, а поскольку
она дает неплохие практические результаты её использование весьма распространено в системах компьютерной графики.
1.3.5. Модель освещенности со специальными эффектами
(модель направленного освещения)
В данном случае под специальными эффектами будем понимать
учет направленности и концентрации света и ограничение освещаемой источником света области. В этом случае направленный свет
представляется, как отражение от идеальной псевдоповерхности
при освещении точечным псевдоисточником (рис. 1.79). При такой
схеме одна и та же модель применяется как для направленных, так
и для точечных источников. Например, используя модель Фонга
для зеркального отражения от идеальной поверхности, получим
следующее выражение для интенсивности света вдоль прямой L:
Is = Ii ( j)cosc (β),
115
Отражающая
псевдоповерхность
Направление
света
Направленный
источник света
N
β
R
Lα
V
Псевдоисточник
Рис. 1.79
где j – номер конкретного источника света; с – характеристика пространственной концентрации направленного источника: при малых значениях c источник представляет из себя заливающий свет,
при больших – узкий луч (прожектор). С учетом сказанного, модель освещенности в случае направленного источника примет вид
Io = Ir kr + å Ii ( j)cosc (β)(ks cosn (β( j)) + kd cos(α( j))).
j
Для ограничения освещенного источником света пространства
можно использовать ряд приемов. Рассмотрим несколько наиболее
распространенных случаев.
Предположим, что имеется заслонка, пропускающая свет от источника на участке от Ymin до Ymax (рис. 1.80, a). Тогда для точки В
интенсивность от данного источника необходимо учитывать, а для
точки A нет.
Если свет от источника распространяется внутри конуса (рис.
1.80, б), то при нахождении суммарной интенсивности интенсивность от данного источника учитывается только для тех точек, для
которых угол между направлением света и направлением от источa)
б)
Заслонка
A
Источник света
B
Ymax
A
Источник света
B
�
Ymin
Конус
Направление света
Рис. 1.80
116
L
ника к данной точке меньше угла полураствора конуса (a) (в данном случае, например, для точки B). Очевидно, что лучше сравнивать не сами углы, а их косинусы.
1.3.6. Учет свойств вещества отражающей поверхности
в модели освещенности
В рассмотренных ранее моделях освещенности длина волны отраженного света совпадает с длиной волны падающего света, что не
совсем верно, поскольку не учитываются свойства вещества отражающей поверхности. Для того чтобы учесть данный фактор, используется следующая модель.
Обозначим через W телесный угол, противоположный источнику света. Тогда энергия, падающая на единичную площадь отражающей
  поверхности в единицу времени, определяется как
Et = Ii (NL)W, где Ii – интенсивность точечного источника света;


N – вектор нормали
  к поверхности; L – вектор направления падающего света; (NL) – скалярное произведение данных векторов.
Затем можем определить интенсивность отраженного света в зависимости от падающей энергии: I = REt, где R – коэффициент, состоящий из зеркальной и диффузной составляющих:
R = kdRd + ksRs; kd + ks = 1,
где Rd, Rs – коэффициенты отражения. Тогда

I = (kd Rd + ks Rs ) Ii (NL)W
и остается добавить в модель отражение рассеянного света. Предположим, что в качестве источника рассеянного света выступает
полусфера, охватывающая отражающую поверхность. Тогда интенсивность отражения рассеянного света I = fkrRrIr, где f – коэффициент затенения полусферы, значение которого определяется
отношением незатененной другими объектами части поверхности
полусферы к ее общей поверхности (0≤ f ≤1). Информацию о затененных участках поверхности можно получить на этапе удаления невидимых поверхностей и построения тени (см. далее).
Rr = kdRd + ksRs – коэффициент двунаправленного отражения рассеянного света.
117
Таким образом, модель освещенности с учетом свойств вещества
отражающей поверхности при нескольких источниках света может
быть представлена в виде:

Io = fkr Ir Rr + å Ii ( j)(kd Rd + ks Rs )(NL( j))W ( j).
j
1.3.7. Методы трассировки лучей
Метод трассировки лучей является одним из наиболее распространенных и наглядных методов построения реалистических изображений, позволяющим строить реалистические изображения
сложных сцен с учетом отражения и преломления.
Суть метода заключается в отслеживании траекторий лучей и
расчета взаимодействий с лежащими на траекториях объектами,
от момента испускания лучей источником света до момента попадания в глаз наблюдателя. Под взаимодействием луча с объектами
понимаются процессы диффузного (в смысле описанной модели
освещенности), многократного зеркального отражения от их поверхности и прохождение лучей сквозь прозрачные объекты. Таким образом, трассировка лучей – первый метод расчета глобального освещения, рассматривающий освещение, затенение (расчет
тени), многократные отражения и преломления. Различают два
основных метода трассировки лучей: метод прямой трассировки
лучей и метод обратной трассировки лучей.
Метод прямой трассировки лучей
При использовании метода прямой трассировки траектории
лучей строятся от источника ко всем точкам всех объектов сцены.
Лучи света начинают свой путь из источника и распространяются
по прямолинейным траекториям во все стороны до попадания на
объекты сцены. Попав на какой-либо объект сцены, луч света может преломиться и уйти внутрь объекта или отразиться (рассеяться). Отразившись от объекта, луч света опять распространяется прямолинейно до попадания на следующий объект, и так далее. Если
точка объекта лежит на стороне, обращенной в противоположную
от источника света сторону, точка из расчетов освещенности исключается. Для всех остальных точек вычисляется освещенность,
например, с помощью модели освещенности Фонга. Если объект
118
не является отражающим или прозрачным, т. е. поверхность объекта
только диффузно рассеивает свет,
траектория луча на этой точке заканчивается. Если же поверхность
объекта обладает свойством отражения и/или преломления, из точки строятся новые лучи, направления которых совершенно точно
определяются законами отражения
Рис. 1.81
и преломления (рис. 1.81).
Часть лучей, в конце концов, попадет в глаз наблюдателя, формируя изображение сцены на сетчатке. Поместим перед глазом
воображаемую плоскость – плоскость проекции, и будем считать,
что изображение формируется на этой плоскости. Каждый луч, попадающий в глаз, проходит через некоторую точку этой плоскости
(экрана), формируя там цвет соответствующего пикселя изображения. Таким образом, для построения изображения достаточно
проследить весь путь распространения света, начиная от его источника, до тех пор, пока либо он попадет в глаз наблюдателю, либо
покинет сцену. Однако метод прямой трассировки лучей обладает
явным недостатком – он требует больших и неоправданных вычислительных затрат. Это связано с тем, что лишь очень небольшая
часть трассируемых лучей вносит сколько-нибудь существенный
вклад в изображение сцены. Ясно, что это те лучи, которые попадают в глаз наблюдателя. По некоторым оценочным данным доля
лучей, не попавших в итоге в глаз наблюдателю, довольно велика.
Эта главная, хотя и далеко не единственная, причина того, что метод прямой трассировки лучей считается неэффективным и практически не используется.
Метод обратной трассировки лучей
В качестве альтернативы рассмотренного метода используется
метод обратной трассировки лучей. Для определения освещенности точки экрана в этом методе прослеживается путь, по которому
пришел от источника луч света, попавший в эту точку и сформировавший там изображение. Таким путем является путь луча, выходящего из глаза наблюдателя и проходящего через соответственную точку экрана. Следовательно, для построения луча имеются
119
две точки: первая – положение наблюдателя, вторая – положение
пикселя на плоскости экрана. Таким образом, направление каждого луча строго определено (две точки в пространстве определяют
одну и только одну прямую), и количество первичных лучей также
известно – это общее количество пикселей экрана.
Через каждый пиксель экрана луч трассируется до ближайшего
пересечения с одним из объектов сцены. Если пересечений с объектами нет, то луч выходит за пределы видимой части сцены, и соответствующему пикселю экрана присваивается цвет фона. Если
луч пересекается с объектом, то в точке пересечения строятся три
новых, так называемых вторичных луча (рис. 1.82).
Один луч строится в направлении источника света. Если источников несколько, строится несколько таких лучей, по одному на
каждый источник. Основное назначение этого луча – определить
ориентацию точки (обращена точка к источнику или от него), наличие объектов, закрывающих точку от источника света, и расстояние до источника света. Если точка обращена в противоположную
сторону от источника света или закрыта другим непрозрачным объектом, освещенность от такого источника не рассчитывается, точка
находится в тени. В случае затеняющего прозрачного объекта интенсивность освещения уменьшается в соответствии со степенью
прозрачности. Если точка закрыта от освещения всеми источниками сцены, ей присваивается фоновый цвет. В противном случае
точка освещена, а интенсивность и цвет освещения рассчитываются
при помощи модели освещенности (например, модели Фонга) как
сумма освещенностей от всех источников, для которых эта точка
не закрыта другими объектами. Лучи такого типа называют теневыми. Если поверхность объекта не является отражающей и непрозрачна, теневой луч – единственный тип лучей, который строится,
траектория первичного луча обрывается, и дальнейшие расчеты не
выполняются. Рассчитанный цвет (освещенности или тени) присваивается тому пикселю экрана, через который проходит соответствующий первичный луч.
Если поверхность объекта обладает отражающими свойствами –
строится второй, так называемый, луч отражения. Направление
 
  от
раженного
луча
определяется
следующим
образом:
R
=
I
2
N
(NI ),

где (NI ) – скалярное произведение векторов.
Для отраженного луча проверяется возможность пересечения с
другими объектами сцены. Если пересечений нет, то интенсивность
и цвет отраженного луча равна интенсивности и цвету фона. Если
120
пересечение есть, то в новой точке снова строится три типа лучей –
теневые, отражения и преломления.
Если поверхность объекта прозрачна – строится третий луч (луч
преломления) Направление для преломленного луча определяется
следующим образом:
 η
T= 1
η2
æ η ö2
 é
 ù 
 
η
× I - ê cos α1 + 1 × (NI )ú × N, cos α1 = 1 - ççç 1 ÷÷÷ (1 - (N × I )2 ),
ê
ú
η2
è η2 ÷ø
ë
û
где η1 и η2 – показатели преломления двух сред (первая – в которой
распространяется первичный луч, и вторая – среда прозрачного
объекта). По аналогии с предыдущим случаем проверяется пересечение вновь построенного луча с объектами пространственной сцены, и, если они есть, в новой точке строятся три новых луча, если
нет – используется интенсивность и цвет фона.
Таким образом, для каждого первичного луча строится дерево
лучей по следующему правилу. В каждой точке пересечения теневые лучи строятся всегда. Преломленный и отраженный лучи строятся при условии, что поверхность пересечения обладает свойствами отражения или преломления. Если объект такими свойствами
не обладает, в точке пересечения вычисляется освещенность, и луч
обрывается (считается, что он заканчивается на источнике света).
В идеале, процесс продолжается до тех пор, пока все лучи либо не
будут рассеяны на чисто диффузных поверхностях, либо не выйдут
за пределы видимой области (рис. 1.83).
Если древовидная структура для данного луча построена, то
расчет освещенности можно выполнить в следующем порядке.
Для каждой ветви дерева спускаемся вдоль древовидной структуры к последнему пересечению вторичного луча и поверхности (будем дальше называть их узлами). Поскольку это последний узел в
цепи, вкладов от преломлений и отражений нет. Поэтому освещенность узла вычисляется при помощи модели освещения (например,
модели Фонга) с учетом видимости источников света для данного
узла. Затем вычисленная освещенность передается вверх по ветви
к следующему ближайшему узлу. Освещенность в этом узле будет
вычисляться по формуле In = I0 + k1I1 + k2I2, где In – полная освещенность в узле n; I0 – локальная освещенность в узле n, вычисленная от источников освещения с помощью модели освещенности;
k1 – коэффициент, определяющий отражающие свойства поверхности; I1 – освещенность предыдущего узла, переданная вдоль вет121
ки отражения; k2 – коэффициент, определяющий преломляющие
свойства поверхности; I2 – освещенность предыдущего узла, переданная вдоль ветки преломления.
Таким образом, результаты освещенности накапливаются при
подъеме от самого последнего узла через все узлы ветви и для всех
ветвей одного пикселя экрана. Изображение можно считать построенным, когда цвета всех пикселей экрана (все соответствующие деревья для каждого первичного луча) вычислены.
В связи с достаточно большим числом вычислений встает вопрос: насколько глубоким может быть дерево узлов? Как далеко
прослеживаются вторичные лучи?
Естественным завершением трассировки лучей является выход
всех испущенных вторичных лучей за пределы видимой области и
их рассеяние на чисто диффузных объектах. Результат вычислений будет наиболее точным. Однако если сцена достаточно сложна, такой расчет будет очень медленным, а в некоторых случаях и
невозможным по причине ограниченности аппаратных ресурсов.
Очевидно, что вклад освещенности от каждого нового вторичного
луча очень быстро уменьшается по той простой причине, что коэффициенты свойств отражения и преломления материалов меньше
единицы. Например, если коэффициент отражения k1 считать одинаковым для всех поверхностей и равным, допустим 0,2, то вклад
четвертого отражения уменьшится до 0,0016, а общее количество
лучей к этому моменту увеличится в 12 раз (для одного источника
света и в предположении, что все объекты прозрачны и отражают
свет). Поэтому часто трассировку лучей прекращают, когда вклад
от следующего узла ветви становится меньше заданной величины.
Это также достаточно точный метод расчетов, который может быть
использован для получения качественных результатов при определенных условиях. Наконец, для получения оценочного расчета
можно оборвать трассировку лучей после выполнения заданного
количества итераций, это самый быстрый, но и наименее точный
расчет.
Основные достоинства рекурсивного метода обратной трассировки лучей – расчет теней, многократных отражений и преломлений,
значительно повысивших реалистичность изображаемых пространственных сцен. Основными недостатками метода являются неучет
вторичного освещения от диффузно отраженного объектами света;
низкая скорость и высокая вычислительная стоимость расчетов, в
результате от 70 до 95 процентов всего времени расчетов тратится
122
на вычисление пересечений; резкие границы цветовых переходов
тени/подсветок/прозрачности; “зазубренность″ линий и т. д.; дискретность определяющих цвет пикселя первичных лучей – одного
первичного луча недостаточно для корректного определения цвета
пикселя, формирующего изображение. Тем не менее, метод обратной трассировки лучей – первый метод расчета глобальной освещенности, учитывающий взаимное влияние объектов сцены друг
на друга.
Для преодоления недостатков классического метода обратной
рекурсивной трассировки лучей были предложены алгоритмы
следующего поколения, основная идея которых состоит в том, что
через каждый пиксель экрана испускается не один, а несколько
первичных лучей. Затем вычисленные значения интенсивности
первичных лучей в пределах одного пикселя усредняются (следует
учитывать, что достижение в этом случае достаточно хорошего качества изображения дается ценой значительного увеличения времени расчетов). В качестве примеров подобных алгоритмов можно
отметить Distributed Ray Tracing (DRT) или Stochastic Ray Tracing
(см. http://www.fcenter.ru/online.shtml?articles/hardware/videos
/8749). Основная идея distribute ray tracing состоит в том, что три
типа вторичных лучей классического алгоритма обратной трассировки лучей – теневой, отражения и преломления, “расщепляются″ на несколько дополнительных лучей, распространяющихся в
направлении “родительского″ луча. Для каждого из расщепленных
лучей находится значение освещенности, а освещенность в точке,
откуда они были излучены, вычисляется как усредненное значение
этих интенсивностей. По сути, вместо одного вторичного луча мы
просто используем несколько и усредняем полученные значения
интенсивности.
Дальнейшее движение в сторону улучшения реалистичности
изображения привело к созданию алгоритма, позволяющего учесть
вторичное диффузное освещение, алгоритма radiosity, или метода
излучательности. Одним из разновидностей этого метода является
метод фотонных карт, суть которого состоит в расчете освещенности точек поверхности трехмерных объектов в два прохода. На первом проходе выполняется прямая трассировка испущенных источником света полных траекторий лучей от момента их испускания
источником через все возможные многократные взаимодействия с
поверхностями и до момента поглощения света какой-либо из них.
Результат отслеживания траекторий сохраняется в базе данных,
123
получившей название “фотонная карта″. На втором проходе выполняется расчет освещенности пикселей изображения методом обратной стохастической трассировки лучей с использованием данных
фотонных карт. Подробное рассмотрение этих методов выходит за
рамки данного пособия. Заинтересованный читатель может ознакомиться с ними, например, здесь: http://www.fcenter.ru/online.
shtml?articles/hardware/videos/8924.
1.4. Тени
Для создания реалистичных изображений необходимо использовать алгоритмы прорисовки теней. Очевидно, в том случае, когда
положения наблюдателя и источника света совпадают, тени не видны. Однако как только наблюдатель (либо источник света) перемещается в любую другую точку, появляются тени.
В настоящее время существует целый ряд алгоритмов прорисовки теней, которые характеризуются как различной скоростью расчетов, так и разным качеством прорисовки теней. Выбор того или
иного алгоритма определяется поставленной перед вами задачей.
Приведем несколько наиболее простых, и в то же время достаточно
эффективных алгоритмов.
Вычислительная сложность алгоритмов построения теней зависит от положения источника света. Если источник света помещен
в бесконечность, тени определяются с помощью ортогонального
проецирования. Если источник света расположен на конечном расстоянии, используется центральная проекция.
Собственно тень состоит из полутени (soft shadows) и полной тени
(hard shadows). Полная или четкая тень – это центральная, темная,
резко очерченная часть, а полутень или мягкая тень – окружающая ее более светлая часть. Из-за больших вычислительных затрат
в компьютерной графике, как правило, рассматривается только
полная тень, которая получается, как показано на рис. 1.84 и которая образуется точечным источником света.
Распределенные источники света конечного размера создают
как тень, так и полутень: в полной тени свет вообще отсутствует,
а полутень освещается частью распределенного источника. В этом
случае от объекта получается не одна тень, а целая серия теней,
которые накладываются друг на друга и образуют более или менее
124
затемнённые области, как показано на рис. 1.85, которые и составляют основную тень и область полутени.
Все алгоритмы прорисовки тени строят чёткие тени. Некоторые
из них способны размывать полученную тень, создавая псевдополутень.
Наиболее часто используемые алгоритмы построения тени рассмотрены далее.
1.4.1. Преобразование «на землю»
Преобразование «на землю» является одним из первых алгоритмов построения тени; он прост в реализации и достаточно быстро
строит тени хорошего качества. Данный алгоритм часто используется для просчета резких теневых участков от полигональных
объектов на ровную поверхность. Например, вы можете применить
этот алгоритм в тех заданиях, которые вам предлагаются в данном
курсе. Применение этого алгоритма ограничено построением резких теневых участков от полигональных объектов на ровную поверхность. Идея его состоит в том, что для каждого полигона сцены, создается другой полигон, который, по существу, и будет тенью
первого. Все вершины полигона тени будут находиться в пределах
плоскости, на которую производится проекция.
Алгоритм основан на построении уравнения для проектирования полигона «на землю»(т. е. на плоскость y = 0), в направлении
от точечного источника света. При этом различают два случая:
− источник света находится в бесконечности (параллельно направленный свет);
− локальный источник света (точечный источник на фиксированном расстоянии от объекта).
Если объект освещен несколькими точечными источниками,
то необходимо рассчитать несколько его “теневых проекций″ (для
каждого источника в отдельности).
Источник света в бесконечности
В случае бесконечно удалённого источника света предполагается, что лучи света, приходящие к объекту, параллельны. Это
упрощает алгоритм построения тени, поскольку здесь необходимо
решить уравнение проекции только один раз и применять полученное решение ко всем вершинам объекта (рис. 1.86).
125
Итак, дана точка источника света с координатами (xL, yL, zL) и
вершина объекта (точка P) с координатами (xP, yP, zP). Необходимо
получить проекцию вершины объекта на плоскость y = 0, т. е. точку тени S с координатами (xS, yS, zS).
xP - xS xL - xP
=
.
yP - yS
yL - yP
Решая это уравнение относительно xS, получаем:
æ x - xP ÷ö
xS = xP - (yP - yS )çç L
÷.
çè yL - yP ÷ø
Из подобных треугольников следует, что
Если обозначить вектор из точки P к источнику света через
V = L – P, и учитывая, что проецирование осуществляется
на плоскость y = 0 (т. е. ys = 0), то точку S можно выразить как
y
y
xS = xP - P × xV . Обозначим α = P . Аналогично получим:
yV
yV
y
zS = zP - P × zV .
yV
Переходя к векторной форме записи, получим:
S = P - αV .
А в матричной форме:
S = [xS
yS
zS ]= PMS = [xP
yP
é 1
ê
ê x
zP ]× êê- V
ê yV
ê 0
ëê
0
0
z
0 - V
yV
0
1
ù
ú
ú
ú
ú.
ú
ú
ûú
Теперь, зная координаты точки P в мировом координатном пространстве, можно получить её проекцию на плоскость y = 0 просто
путём умножения на матрицу MS.
Локальный источник света
Описанные ранее уравнения для бесконечно удалённого источника света могут быть обобщены для случая, когда источник света
находится на конечном расстоянии от объекта. В этом случае необходимо выполнять дополнительные вычисления для каждой вершины, так как каждая вершина имеет, в общем случае, своё собственное направление на источник света (рис. 1.87).
126
Итак, в этом случае также S = P - α(L - P). Как и в предыдущем
случае, проецирование осуществляется на плоскость y = 0, и в этом
случае
yP
α=
,
yP - yL
тогда
xS =
xL yP - xP yL
z y - zP yL
; zS = L P
.
yP - yL
yP - yL
Перейдя к однородным координатам, можно использовать матричную форму записи в виде: S = PNS, где NS – матрица вида:
é-yL 0
0
0 ù
ê
ú
ê xL 0 zL
1 ú
ê
ú,
NS = ê
0 -yL
0 úú
ê 0
ê 0
0
0
-yL úûú
ëê
S и P – векторы соответствующих точек, представленные в однородных координатах. Осуществив умножение на матрицу NS,
затем разделим первую и третью компоненты pезультирующего
вектора на четвертую, получим искомые координаты точки S
(т. е. осуществим обратный переход от однородных координат к
декартовым).
Пример 1.11. Полигон ABC отбрасывает тень от источника света L на плоскость y = 0 и при этом формируется полигон Sa Sb Sc
(рис. 1.88). Получим точку Sa для тени, которую отбрасывает точка
A. Пусть точка A имеет координаты (5, 4, 2), а источник света расположен в точке L c координатами (10, 9, 1). Перейдя к однородным
координатам, получим A = [5 4 2 1], L = [10 9 1 1]. Для получения
однородных координат точки Sa выполним линейное преобразование Sa = ANS.
é-9 0 0
0ù
ê
ú
ê 10 0 1
1ú
ú
Sa = [5 4 2 1]× êê
ú = [-5 0 -14 -5].
ê 0 0 -9 0 ú
ê 0 0 0 -9 ú
êë
úû
Для обратного перехода к декартовым координатам разделим
первую и третью компоненты результирующего вектора на четвер127
тую (вторая тождественно равна нулю). Итак, искомая точка Sa
имеет координаты (1, 0, 2.8).
Проделав то же самое для двух других вершин В и С, получим
точки Sb и Sc. А теперь, имея координаты вершин, закрасить полигон обычным методом не представляет труда.
Ту же самую процедуру можно осуществить несколько иначе
(см. рис. 1.88). По существу, это то же самое преобразование, но оно
нам понадобиться для более простого объяснения алгоритма просчета теней на произвольных поверхностях. Итак:
1. Создадим вектор от источника света до рассматриваемой
в данный момент вершины (сначала это вершина A): V = A – L.
2. Удлиним вектор так, чтобы он коснулся нашей плоскости
y = 0: V = V((y1 + y2)/y1). Здесь y1 + y2 – расстояние от источника света до плоскости y = 0; y2 – расстояние от точки А до той же
плоскости. Поскольку плоскость горизонтальна и проходит через
начало координат, то значения y1 и y2 легко определить (y2 – это Y
координата вершины А, a (y1 + y2) – Y координата точки L).
3. Сложив вектор с точкой источника света, получим точку вершины полигона тени: Sa = L + V.
Убедимся, что полученный результат не изменился. Для нашего
примера:
1. V = A – L = [5 4 2] – [10 9 1] = [– 5 – 5 1].
2. V = V((y1 + y2)/y1) = [– 5 – 5 1]*9/5 = [– 9 – 9 1.8].
3. Sa = L + V = [10 9 1] + [– 9 – 9 1.8] = [1 0 2.8].
Как вы убедились, результат получился тем же самым.
Просчет теней на произвольных поверхностях
в случае локального источника света
Данная процедура аналогична алгоритму проецирования «на
землю», только здесь несколько сложнее определить значения y1 и
y2. Для начала необходимо определить поверхность. Есть несколько методов, но здесь мы рассмотрим метод, когда поверхность определяется одной точкой плоскости и вектором, исходящим из точки
и перпендикулярным поверхности (нормалью) (рис. 1.89).
Предположим, что вектор нормали есть (Na, Nb, Nc), а координаты точки в пространстве – (Px, Py, Pz). Расстояние (R) от этой точки
до поверхности определяется следующим образом:
(Na × Px + Nb × Py + Nc × Pz )
R=
.
N2a + N2b + N2c
128
В приведенной формуле мы считаем, что поверхность проходит
через начало координат. В остальном процедура точно такая же,
как та, что рассматривалась в конце предыдущего примера.
В заключение описания алгоритма прорисовки тени «на землю»
следует отметить, что при работе с данным алгоритмом следует учитывать некоторые нюансы. Так, метод прорисовки тени «на землю»
будет прорисовывать тень даже в том случае, если источник света
находится между полигоном и поверхностью. Более того, даже в
том случае, если источник света находится вообще по другую сторону поверхности. Чтобы исключить подобные вещи, необходимо
или отслеживать наступление указанных условий, или исключить
их наступление в принципе.
1.4.2. Совмещение процедур удаления
невидимых поверхностей и построения теней
Алгоритм построения тени можно рассматривать, как двухшаговый процесс удаления невидимых поверхностей: для положения
каждого источника света и для точки наблюдения. Рассмотрим
сцену на рис. 1.90. Источник света находится спереди слева от параллелепипеда в бесконечности. Точка наблюдения – сверху справа от объекта. Координаты точек следующие:
B1 = (0, 0, 0), B2 = (6, 0, 0), B3 = (6, 0, 6), B4 = (0, 0, 6),
P1 = (1, 0, 3.5), P2 = (2, 0, 3.5), P3 = (2, 0, 5), P4 = (1, 0, 5),
P5 = (1, 3, 3.5), P6 = (2, 3, 3.5), P7 = (2, 3, 5), P8 = (1, 3, 5).
В данном случае имеем собственную тень и проекционную. Собственная тень получается тогда, когда сам объект препятствует попаданию света на некоторые его грани (в данном случае на правую
грань параллелепипеда). При этом алгоритм построения теней аналогичен алгоритму удаления невидимых граней. Грани, затененP8
B4
Z
P5
P7
P4
Y
P6 B1
P1
P2
B2
P3
B3
X
Рис. 1.90
129
ные собственной тенью, являются невидимыми, если точку наблюдения совместить с источником света.
Проекционная тень получается тогда, когда один объект препятствует попаданию света на другой (на рис. 1.90 – тень на горизонтальной плоскости). Для построения таких теней необходимо
получить проекции всех невидимых граней объектов сцены. Центр
проекции при этом находится в источнике света. Точки пересечения проецируемой грани со всеми другими плоскостями образуют
многоугольники, которые помечаются как теневые. Для ускорения процесса можно проецировать контур каждого объекта, а не
отдельные грани.
После этого строится образ сцены из заданной точки наблюдения. Необходимо помнить, что для создания образов сцены из разных точек наблюдения нет необходимости строить тени заново, так
как они зависят только от положения источника света и не зависят
от положения наблюдателя.
Для того чтобы найти собственные тени, необходимо определить
невидимые грани относительно положения источника. Составим
матрицу описания параллелепипеда
é-1 1
ê
ê0
0
ê
V =ê
0
0
ê
ê 2 -1
ëê
0 0
0
0 ù
ú
1 -1 0
0 ú
ú,
0 0 -1
1 úú
0 3
5 -3,5úûú
здесь столбцы от первого до шестого содержат коэффициенты уравнений плоскостей, содержащих соответственно правую, левую,
нижнюю, верхнюю, ближнюю и дальнюю грани параллелепипеда,
если смотреть на преобразованный объект из бесконечности с положительной полуоси z. Вектор от источника света к объекту в однородных координатах E = P2 – P8 = [1 –3 –1,5 0].
Находим скалярное произведение E × V = [-1 1 -3 3 1,5 -1,5].
Знак минус означает, что при наблюдении из положения источника правая, нижняя и дальняя грани являются нелицевыми и, следовательно, находятся в собственной тени.
Как уже отмечалось, существует несколько способов нахождения
проекционных теней. Рассматриваемый в этом разделе заключается
в том, чтобы перенести и повернуть параллелепипед вместе с плоскостью его основания до совмещения вектора направления на источник с осью z. Источник находится в бесконечности, поэтому ортого130
нальная проекция видимых граней на преобразованную плоскость
основания даёт проекционную грань. Значение z получается подстановкой (x, y) координат вершин преобразованного параллелепипеда
в уравнение преобразованной плоскости основания. Затем координаты проекционных теней проводятся к первоначальной ориентации.
Для совмещения направления света, падающего из бесконечности вдоль прямой Р8Р2, с осью z необходимо выполнить следующую последовательность преобразований:
− перенести Р2 в начало координат;
− выполнить поворот на 33,69° вокруг оси у, чтобы Р4 совпала
с осью z;
− выполнить поворот на 59,04° вокруг оси x, чтобы Р8 совпала
с осью z.
Совместив последовательность этих преобразований в одну матричную операцию, получим матрицу T вида:
é 0,83
0,48 -0,29 0ù
ê
ú
ê 0
0,51
0,86 0ú
ê
ú.
T=ê
ú
0
,
55
0
,
71
0
,
43
0
ê
ú
ê-3,59 1,53 -0,93 1ú
ëê
ûú
Преобразуя плоскость основания и параллелепипед умножением на матрицу T, получим:
− преобразованные точки плоскости основания:
é0 0 0 1ù
é-3.59 1.53 -0.93 1ù
ê
ú
ê
ú
ê6 0 0 1ú
ê 1.39
4.41 -2.67 1ú
ê
ú
ê
ú.
ê6 0 6 1ú × T = ê 4.69
0.15 -0.09 1úú
ê
ú
ê
ê0 0 6 1ú
ê-0.29 -2.73 1.65 1ú
êë
úû
êë
úû
− преобразованные вершины параллелепипеда:
é1 0 3.5 1ù
é-0.84 -0.48 0.29 1ù
ê
ú
ê
ú
ê2 0 3.5 1ú
ê 0
0
0
1ú
ê
ú
ê
ú
ê2 0 5 1ú
ê 0.82 -1.06 0.64 1ú
ê
ú
ê
ú
ê1 0 5 1ú
ê
-1.54 0.93 1úú
ê
ú ×T = ê 0
ê1 3 3.5 1ú
ê-0.84 1.06 2.87 1ú .
ê
ú
ê
ú
ê
ú
ê
ú
1.54 2.58 1ú
ê2 3 3.5 1ú
ê 0
ê
ú
ê
ú
0.47 3.22 1ú
ê2 3 5 1ú
ê 0.82
ê
ú
ê
ú
êë1 3 5 1úû
êë 0
0
3.51 1úû
131
Уравнение преобразованной плоскости основания найдём методом Ньюэлла:
z = –0.6y.
Подставляя (х, у) координаты вершин преобразованного параллелепипеда в уравнение плоскости, определим z, что даёт проекцию тени на плоскость основания:
P1¢ = [-0.84 -0.48 0.29 ]
P2¢ = [0 0 0 ]
P3¢ = [0.82 -1.06 0.64 ]
P4¢ = [0 -1.54 0.93]
P5¢ = [-0.84 1.06 -0.64 ]
P6¢ = [0 1.54 -0.93]
P7¢ = [0.82 0.48 -0.29 ]
P8¢ = [0 0 0 ],
где штрих обозначает вершину проекционной тени.
Из положения источника видны только передняя, левая и верхняя грани; они и порождают проекционные тени:
− передняя: Р3Р4Р8Р7 – Р3′Р4′Р8′Р7′
− левая: Р1Р4Р8Р5 – Р1′Р4′Р8′Р5′
− верхняя: Р7Р8Р5Р6 – Р7′Р8′Р5′Р6′
Отметим, что ни одна видимая грань не содержит точку Р2; поэтому её проекция P2′ не входит в видимые проекционные тени.
Обратным преобразованием, т. е. T–1, построенные проекционные
тени переводятся в исходную ориентацию:
é1
ê
ê2
ê
ê2
ê
ê1
1
S = P ¢T = êê
ê2
ê
ê3
ê
ê3
ê
êë2
132
0
0
0
0
0
0
0
0
3.5
3.5
5
5
2
2
3.5
3.5
1ù S1
ú
1ú S2
ú
1úú S3
1úú S4
.
1úú S5
ú
1ú S6
ú
1ú S7
ú
1úû S8
Проекциями теней на плоскость основания будут S3S4S8S7,
S1S4S8S5, S7S8S5S6, S4S8S7, S1S4S8S5, S7S8S5S6, а общим контуром будет ломаная S1S5S6S7S3S4.
Ha рис. 1.90 показан результат после поворота на –45° вокруг
оси у и затем на 35° вокруг оси х. Точка наблюдения находится в
бесконечности на положительной полуоси z. Правая грань видима,
но находится в собственной тени, поэтому она выглядит чёрной.
Проекционная тень тоже выглядит чёрной, причём при наблюдении из заданной точки часть её оказывается невидимой.
Совмещение процедур удаления невидимых поверхностей
и построения теней в алгоритме построчного
сканирования Уоткинса
Идея совмещения процессов построения теней и удаления невидимых поверхностей была использована во многих алгоритмах.
В частности, процедура построения теней в алгоритме построчного
сканирования Уоткинса осуществляется в два этапа.
На первом этапе для каждого многоугольника сцены и каждого
источника света определяются самозатененные участки и проекционные тени. Они записываются в виде двоичной матрицы, в которой
строки – многоугольники, отбрасывающие тень, а столбцы – затеняемые многоугольники. Единица в матрице означает, что грань
может отбрасывать тень на другую, нуль – что не может. Единица
на диагонали соответствует многоугольнику в собственной тени.
Если сцена состоит из n многоугольников, то возможно n(n – 1)
проекционных теней, поэтому важно найти эффективный способ
получения матрицы. Рассмотрим для иллюстрации несложный
пример.
Для простой сцены на рис. 1.90 матрицу теней можно составить на основе непосредственного наблюдения. Результат приведён
в табл. 1.
Обычно матрица включается в связный список, объединяющий
тени и многоугольники.
Второй этап – обработка сцены относительно положения наблюдателя – состоит из двух процессов сканирования. В интервальном
алгоритме построчного сканирования Уоткинса первый процесс
определяет, какие отрезки на интервале видимы. Второй – с помощью списка теневых многоугольников находит, падает ли тень на
многоугольник, который создает видимый отрезок на данном ин133
Таблица 1
Правый
Левый
Нижний
Верхний
Ближний
Дальний
Плоскость
основания
Затеняемые многоугольники
Многоугольники,
отбрасывающие тень
Правый
Левый
Нижний
Верхний
Ближний
Дальний
Плоскость основания
1
0
0
1
1
0
0
0
0
0
0
0
0
0
0
1
1
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
1
0
1
1
1
1
1
1
0
тервале. Второе сканирование для интервала производится следующим образом:
− если нет ни одного теневого многоугольника, то видимый отрезок изображается;
− если для многоугольника, содержащего видимый отрезок,
имеются теневые многоугольники, но они не пересекают и не покрывают данный интервал, то видимый отрезок изображается;
− если интервал полностью покрывается одним или несколькими теневыми многоугольниками, то интенсивность изображаемого
видимого отрезка определяется с учетом интенсивностей этих многоугольников и самого отрезка;
− если один или несколько теневых многоугольников частично
покрывают интервал, то он разбивается в местах пересечения с ребрами теневых многоугольников. Затем алгоритм применяется рекурсивно к каждому из подынтервалов до тех пор, пока интервал
не будет изображен.
Здесь предполагается, что интенсивность видимого отрезка зависит от интенсивности теневого многоугольника. В простейшем
случае можно считать, что тени абсолютно черные. Однако если
взять источник света и два каких-нибудь предмета, то можно увидеть, что тень может быть не только такой. Интенсивность тени зависит от интенсивности источника и от расстояния между затененной гранью и гранью, отбрасывающей тень. Это вызвано ограниченным размером источника и тем, что на затененную поверхность
падает рассеянный свет.
134
Для того чтобы смоделировать такой эффект, можно установить
пропорциональную зависимость интенсивности тени и источника.
Если накладывается несколько теней, то их интенсивности складываются. Более сложных расчетов требует правило, позволяющее
сделать интенсивность тени пропорциональной как интенсивности
источника, так и расстоянию между поверхностью, на которую падает тень, и поверхностью, отбрасывающей тень.
Можно изменить алгоритм, использующий z-буфер, так, чтобы
он включал построение теней. Модифицированный алгоритм состоит из двух шагов:
1. Cтроится сцена из точки наблюдения, совпадающей с источником. Значения z для этого вида хранятся в отдельном теневом
z-буфере. Значения интенсивности не рассматриваются.
2. Затем сцена строится из точки, в которой находится наблюдатель. При обработке каждой поверхности или многоугольника его
глубина в каждом пикселе сравнивается с глубиной в z-буфере наблюдателя. Если поверхность видима, то значения х, у, z из вида
наблюдателя линейно преобразуются в значения х′, у′, z′ на виде
из источника. Для того чтобы проверить, видимо ли значение z′
из положения источника, оно сравнивается со значением теневого
z-буфера при х′, у′. Если оно видимо, то оно отображается в буфер
кадра в точке х, у без изменений. Если нет, то точка находится в
тени и изображается согласно соответствующему правилу расчета
интенсивности с учетом затенения, а значение в z-буфере наблюдателя заменяется на z′.
1.4.3. Алгоритм построения полутеней (алгоритм Кука)
В указанном алгоритме используется модель освещения Кука –
Торрэнса, где источнику конечного размера противолежит телесный угол dϖ. Поэтому, закрывая часть источника, можно уменьшить телесный угол, а, следовательно, и интенсивность падающего
от источника света. При этом соответственно снижается и отраженная интенсивность (см. рис. 1.91).
Средняя линия полутени рассчитывается в предположении, что
точечный источник находится в центре сферы. Учитывая подобие
r R
треугольников, получаем: = , где d – расстояние от точки, отd D
брасывающей тень, до соответствующей точки на средней линии
135
полутени; D – расстояние от точки, отбрасывающей тень, до центра
сферического источника; R – радиус сферического источника; r –
половина ширины полу-тени.
Если смотреть от многоугольника, отбрасывающего тень, то телесный угол источника dv (в случае, если R << D) вычисляется по
формуле
æ R ö2
dϖ = π çç ÷÷÷ ,
çè D ø
dϖ
.
π
Это означает, что если телесный угол источника меньше, то он
создает более резкую тень (т. е. с меньшим r). У точечного источника dϖ = 0, следовательно, и r = 0, поэтому полутени нет вообще.
При сближении затеняемой и затеняющей поверхности d и r уменьшаются, и тень становится резче.
Интенсивность точек полутени определяется видимой частью
источника. Для сферического источника, частично видимого от – R
до а, эта доля составляет:
поэтому половина ширины полутени равна r = d
é
ù
æ a ö÷2
1 1 êa
-1 æç a ö÷ú
ç
Afrac =
× ò 2 × R - x dx = + × ê × 1 - ç ÷÷ + sin ç ÷÷ú .
çè R ø
èç R øú
2 π êR
πR 2 -R
êë
úû
1
a
2
2
Результаты показывают, что на одном краю полутень получается более четкой. Кук рекомендует хранить эти данные в таблице цветов. Однако проще рассчитывать линейную аппроксимацию
æ
aö
Afrac = 0,5çç1 + ÷÷÷, которая дает погрешность меньше 7%.
çè
Rø
Рассмотренные в данном разделе алгоритмы представляют собой далеко не полный список того, что было придумано в области
построения теней в реальном времени, но, тем не менее, рассмотрены наиболее популярные и часто используемые методы.
136
→
R
→
I
1
→
N
α
2
α1
→
N
3
→
T
Рис. 1.82
Íàáëþäàòåëü
Ïåðâàÿ
òî÷êà
ïåðåñå÷åíèÿ
Ïðåëîìëåííû
é (refraction)
ëó÷
Òåíåâûå
ëó÷è
Ïåðâè÷íûé ëó÷
Ïèêñåëü âèäîâîãî îêíà
Òåíåâûå
ëó÷è
Îòðàæåííûé
(reflection) ëó÷
Òåíåâûå
ëó÷è
Âòîðàÿ
òî÷êà ïåðåñå÷åíèÿ
Ïðåëîìëåííûé
(refraction) ëó÷
Îòðàæåííûé
(reflection)
ëó÷
Òðåòüÿ
òî÷êà ïåðåñå÷åíèÿ
Ïðåëîìëåííûé
(refraction) ëó÷
Рис. 1.83
137
Источник направленного
параллельного света
Точечный
источник света
Объект
Объект
Четкая
тень
Четкая
тень
Рис. 1.84
Протяженный
источник света
Протяженный
источник света
Объект
Объект
Тень
Полутень
Рис. 1.85
x
L
P
S
z
Рис. 1.86
138
y
L
y
y
L
y1
A
P
B
x
y2
x
Sb
Sa
z
S
z
C
Sc
Рис. 1.88
Рис. 1.87
y
L
P
N
x
Sp
z
Рис. 1.89
R
D
Сферический
O источник света
Объект,
отбрасывающий A
тень
Полутень
d
Тень
r
Незатененная
область
Средняя линия полутени
Рис. 1.91
139
2. Рендеринг
Под термином рендеринг обычно понимают процесс создания
реалистичных изображений на экране, использующий математические модели для добавления цвета, тени и т. д. Рассмотрим этапы
рендеринга.
2.1. Cортировка по Z-буферу и смешение текстур
Полигоны, оставшиеся после удаления невидимых поверхностей (на стадии геометрических преобразований), сортируются по
глубине, а затем, уже на стадии рендеринга, для получения более
реалистичного изображения наиболее удаленные полигоны из этого упорядоченного списка обрабатываются в первую очередь. Для
учета взаимного расположения полигонов применяют Z-буфер –
часть графической памяти, в которой хранятся координаты z каждого пикселя (отсюда название Z-буфер). Алгоритм, использующий
Z-буфер, был рассмотрен в подразд. 1.2.2 данного пособия. Повторяем, что Z-буфер определяет, какая из многих перекрывающихся в области изображения точек наиболее близка к наблюдателю.
Этот буфер представляет собой матрицу ячеек памяти, каждая из
которых соответствует ячейке видеопамяти, хранящей цвет одного
пикселя (ячейка буфера кадра). В процессе рендеринга для очередного элемента (полигона) формируется его растровое изображение
(bitmap) и для каждого i-го пикселя этого полигона вычисляется
его глубина Zi. Если глубина Zi данного пикселя будет меньше соответствующего значения в Z-буфере (т. е. обрабатываемый пиксель
оказался ближе к наблюдателю, чем ранее обработанные), то выполняется модификация соответствующего пикселя видеопамяти
(цвета), а в соответствующую ячейку Z-буфера видеопамяти помещается новая величина Zi. В противном случае (т. е. если текущий
пиксель полигона оказывается перекрытым прежде сформированными элементами) никакой модификации не производится. Первоначально буфер кадра заполняется цветом фона, а Z-буфер – достаточно большим по абсолютной величине отрицательным числом.
Однако цвет пикселя видеопамяти, сформированный в результате Z-буферизации, возможно, придется модифицировать в том
случае, если перекрывающий элемент является прозрачным. Эффект прозрачности и просвечивания достигается путем смешива140
ния значений цветов исходного и результирующего пикселей. В общем случае у нас есть два значения цвета – C1 для того пикселя,
который находится ближе к наблюдателю, и C2 для того, который
расположен дальше. Результирующий цвет в ячейке видеопамяти
формируется на основе этих двух значений с учетом свойства “прозрачности″ ближнего пикселя.
Для получения нового значения цвета обычно используют так
называемый альфа-блендинг (Alpha-blending). Мерой прозрачности
объекта является коэффициент прозрачности 0 ≤ a ≤ 1 (единица соответствует полной непрозрачности). Результирующий цвет пикселя вычисляется по формуле:
C = C1α + C2(1 – α).
Причем, поскольку цвет определяется тремя значениями базисных цветов (R, G и B), то необходимо выполнить данную процедуру
три раза (соответственно для каждого базисного цвета в отдельности). Ясно, что для реализации данного метода требуется отдельный альфа-буфер, размер которого определяется числом пикселей
на экране. Часто 8-битный коэффициент прозрачности для каждого
пикселя хранят прямо в видеопамяти, поскольку при 24-битном кодировании цвета (по 8 бит на каждый из цветов (красный, зеленый
и синий)), от двойного слова (32 бит), выделяемого на пиксель для
упрощения адресации, остается, как раз, 8 бит. Такой формат видеопамяти называют RGBA. Альфа-буфер может использоваться не
только для реализации эффекта прозрачности, но и для размывки
границ или создания тумана. Типичным примером использования
смешения текстур является сцена, изображающая голубое небо с
просвечивающими белыми облаками. Смешение позволяет голубому небу проступать сквозь белые облака за счет смешения значений
двух пикселей – облака и неба – в единый пиксель.
2.2. Наложение текстуры
Наложением текстуры (texture mapping) в компьютерной графике называют процесс покрытия двумерной текстурой трехмерного
объекта (текстура как бы натягивается на объект) для придания ему
соответствующего внешнего вида. Таким образом, текстура накладывается на полигональную модель объекта для придания ему более
реалистического вида. Текстура состоит из элементов, называемых
141
текселами (Texel – Texture Element), эквивалентных пикселям
(Picture Element) экрана. Для отображения на дисплее текселы проецируются в пикселы. Текстуры (в виде матриц текселей) хранятся
в памяти. Для каждого полигона-частицы отображаемой поверхности вычисляется соответствующий ему участок текстуры – тоже полигон. Далее этот участок должен быть отображен в видеопамять –
тексели должны быть отображены в пиксели. Рассмотрим наиболее
часто используемые методы наложения текстуры.
2.2.1. Точное текстурирование (point-sampling)
Точное текстурирование является самым тривиальным способом отображения текселей в пикселы.
Пусть имеется треугольная грань в пространстве, необходимо
получить проекцию этой грани на экран и наложить на нее текстуру. Рассмотрим данную процедуру относительно произвольной точки грани (точка D(x, y, z)), которой в проекции соответствует точка
DS(Sx, Sy). Требуется найти цвет этой точки (точнее, цвет точки
текстуры, соответствующей точке DS). Следовательно, необходимо
найти координаты текстуры для той точки, проекцией которой на
экран является точка PS. Текстура накладывается линейным образом (рис. 2.1). Очевидно, нам надо каждой точке проекции грани
сопоставить соответствующую ей точку текстуры.
Пусть вершины грани объекта в пространстве заданы своими координатами: A(Ax,Ay,Az), B(Bx,By,Bz) и C(Cx,Cy,Cz), а соответствующие им точки текстуры – At(Au, Av), Bt(Bu,Bv) и Ct(Cu, Cv).
Объект в пространстве
A
v
y
Текстура
Экран
D(x,y,z)
A
B
S
.
At
C
t
t
D S (Sx, Sy)
Bt
D (Du, Dv)
u
CS
Точка
наблюдения
x
Рис. 2.1
142
C
S
B
Рассмотрим точку D, принадлежащую грани. Поскольку она
лежит внутри грани, то для нахождения ее координат можно воспользоваться следующим выражением (в векторном виде):
D = A + a(B – A) + b(C – A).
Таким образом, точка D однозначно задается парой неизвестных
коэффициентов (a,b). Поскольку текстура накладывается линейно,
то и для нахождения координат соответствующей точки текстуры
можно записать:
Du = Au + a(Bu – Au) + b(Cu – Au), Dv = Av + a(Bv – Av) + b(Cv – Av).
С другой стороны, для нахождения координат точки DS можно
воспользоваться известными выражениями для операций проецирования. Например, в случае центральной проекции, имеем:
Sx =
x
y
; Sy =
.
1 - z / z ¢¢
1 - z / z ¢¢
Здесь z ¢¢ – расстояние от начала пространственной системы координат до точки наблюдения. Если координаты x, y и z в последних уравнениях выразить через известные значения A, B, С и неизвестные коэффициенты a, b, получим:
Sx =
Ay + a(By - Ay ) + b(Cy - Ay )
Ax + a(Bx - Ax ) + b(Cx - Ax )
; Sy =
.
1 - Dz / z ¢¢
1 - Dz / z ¢¢
Таким образом, имеем систему двух линейных уравнений относительно двух неизвестных a и b. Решив ее, определим значения
неизвестных a и b, по ним найдем координаты требуемой точки
текстуры Du и Dv, а, следовательно, и ее цвет.
Вычисления, необходимые для данного метода текстурирования, достаточно трудоемки. Поэтому на практике используют приближенные вычисления, хотя и именно по этим формулам.
Стоит отметить тот факт, что на самом деле здесь грань не обязательно должна быть треугольной – можно взять любые три вершины многоугольной грани. То же самое справедливо и для остальных, описываемых далее методов текстурирования.
Итак, наложение текстуры на поверхность объектов сцены повышает ее реалистичность. Соответствие между точками на поверхности объекта и точками текстуры устанавливается с помощью специальной функции проецирования F(): (u,v) = F(x,y,z) что в общем
случае приводит к сжатию или растяжению рисунка текстуры.
143
r
z
T (u,v)
1
y
h
x
0
1
u
Рис. 2.2
Здесь, как и прежде, u, v – координаты текстуры, а x, y, z – координаты текстурируемого объекта.
Если нам требуется перенести текстуру не на плоский объект, а
на поверхность типа цилиндра или сферы, то в качестве функции
проецирования могут использоваться цилиндрическая и сферическая функции отображения.
Рассмотрим цилиндрическое отображение: имея параметрическое задание цилиндрической поверхности (θ,z), легко получить
функцию проецирования для координат текстуры (рис. 2.2). Произвольная точка кривой поверхности цилиндра радиуса r и высоты
h задается следующим образом:
(r cos θ,r sin θ, hz), 0 < θ < 2π, 0 < z < 1.
Функция проецирования в этом случае выглядит так:
(u,v) = (θ / 2π, z), u, v Î [0,1].
Отображение на сферу более трудоемко. Проецирование плоскости на сферическую поверхность приводит к полному разрушению
рисунка на полюсах. Рассмотрим в качестве примера наложение текстуры на часть сферы. Пусть эта часть задана следующим образом:
(r cos θ sin j, r sin θ sin j, r cos j),
где 0 ≤ θ ≤ π/2, π/4 ≤ j ≤ π/2.
Тогда мы можем получить координаты текстуры из соотношения:
æ θ (π / 2) - j ö÷
(u,v) = çç
,
÷.
çè π / 2 (π / 4) ÷ø
В общем случае текстурируемые поверхности не являются цилиндрическими или сферическими. Для наложения текстуры на
объекты произвольной формы применяется метод двухступенчатого отображения, суть которого в следующем:
144
1. На первом шаге двумерная область текстуры отображается на
простую трехмерную промежуточную поверхность, например, цилиндрическую:
T (u,v)  T ¢(xi, yi, zi).
Этот этап называется S-mapping.
2. На втором шаге полученная трехмерная текстура проецируется на поверхность объекта (O-mapping):
T ¢(xi, yi, zi)  O(x, y, z).
В качестве промежуточной поверхности предлагается использовать произвольно ориентированную плоскость, кубическую, цилиндрическую или сферическую поверхности, выбор одной из которых зависит, прежде всего, от геометрической формы поверхности
текстурируемого объекта. Существует также несколько вариантов
операции O-mapping (рис. 2.3). Соответствия между координатами
могут быть получены следующим образом:
1. Цвет точки (x, y, z) на поверхности объекта определяется цветом точки (xi, yi, zi), являющейся точкой пересечения луча, исходящего из точки наблюдения и отраженного от поверхности объекта,
с промежуточной поверхностью T′.
2. Цвет точки (x, y, z) на поверхности объекта определяется цветом точки (xi, yi, zi), являющейся точкой пересечения нормали к
поверхности объекта в точке (x, y, z), с промежуточной поверхностью T′.
3. Цвет точки (x, y, z) на поверхности объекта определяется цветом точки (xi, yi, zi), являющейся точкой пересечения линии, проходящей через (x, y, z) и центр тяжести объекта, с промежуточной
поверхностью T′.
4. Цвет точки (x, y, z) на поверхности объекта определяется цветом точки (xi, yi, zi), являющейся точкой пересечения линии, идущей из (x, y, z) к T′, ориентация которой задается нормалью к T′ в
точке (xi, yi, zi).
Главным недостатком точного текстурирования является тот
факт, что когда полигон расположен близко к экрану, количество
пикселей будет значительно выше, чем текселей, следовательно,
качество изображения очень сильно пострадает (возникает так называемый эффект блочности (эффект больших квадратов, особенно
при приближении наблюдателя к текстурированной поверхности),
145
который достаточно ощутимо проявлялся в компьютерных играх
прошлых поколений).
Тем не менее, данный метод обладает рядом преимуществ, основным из которых является тот факт, что определение цвета пикселя
осуществляется всего по одному текселю, что, в свою очередь, требует относительно мало ресурсов 3D-акселератора.
2.2.2. Аффинное текстурирование
Этот метод текстурирования основан на приближении координат текстуры (u, v) линейными функциями (рис 2.4). Итак, пусть
u = k1Sx + k2Sy + k3. Необходимо найти k1, k2, k3, зная координаты точки на экране – (Sx, Sy). Предположим, что грань рисуется
построчно (y = const – сканирующая прямая). Вершины грани заранее отсортируем по координате y. Зная уравнения прямых, содержащих ребра грани, для каждой строки (сканирующей прямой)
можно посчитать начальное значение xSt (в точке пересечения сканирующей прямой с ребром грани), uSt (считается точно так же как
xSt, поскольку u вдоль прямой меняется тоже линейно), а также
длину этой строки (L):
xSt = Ax + (m – Ay)(Cx – Ax)/(Cy – Ay)
uSt = Au+ (m – Ay)(Cu – Au)/(Cy – Ay)
xEnd = Ax + (m – By)(Bx – Ax)/
(By – Ay)
L = |xSt – xEnd|
Нетрудно заметить, что поскольку u =
k1Sx + k2Sy + k3, то при переходе к следующему пикселю строки u изменяется
на k1. Этот коэффициент считается таким образом:
(A x ,A y )
(xEnd,m)
(xSt,m)
y =m
(Cx ,C y )
(Bx ,By )
Рис. 2.4
146
xSt = Ax + (By – Ay)(Cx – Ax)/(Cy – Ay)
uSt = Au + (By – Ay)(Cu- Au)/(Cy – Ay)
xEnd = Bx
uEnd = Bu
k1 = ( uSt – uEnd)/(xSt – xEnd)
Следовательно, k1 – некоторое число, постоянное для всей грани, поэтому считать его надо один раз. Координата v рассчитывается аналогичным образом – просто во всех приведенных формулах u
меняется на v.
2.2.3. Перспективно-корректное текстурирование
В данном случае координаты текстуры (u, v) интерполируются
кусочно-линейными функциями. При изображении каждая строка
разбивается обычно на отрезки длиной 8 (или 16 или 32 пикселя)
и плюс один оставшийся отрезок произвольной длины. В начале и
конце каждого отрезка считаются точные значения u, v, а внутри
отрезка они интерполируются линейно.
Точные значения u и v, в принципе, можно считать по формулам описанным ранее (см. описание метода точного текстурирования), но обычно используют более простой путь. Пусть Z = 1 – z/z″.
Нетрудно заметить, что величины 1/Z, u/Z и v/Z зависят от Sx, Sy
линейно. Следовательно, достаточно для каждой вершины грани
посчитать 1/Z, u/Z, v/Z и линейно их интерполировать – точно так
же, как интерполируются u и v в предыдущем разделе. Причем, так
как эти значения зависят от Sx, Sy линейно, то интерполяция дает
не приближенные результаты, а абсолютно точные. Затем уже считаем точные значения u и v:
u = (u/Z)/(1/Z), v = (v/Z)/(1/Z).
При прорисовке грани на ребрах интерполируются не u и v (см.
предыдущий подраздел), а 1/Z, u/Z и v/Z. Расчет точных значений
u и v в конце каждого отрезка не вызывает никаких затруднений,
поскольку значения 1/Z, u/Z и v/Z в начале отрезка уже получены,
меняются они линейно и длина отрезка известна (8, 16 или 32 пикселя, либо длина остатка).
2.2.4. Параболическое текстурирование
Этот метод основан на приближении координат текстуры (u, v)
квадратичными функциями. Для каждой строки (сканирующей
прямой) строятся аппроксимирующие u и v квадратичные функции. Затем с помощью полученных функций они интерполируются
147
по строке (сканирующей прямой). Для этого необходимы точные
значения u и v в начале, середине и конце строки. Их можно посчитать точно так же, как описано в предыдущем разделе.
Итак, пусть у нас есть точные значения u в начале, середине и
конце строки. Обозначим их соответственно через ua, ub и uc. Мы
пытаемся аппроксимировать u квадратичной функцией, т. е. полагаем, что u = Ax2 + Bx + C, где x – расстояние от текущей точки до
начала строки. Тогда, подставив в формулу ua, ub и uc и соответствующие им x, получаем (зная заранее длину строки L):
ua = C
ïìï
ïï
2
íub = AL / 4 + BL / 2 + C .
ïï
ïï u = AL2 + BL + C
c
ïî
Решая эту систему, находим коэффициенты А, В, С.
Теперь посчитаем, как меняется u при переходе вдоль строки закраски к следующему пикселю:
∆u(x) = u(x + 1) - u(x) = A (x + 1)2 + B(x + 1) + C - Ax2 - Bx - C =
= A (2x + 1) + B.
Посчитаем также величину ∆∆u:
∆∆u(x) = ∆u(x + 1) - ∆u(x) = A (2 × (x + 1) + 1) + B - A (2x + 1) - B = 2 A.
Поскольку начальные значения u(0), ∆u(0), ∆∆u известны, то
можно организовать рекуррентные вычисления значения u в любой точке закрашиваемой строки:
u(1) = u(0) + ∆u(0),
u(2) = u(1) + ∆u(1),
u(3) = u(2) + ∆u(2),
...
∆u(1) = ∆u(0) + ∆∆u
∆u(2) = ∆u(1) + ∆∆u
∆u(3) = ∆u(2) + ∆∆u
Координата v рассчитывается аналогичным образом – просто во
всех приведенных формулах u меняется на v.
2.2.5. Билинейная фильтрация текстур
В реальной жизни цвет поверхности, как правило, не меняется
скачком при переходе к рассмотрению соседнего участка, а являет148
ся непрерывной, плавно изменяющейся функцией. В графических
же системах при обычном текстурировании получают координаты
в текстуре, округляют их до ближайшего целого числа и выбирают
нужный цвет из текстуры. Таким образом, значение цвета берется в самой близкой к рисуемой точке сетки замеров цвета, поэтому
цвет меняется скачкообразно, оставаясь непрерывным между узлами сетки, и возникает эффект больших квадратов, особенно при
приближении наблюдателя к текстурированной поверхности (так
называемый блочный эффект).
Для устранения этого эффекта используются методы текстурирования, основанные на фильтрации текстур. Наиболее простой в
этом ряду – метод билинейной фильтрации текстур, когда цвет линейно интерполируется между узлами сетки замеров. Например,
пусть в текущей точке (точка k) получили координаты текстуры
u, v – какие-то нецелые, в общем случае, числа. Тогда по целым
частям u, v определяется, между какими узлами сетки находится
данная точка, а по дробным – как близко она находится к каждому из узлов (рис. 2.5). Точки A, B, C, D – пиксели текстуры (они
же узлы сетки замера цвета), окружающие точку k. Пусть Iu, Iv –
целые части координат текстуры точки (u, v); а Fu, Fv – дробные
части. Тогда точки A, B, C, D имеют координаты в текстуре (Iu, Iv),
(Iu + 1, Iv), (Iu, Iv + 1), (Iu + 1, Iv + 1). Проинтерполируем какую-то
компоненту цвета (R, G, B) по прямым AC и BD:
a = A + (C – A)Fv, b = B + (D – B)Fv.
Теперь проинтерполируем цвет по прямой ab в нашей точке k:
k = a + b Fu.
Проинтерполировав таким образом каждую компоненту цвета,
получим цвет интересующей нас точки с
учетом билинейной фильтрации.
A
B
При использовании рассматриваемого способа текстурирования изобраa
b
k
жение получается более качественным
(отсутствует эффект блочности). Однако
близкие к экрану полигоны выглядят
расплывчато, и связано это с тем, что
для интерполяции необходимо большее
количество текселей, нежели доступные
C
D
четыре.
Рис. 2.5
149
Тем не менее, с помощью билинейной фильтрации можно получить более реалистичное изображение, поскольку здесь используются уже 4 текселя для определения цвета каждого пикселя.
2.2.6. Мипмэппинг
Если полигон находится на достаточно большом расстоянии от
наблюдателя или ориентирован в пространстве так, что соседним
пикселям на экране соответствуют сильно разнесенные точки текстуры, то возникают искажения изображения (так называемые
артефакты). Например, если посмотреть на текстурированную поверхность, значительно удаленную от наблюдателя, то вместо рисунка текстуры мы увидим фактически случайный набор точек.
Это происходит вследствие того, что при текстурировании мы выбираем лишь какую-то одну точку текстуры, а реально в экранный
пиксель в этих случаях будет проецироваться сразу несколько текселей. Эти ошибки визуализации особенно характерны при анимации, и становятся причиной мерцания во время движения и эффекта медленного движения в той части изображения, которая должна
быть неподвижной.
Очевидно, что появление артефактов вызвано использованием
текстур одного и того же размера для разноудаленных полигонов.
Следовательно, напрашивается простое решение, когда при удалении объекта от наблюдателя используемая текстура также уменьшается. Это условие обеспечивается использованием набора текстурных карт разного размера. Такой прием называется мипмэппингом (Mipmaping).
Предположим, что исходное изображение текстуры имеет размер 2n×2n. Для реализации мипмэппинга формируется набор текстурных карт, каждая из которых является уменьшенной копией
исходной текстуры (размером 2n–1×2n–1,2n–2×2n–2 и т. д.). Размер
последней текстурной карты равен одному пикселю. В результате
имеем пирамиду (mip-map), состоящую из (n + 1) уровня, где на
нижнем (нулевом) уровне находится исходная текстура. Вся пирамида занимает объем памяти, необходимый для хранения 22n – 1
пикселей.
В процессе рендеринга объекта из созданного набора выбирается та текстурная карта, которая наилучшим образом соответствует
150
размерам объекта и его расстоянию до наблюдателя, что способствует улучшению качества изображения, хотя и требует дополнительных ресурсов памяти.
Чаще всего для создания набора текстурных карт используются
следующие нехитрые процедуры:
1. Из исходной текстуры вычеркиваются те пиксели, у которых
одна из координат (заранее определенная) имеет нечетное (или четное – одно из двух) значение. Процедура тривиальна, но дает не
очень хорошие визуальные результаты.
2. Из исходной текстуры в новую переносятся те пиксели, у которых одна из координат (заранее определенная) имеет четное значение. При этом цвет пикселя в новой текстуре получается усреднением значения его исходного цвета и цвета трех соседних пикселей.
3. В результирующую текстуру переносятся пиксели, у которых
одна из координат имеет четное значение, а для определения цвета
результирующего пикселя к исходному цвету применяется фильтр,
заданный матрицей вида:
é1 2 1ù
ú
1 êê
× ê2 4 2úú .
16 ê
ú
ë1 2 1û
4. В результирующую текстуру переносятся пиксели, у которых
одна из координат имеет четное значение, и цвет пикселя в новой
текстуре определяется билинейной интерполяцией цветов соответствующих четырех пикселей текстуры предыдущего уровня.
Имея, набор текстур, созданных тем или иным способом, остается понять, какую именно из текстурных карт надо выбрать при
текстурировании? Наиболее простым методом, дающим ответ на
данный вопрос, является метод, получивший название «полигональный мипмэппинг». Для выбора соответствующей текстуры
из имеющегося набора необходимо посчитать площадь полигона
на экране в пикселях (P) и его площадь в текстуре в текселях (T).
Соотношение найденных площадей определяет примерное количество пикселей, соответствующих одному текселю. По найденному
соотношению выбирают наиболее подходящий уровень текстуры
(L) в наборе текстурных карт:
L = floor(log2(S/T)/2),
151
где функция floor(x) возвращает значение с плавающей точкой,
представляющее наибольшее целое, которое меньше или равно x.
Определившись с размером необходимой текстурной карты
(2L×2L), далее можно воспользоваться одним из названных методов
наложения текстуры.
Используя данную процедуру, полностью устранить артефакты
не удается, поскольку уровни текстур для двух соседних полигонов
могут меняться скачком, и, соответственно, на изображении иногда
явно прослеживаются границы перехода от одного уровня мипмэппинга к другому (этот артефакт получил название mip-banding).
2.2.7. Трилинейная фильтрация текстур
Для борьбы с артефактами типа mip-banding используется метод трилинейной фильтрации (trilinear filtering), представляющий
собой симбиоз мипмэппинга и билинейной фильтрации. В данном
методе для рендеринга используется не одна, а две соседние текстурные карты из набора текстур. При этом для каждой из двух
соседних текстурных карт выполняется билинейная фильтрация,
т. е. для определения цвета пикселя берется среднее значение цветов восьми текселей (по четыре из каждой текстуры). По существу
здесь выполняется билинейная фильтрация на двух соседних уровнях текстурных карт, а в итоге цвет пикселя определяется при помощи интерполяции по цветам двух соседних текстур.
Необходимо отметить, что в результате использования трилинейной фильтрации улучшение качества изображения по сравнению с билинейной фильтрацией иногда совсем незначительно, а
требования к ресурсам памяти практически удваиваются (удваивается также и время наложения текстуры). Поэтому в каждом конкретном случае следует учитывать данное обстоятельство при выборе того или иного метода текстурирования.
2.2.8. Рельефное текстурирование
(Bump mapping)
Для придания изображению еще большей реалистичности используют метод рельефного текстурирования. В отличие от ранее
рассмотренных методов наложения текстуры, где, фактически, ме152
нялся только цвет пикселя, здесь в изображение добавляется эффект рельефности (объемности) изображаемого плоского полигона
за счет использования так называемой рельефной карты текстуры.
Рельефная карта кроме данных о цвете определенных участков содержит информацию о неровностях (шероховатостях, рельефе).
Самым простым способом задания рельефа является использование карты высот. Карта высот представляет собой специальную
8-битную черно-белую текстуру, в которой яркость каждого пикселя пропорциональна высоте его положения относительно базовой
(нулевой) поверхности.
Следует понимать, что использование данного метода текстурирования для имитации крупных впадин или возвышенностей подчас не дает желаемого эффекта (градации яркости пикселей имеют
свои пределы). Однако для имитации незначительных неровностей
(шероховатость камня, рельеф коры дерева и т. п.) этот метод вполне можно использовать для получения достаточно хорошего конечного результата.
По сути данный метод является логическим продолжением техники закраски по Фонгу (при необходимости можно ознакомиться
с данным методом в разделе «Закраска Фонга»). Напомню, что степень освещенности точки на поверхности зависит от угла падения
светового луча (закон косинуса): чем меньше угол между нормалью
к поверхности с основанием в данной точке и лучом света, тем больше освещенность этой точки поверхности. Тогда, если поверхность
неровная, то нормали в каждой точке этой поверхности будут разными, а, следовательно, и освещенность в различных точках поверхности тоже будет разная. Этот факт и учитывается при рельефном текстурировании – для моделирования неровностей в разных
точках полигона задаются нормали к поверхности (точнее не сами
нормали, а градации яркости серого, по которым можно определить
нормали), которые учитываются при попиксельном вычислении
освещения. Таким образом, в данном случае достигается большая
реалистичность изображения без увеличения геометрической сложности модели, так как все расчеты ведутся на пиксельном уровне.
Достоинством метода также является то, что при изменении положения источника света освещение этих неровностей быстро корректируется за счет информации, содержащейся в карте высот.
Итак, карта высот содержит информацию о величине коррекции вектора нормали в соответствующей точке текстурируемого
полигона. Для учета этой информации необходимо преобразовать
153
яркость каждого пикселя из карты высот в соответствующий вектор, указывающий направление уклона поверхности (для этого
воспользуемся яркостью четырех пикселей, соседних с текущим,
координаты которого в карте высот обозначим через (x,y)):
xgr = pixel(x – 1, y) – pixel(x + 1, y);
ygr = pixel(x, y – 1) – pixel(x, y + 1).
Зная вектор корректировки, можем изменить вектор нормали в
соответствующем пикселе текстурируемой поверхности.
На рис. 2.6 показана карта высот (U и V – оси координат карты
высот) и полигон с исходным вектором нормали (n). Здесь же показаны два вектора (xgr, ygr), которые используются для корректировки исходного вектора нормали n. В результате коррекции нормали с
учетом данных карты высот получим новый вектор нормали (nnew):
nnew = n + (u · xgr) + (v · ygr),
здесь (u,v) – координаты соответствующей точки карты высот. Получив новый вектор нормали, можно просчитать яркость данного
пикселя, используя технологию затенения по Фонгу, которая более
подробно будет рассмотрена в следующем разделе.
Заканчивая обзор методов текстурирования, можно порекомендовать для увеличения реалистичности изображения использовать
эффект атмосферной перспективы, при котором объекты, находящиеся на значительном удалении от наблюдателя, изображаются
как бы подернутыми дымкой (туманом). Это несложно сделать, используя смешивание цветов тумана и объектов. Для этого используют информацию о глубине (z координате) из Z-буфера: чем дальше
от наблюдателя находится объект, тем больше на результирующий
цвет влияет туман и меньше – цвет исходного пикселя (см. разд.
«Сортировка по Z-буферу и смешение текстур»).
2.3. Методы закраски
2.3.1. Закраска Ламберта
Используя модель освещенности Ламберта, предполагают, что
вектор, направленный из точки поверхности к глазу наблюдателя,
несильно зависит от расположения данной точки на поверхности.
Таким образом, направление данного вектора принимается постоянным для всей грани (поверхности). Постоянным для всей грани
154
принимается также направление вектора из точки на поверхности
к источнику света. Грань не отражает свет, а только рассеивает его.
Нормаль в любой точке грани постоянна. Таким образом, получаем,
что освещенность по Ламберту равна константе для всей грани, т. е.
все точки грани освещены одинаково (достаточно посчитать освещенность один раз для каждой грани). В англоязычной литературе
по компьютерной графике освещение по Ламберту обычно принято
называть flat shading. Иначе данный метод называется однотонной
закраской. При реализации закраски по Ламберту на результирующем изображении могут быть хорошо заметны резкие перепады
интенсивности между различно закрашенными многоугольниками. Таким образом, используя данный метод закраски, получим
изображение, реалистичность которого явно недостаточна.
2.3.2. Закраска Фонга
Для повышения скорости формирования изображений практически все обычно используемые методы так называемого «освещения по Фонгу» не учитывают отраженной компоненты освещенности, т. е. ks = 0 (см. подразд. 1.3.4) (грань не отражает свет, а только
рассеивает).
Рассмотрим один из наиболее популярных методов закраски
Фонга, который сводит освещение к текстурированию по определенной текстуре. В этом методе принимаются следующие предположения: 1) вектор, проведенный из точки поверхности к источнику света, постоянен (т. е. имеем точечный бесконечно удаленный
источник света); 2) длина единичной нормали к поверхности изображаемого тела не меняется при интерполяции между вершинами
грани (т. е. принимаем, что, если в вершинах нормаль к телу имеет единичную длину, то при интерполяции этой нормали между
вершинами по какой-то грани мы будем получать в каждой точке
нормаль той же самой единичной длины). В действительности это
совсем не так, но для несильно отличающихся углов наклона нормалей это допущение приблизительно верно.
Поскольку ks = 0, а длина нормали к поверхности изображаемого тела по предположению равна единице на всей грани, имеем:
Io = Ir kr +
Ii kd
(NL),
d + const
155
где N – вектор нормали к поверхности; L – вектор, проведенный из
точки поверхности к источнику света (рис. 1.78).
Еще более упростим модель, предположив L = (0, 0, 1). Тогда
Ii kd
(Nx Lx + Ny Ly + Nz Lz ) =
d + const
Ii kd
Ii kd
= Ir kr +
× Nz = (2.1)
(Nx × 0 + Ny × 0 + Nz ×1) = Ir kr +
d + const
d + const
Ii kd
= Ir kr +
× 1 - (Nx2 + Ny2 ).
d + const
Io = Ir kr +
Таким образом, интенсивность выражается через Nx, Ny, значения которых меняются линейно. Поскольку длина вектора
N равна 1, то Nx, Ny – числа с плавающей запятой в диапазоне
[–1, 1]. Интерполяция чисел с плавающей точкой – очень трудоемкий с вычислительной точки зрения процесс. Кроме того, вычисление квадратного корня в формуле (2.1) для каждого пикселя
также существенно замедлит выполнение программы. Поэтому
вместо интерполяции Nx и Ny обычно интерполируют величины
128 · (Nx + 1) и 128. ( Ny + 1), причем уже в целых числах. В этом
случае все возможные значения этих величин могут быть только
целыми числами 0, 1, …, 255. Обычно при реализации такой модели заранее считаются значения Io для каждой пары приведенных
таким образом к новому масштабу Nx и Ny. Так, в процессе выполнения программы производится линейная интерполяция величин
128 . (Nx + 1) и 128 . (Ny + 1) и по ним определяем заранее вычисленное значение интенсивности. По существу, данный процесс можно
назвать текстурированием, где в качестве текстуры используется
таблица освещенности размером 256×256, а в качестве координат
текстуры для каждой вершины берутся приведенные к новому масштабу координаты нормали в этой вершине.
Иногда для компенсации ошибок лианеризации используют нелинейную таблицу интенсивностей. Считается она таким образом:
Io = Ia ka +
Ii kd
× (sin(Nx π / 256)sin(Ny π / 256))4 . d + const
(2.2)
Здесь Nx и Ny уже приведены к новому масштабу. Результат в
этом случае получается лучше, чем при вычислении по формуле
(2.1).
156
Теперь вернемся к вопросу о том, как привести случай с произвольным вектором, направленным на источник света, к только что
рассмотренному случаю, когда L = (0,0,1). В данном случае необходимо применить к нормалям в вершинах тела операцию поворота,
совмещающего наш произвольный вектор с вектором (0,0,1). Скалярное произведение при этом не изменяется. После этого поворота
выполняем процедуры, описанные ранее. Поворот нормалей в каждой вершине не требует практически никаких дополнительных
вычислительных затрат, так как при движении и вращении тела
(или точки наблюдения) все равно надо будет применять операции
поворота к соответствующим нормалям. Поэтому эти два поворота можно совместить в один. При использовании матричных операций достаточно перемножить (в нужном порядке!) матрицу собственного поворота тела, матрицу перехода от произвольной точки
наблюдения к нашей “стандартной″ точке и матрицу перехода от
произвольного вектора L к “стандартному″ вектору L = (0,0,1); т. е.
добавляется расчет этой матрицы перехода и одно матричное умножение, что достаточно немного с вычислительной точки зрения.
Рассмотрим алгоритм закраски Фонга. В этом алгоритме значение нормали вдоль строки закрашивания интерполируется между
значениями нормалей на ребрах многоугольника в точках пересечения ребер с данной строкой. Значения нормалей в этих точках,
в свою очередь, получают как результат интерполирования между
значениями нормалей в вершинах этих ребер. Значения же нормалей в вершинах многоугольников вычисляются как результат
усреднения нормалей ко всем полигональным граням, которым
принадлежит данная вершина. Полученное таким образом значение нормали для каждого пикселя на закрашиваемой строке используется для вычисления интенсивности этого пикселя по той
или иной модели освещенности (2.1) или (2.2).
Сначала рассмотрим пример, илY
V
люстрирующий нахождение нормалей в вершинах многоугольников.
Пример 2.1. Пусть три многоугольника (ABV, BCV, ACV) сходятся
0
в одной вершине V (рис. 2.7). УравA
C X
нения плоскостей для этих многоуZ
гольников:
B
PABV: – 5x + y + 5z + 10 = 0;
Рис. 2.7
157
PACV: – y + 5z = 0;
PABV: 10x + 3y + 15z – 70 = 0.
Усредненная нормаль к вершине V считается по формуле
nV = (a1 + a2 + a3)i + (b1 + b2 + b3)j + (c1 + c2 + c3)k,
где ai, bi, ci ( i = 1,2,3) – коэффициенты при x, y, z в i-м уравнении
плоскости соответственно.
Итак:
nV = ( – 5 + 0 + 10)i + (1 – 1 + 3)j + (5 + 5 + 15)k = = 5i + 3j + 25k.
Абсолютная величина нормали:
nv = 52 + 32 + 252 = 659.
Единичная или нормированная нормаль:
n
5
3
25
e= v =
×i +
×j+
× k.
nv
659
659
659
Теперь рассмотрим на примере алгоритм нахождения нормали в
произвольной точке на сканирующей прямой.
Пример 2.2. Найдем уравнение нормали
в точке P (рис. 2.8). Для этого необходимо
C
A
P
найти уравнения нормалей в вершинах A,
B и C по алгоритму, описанному в примеQ
R
B
ре 2.1. Предположим, эти уравнения найдены. Затем определяем нормаль в точке Q
линейной интерполяцией между нормалями в точках A и B:
Рис. 2.8
AQ
.
AB
Нормаль в точке R находим линейной интерполяцией между
нормалями в точках B и C:
nQ = un A + (1 - u)nB ; 0 £ u £ 1; u =
nR = wnB + (1 - w)nC ; 0 £ w £ 1; w =
BR
.
BC
И, наконец, нормаль в точке P находим линейной интерполяцией между нормалями в точках Q и R:
nP = tnQ + (1 - t)nR ; 0 £ t £ 1; t =
158
QP
.
QR
V1
V4
V2
Поворот
P
V2
V1
V3
P
V4
V3
Рис. 2.9
Нормаль вдоль сканирующей прямой можно вычислить, используя приращение, что повышает вычислительную эффективность алгоритма:
n p2 = n p + (nQ - nR )(t2 - t1 ) = n p + ∆n∆t,
1
1
где индексы 1 и 2 указывают на расположение пикселей вдоль строки.
Несмотря на то, что метод Фонга позволяет получать более реалистичные изображения, он обладает рядом недостатков.
Во-первых, работая в плоскости экрана, мы проводим интерполяцию с одинаковыми приращениями, хотя правильнее было бы
учитывать перспективное представление граней и использовать
разные приращения.
Во-вторых, возникают проблемы при анимации. Дело в том, что,
как видно из рис. 2.9, в определенный момент времени при повороте грани нормаль в одной и той же точке P начинает интерполироваться по нормалям другой тройки вершин (сначала – по V1, V4 и
V2, а потом – по V1, V4 и V3), что, естественно, иногда бывает очень
заметно.
В-третьих, при разбивке поверхности на четырехугольники надо
учитывать, что, если точка является вершиной хотя бы одного четырехугольника, то она также должна быть вершиной всех четырехугольников, которым она принадлежит. Иначе можно столкнуться с ситуацией, показанной на рис.
V1
2.10, где закраска грани 1 интерполируется по V1 и V3 без учета V2, в
Грань 1
то время как при закраске граней 2
V2
Грань 2
и 3 V2 учитывается. Это может при- V3
вести к нежелательным визуальным
Грань 3
эффектам.
Рис. 2.10
159
2.3.3. Закраска Гуро
Закраска методом Гуро является простым и, вместе с тем, эффективным методом придания ощущения изогнутости для ровного
полигона. При использовании модели освещенности по Гуро предполагается (см. подразд. 1.3.4), что ks = 0 (грань не отражает свет,
а только рассеивает) и освещенность меняется по грани линейно.
Таким образом, в вершинах грани интенсивность считается по формуле
Io = Ia ka + Pi Ii kd cos(α).
В методе закраски Гуро используется интерполяция интенсивности. При этом нормали в вершинах многоугольников вычисляются, как и в алгоритме Фонга (пример 2.1). Используя значения
нормалей, затем вычисляют интенсивности в вершинах многоугольника. Далее эти полученные значения используют для билинейной интерполяции: для очередной сканирующей прямой сначала находят значения интенсивностей в точках пересечения сканирующей прямой с ребрами многоугольника, а затем линейно интерполируют между ними для нахождения интенсивности пикселя
при закраске вдоль сканирующей строки. Таким образом, методом
Гуро можно получить сглаженное по сравнению с однотонной закраской изображение.
Пример 2.3. Найдем интенсивность для изображения пикселя в
точке P (рис. 2.8) линейной интерполяцией интенсивностей в точках Q и R. Для начала необходимо найти значения интенсивностей
в точках A, B и C. Интенсивность в точке Q найдем линейной интерполяцией между интенсивностями в точках A и B:
IQ = uI A + (1 - u) IB ; 0 £ u £ 1; u =
AQ
.
AB
Аналогично для получения интенсивности в точке R линейно
интерполируются интенсивности в вершинах B и C:
IR = wIB + (1 - w) IC ; 0 £ w £ 1; w =
BR
.
BC
И, наконец, линейной интерполяцией по сканирующей строке
между точками Q и R находится интенсивность в точке P:
IP = tIQ + (1 - t) IR ; 0 £ t £ 1; t =
160
QP
.
QR
Значения интенсивности вдоль сканирующей строки можно,
как и при закраске Фонга, вычислять инкрементально. Для двух
пикселей в t1 и t2 на сканирующей строке: I p = I p + (IQ - IR )(t2 - t1 ) = I
2
1
+ (IQ - IR )(t2 - t1 ) = I p + ∆I ∆t. Однако данный метод закраски обладает рядом
1
недостатков. В частности, один из недостатков метода Гуро иллюстрируется на рис. 2.11.
Если нормали к вершинам В, С, D вычислить усреднением нормалей к многоугольникам, сходящимся в данных вершинах, то они
будут одинаково ориентированы, т. е. интенсивность в этих точках
будет равной (рис. 2.11, а). При линейной интерполяции от В до D
значение интенсивности получится постоянным, и поверхность на
данном участке будет выглядеть плоской. Для изображения плавного перехода в В, С и D необходимы дополнительные многоугольники (рис. 2.11, б). Если же нужно сохранить резкие складки, то
для предотвращения сглаживания требуется выборочное усреднение нормалей к поверхности. В примере (рис. 2.11, в) nB1 вычисляется только для одной грани справа от В, аналогично получается
nD1 и nD2. В то же время nC вычисляется как среднее для граней
nB
nA
а)
B
A
nB
nA
б) nA
B
nB
nC
nC
nD
A
nE
nB2
B
nC
nD
nD1
nC
nD
C
E
nF
D
C
nB1
nA
nE
D
C
A
в)
nD
nC
E
nD2
D
nE
nE
E
Рис. 2.11
161
слева и справа от С. В этом случае в
В и D получается острое ребро, а в
С – плавный переход.
На практике при реализации
алгоритма закраски производится лишь подсвечивание пикселей.
A
B
C
Поэтому можно внести некоторые
D
изменения в ранее рассмотренные
e
процедуры. Итак, пусть имеется
треугольный полигон (рис. 2.12).
Предполагается, что освещенность
в вершинах уже вычислена, и вдоль
кромок полигона она изменяется
линейно, т. е. известна освещенРис. 2.12
ность в точках A и В. Необходимо
просчитать освещенность для пикселей вдоль линии А–В (по сути –
это три пикселя С–D). Центр первого пикселя (С) не совпадает с
точкой А, а центр пикселя D не совпадает с точкой B. Вначале определяется градиент изменения освещенности по всей длине линии:
(B - AS )
grad = S
,
(BX - AX )
где AS и BS – освещенность в точках А и В; BX и AX – значения X в
точках А и В соответственно. Градиент показывает относительную
величину изменения освещенности в пересчете на единицу изменения координаты X. Затем определяется точное значение освещенности в точке С:
CS = (1 - e)grad,
величина e определяет смещение центра первого пикселя (С) относительно точки А. Теперь можно легко прорисовать пиксели вдоль
линии A-B.
С помощью метода Гуро можно изображать только матовые поверхности, не имеющие зеркальных бликов. Действительно, в случае, когда блик расположен внутри грани и не доходит до вершин,
зеркальная составляющая в вершинах равна нулю и, следовательно, блик не появится при интерполяции.
Кроме этого, недостатки метода Гуро начинают проявляться при
попытке совмещения вычисления освещенности с затенением больших по размеру полигонов. Например, пусть имеется большой по162
лигон, освещенный единственным источником света, расположенным в центре полигона. Освещенность, создаваемая источником
света в вершинах полигона, будет очень малой ввиду значительной
удаленности от источника света. Выведенный на экран полигон будет темным, хотя это неверно, поскольку центр полигона освещен.
С другой стороны, большой полигон будет всегда полностью освещен, если с его противоположных краев находятся источники света (даже если источники маломощны и середина полигона просто
обязана быть в тени).
Устранить данный недостаток можно, используя большое количество небольших полигонов совместно с отдаленным источником
света. В этом случае закраска по Гуро может выглядеть очень неплохо. Таким образом, чем меньше размер полигона, тем точнее
и качественней будет сглаживание, тем больше оно будет приближаться по качеству к закраске по Фонгу.
У метода Гуро есть еще один недостаток. Дело в том, что возникает классический оптический эффект полос Маха: на границах
четырехугольников человеческий глаз усиливает переходы и границы воспринимаются как светлые линии (это происходит из-за
разрыва производной).
В заключение данного раздела остановимся еще раз на сравнении рассмотренных методов закраски полигональных поверхностей. Прежде всего, следует обратить внимание на то, что метод
Гуро выполняется быстрее метода Фонга, но при его использовании
нельзя изобразить некоторые специальные световые эффекты, например, блики. Закраска методом Фонга позволяет получить более
качественные изображения, однако этот метод более трудоемкий.
Закраска Гуро лучше всего выглядит в сочетании с простой моделью с диффузным отражением, так как форма бликов при зеркальном отражении сильно зависит от выбора многоугольников,
представляющих объект или поверхность.
При закраске Гуро вдоль сканирующей строки интерполируется
значение интенсивности, а при закраске Фонга – вектор нормали.
Затем он используется в модели освещения для вычисления интенсивности пикселя. При этом достигается лучшая локальная аппроксимация кривизны поверхности и, следовательно, получается
более реалистичное изображение. В частности, правдоподобнее выглядят зеркальные блики.
Хотя метод Фонга устраняет большинство недостатков метода
Гуро, он тоже основывается на линейной интерполяции. Поэтому в
163
местах разрыва первой производной
интенсивности заметен эффект полос Маха, хотя и не такой сильный,
2
как при закраске Гуро. Однако иноP
гда этот эффект проявляется сильнее
у метода Фонга, например для сфер.
Кроме того, оба метода могут приве1
сти к ошибкам при изображении невыпуклых многоугольников, наприQ
мер, таких, как на рис. 2.13.
Первая сканирующая строка исРис. 2.13
пользует данные из вершин Q, R и S,
а вторая, лежащая выше, берет также данные вершины Р. Это может нарушить непрерывность закраски.
Также возникают трудности, когда любой из этих методов применяется при создании последовательности кинокадров. Например, закраска может значительно изменяться от кадра к кадру. Это
происходит из-за того, что правило закраски зависит от поворотов,
а обработка ведется в пространстве изображения. Поэтому, когда
от кадра к кадру меняется ориентация объекта, его закраска (цвет)
тоже изменяется, причем достаточно заметно. Существуют методы
закраски Гуро и Фонга, инвариантные относительно поворота, однако их изложение выходит за рамки данного пособия.
В заключение данного раздела рассмотрим пример, в котором
сравниваются интенсивности в некоторой произвольной точке
при использовании рассмотренных методов закраски (пример позаимствован на интернет-ресурсе http://stratum.ac.ru/textbooks/
kgrafic/additional/addit26.html).
Пример 2.4. Рассмотрим участок поверхности, показанный на
рис. 2.14. Пусть ось z направлена перпендикулярно к плоскости
S
R
3
A
C
P
R
Q
2
Плоскость
сканирующей строки
B
4
1
Рис. 2.14
164
страницы, x – вправо, а y – вверх. Координаты точки B (0.366,
1.366, 2). Пусть уравнения плоскостей 1 – 4:
1) 2z – 4 = 0;
2) – x + 1.732y + 7.5z – 17 = 0;
3) – 2.25x + 3.897y + 10z – 24.5 = 0;
4) 5.5z – 11 = 0.
Предположим, что вектор к точке наблюдения – S(1, 1, 1) и
единственный точечный источник расположен в бесконечности на
положительной полуоси z, т. е. вектор падающего света равен L(0,
0, 1). Модель освещения задана уравнением
I = Iaka + Il[kd(n′L′) + ks(R′S′)n]/(d + K),
где d = 0, K = 1, Ia = 1, Il = 10, n = 2, ks = 0.8, kd = ka = 0.15.
Поскольку свет падает вдоль оси z, то направление отраженного
света можно найти методом Фонга.
Рассмотрим поочередно каждый метод закраски.
1. Однотонная закраска.
Точка P лежит в многоугольнике 3. Из уравнения плоскости
многоугольника 3 находим нормаль
n3′ = n3/|n3| = – 0.21i + 0.36j + 0.91k.
Косинус угла между нормалью и вектором падающего света:
n′L′ = (– 0.21i + 0.36j + 0.91k)k = 0.91
Отсюда следует, что угол падения составляет примерно 24.2°.
Из уравнений для определения вектора отражения имеем:
Rz′ = 2n′z2 – 1 = (2)(0.91)2 – 1 = 0.66;
Rx′ = 2n′zn′x = (2)(0.91)(–0.21) = –0.38;
Ry′ = 2n′zn′y = (2)(0.91)(0.36) = 0.66;
R′ = – 0.38i + 0.66j + 0.66k.
Единичный вектор наблюдения: S′ = S/|S| = 0.58i + 0.5j + 0.58k.
Теперь находим косинус угла между вектором отражения и вектором наблюдения:
R′S′ = (–0.38i + 0.66j + 0.66k)(0.58i + 0.58j + 0.58k) = 0.55,
таким образом, искомый угол приблизительно равен 57°.
Модель освещения для точки P дает
IP = Iaka + Il[kd(n′L′) + ks(R′S′)n]/(d + K) = (1)(0.15) + (10/1) ×  
× [(0.15)(0.91) + (0.8)(0.55)2] = 0.15 + 10(0.14 + 0.24) =
= 0.15 + 3.8 = 3.95.
165
2. Закраска Гуро.
Для закраски Гуро необходимы векторы нормали в точках A, B и
C. Аппроксимируя их усреднением нормалей к окружающим плоскостям, получаем:
nA = n2 + n3 = –3.25i + 5.63j + 17.5k;
nB = n1 + n2 + n3 + n4 = –3.25i + 5.63j + 25k;
nC = n3 + n4 = –2.25i + 3.897j + 15.5k,
где n1, n2, n3, n4 получены из уравнений соответствующих плоскостей. Единичные нормали, соответственно:
nA′ = nA/|nA| = –0.17i + 0.3j + 0.94k;
nB′ = nB/|nB| = –0.12i + 0.22j + 0.97k;
nC′ = nC/|nC| = –0.14i + 0.24j + 0.96k.
Единичные векторы отражения:
RA′ = –0.33i + 0.57j + 0.76k;
RB′ = –0.24i + 0.42j + 0.87k;
RC′ = –0.27i + 0.46j + 0.84k.
Интенсивности в точках A, B и C равны
IA = 0.15 + 10(0.14 + 0.27) = 4.25;
IB = 0.15 + 10(0.15 + 0.30) = 4.65;
IC = 0.15 + 10(0.14 + 0.29) = 4.45.
На заданной сканирующей строке имеем u = AQ/AB = 0.4 и
w = BR/BC = 0.7. Интерполируя, находим интенсивность в точках
Q и R:
IQ = uIA + (1 – u)IB = (0.4)(4.25) + (1 – 0.4)(4.65) = 4.49;
IR = wIB + (1 – w)IC = (0.7)(4.65) + (1 – 0.7)(4.45) = 4.59.
Точка P на сканирующей строке расположена в t = QP/QR = 0.5.
Интерполируя, определим интенсивность в Р:
IP = tIQ + (1 – t)IR = (0.5)(4.49) + (1 – 0.5)(4.59) = 4.54.
3. Закраска Фонга.
При закраске Фонга нормаль в точке P получается путем интерполяции нормалей в точках A, B, C. Затем эта нормаль используется для вычисления интенсивности в точке P. Единичные нормали
в точках Q и R:
166
n′Q = un′A + (1 – u)n′B = (0.4)[–0.17 0.3 0.94] +
+ (0.6)[–0.12 0.22 0.97] = [–0.14 0.25 0.96] =
= –0.14i + 0.25j + 0.96k;
n′R = un′B + (1 – w)n′C = (0.7)[–0.12 0.22 0.97] + (0.3) ×
× [–0.14 0.24 0.96] = [–0.13 0.23 0.96] = –0.13i + 0.23j + 0.97k.
Интерполируя нормаль вдоль сканирующей строки, находим:
n′P = tn′Q + (1 – t)n′R = (0.5) [–0.14 0.25 0.96] + 0.5 ×
× [–0.13 0.23 0.97] = [–0.14 0.24 0.97] = –0.14i + 0.24j + 0.97k.
Тогда единичный вектор отражения в точке P:
R′P = – 0.27i + 0.46j + 0.87k.
Интенсивность в точке P:
IP = 0.15 + (10)(0.15 + 0.30) = 4.65.
Сравнивая различные методы закраски, имеем
Однотонная: IP = 3.95.
Гуро: IP = 4.54.
Фонга: IP = 4.65.
2.4. Алгоритмы сглаживания (аnti-aliasing)
Поскольку все растровые алгоритмы построения геометрических примитивов имеют серьезный недостаток, являющийся следствием растровой природы монитора (изображение строится из дискретного набора точек), то на заключительном этапе рендеринга
выполняется алгоритм сглаживания (аnti-aliasing) для устранения
эффекта дискретизации, ступенчатости изображения на границе
объектов. Упрощенно экран обычного монитора можно представить матрицей пикселей, выровненных по дискретной сетке. Следовательно, точное представление объекта, имеющего наклонные
линии, невозможно. Дискретизация приводит к появлению на
прямых линиях эффекта ступенчатости или зазубренности. Без
принятия дополнительных мер эта ступенчатость хорошо заметна,
и, в результате, изображение теряет в реалистичности. Алгоритм
сглаживания снижает остроту проявления подобного «лестничного» эффекта, путем интерполяции пикселей для получения более
четких краев. Наиболее часто используются методы, создающие
167
плавный переход от цвета линии или
ребра многоугольника к цвету фона.
В некоторых случаях, результатом
является смазывание (blurring) краев
(рис. 2.15). При сглаживании создаются промежуточные пиксели, которые обеспечивают плавный переход
между цветами и ступенчатыми краями. В результате сглаживания неровный край изображения заполняется
промежуточными полупрозрачными
пикселями. Сглаженный таким обраРис. 2.15
зом край выглядит более гладко. На
рис. 2.15 показаны две прямые линии, одна из которых получена с
использованием процедуры сглаживания, а другая – без нее.
Очевидно, что полностью устранить ступенчатость невозможно,
для этого необходимо отказаться от растровых мониторов. Однако
алгоритмы сглаживания позволяют создать иллюзию гладкости
изображаемых геометрических примитивов (здесь следует помнить, что, выигрывая в визуальном качестве изображения, мы несколько теряем в его четкости).
Алгоритмы сглаживания помимо борьбы со ступенчатостью линий позволяют устранить появление некоторых неприятных артефактов, возникающих в растровых алгоритмах. Например, при построении отрезков прямых по методу Брезенхема (рассматривается
далее), горизонтальный и диагональный отрезки подсвечиваются с
существенно различной яркостью (вплоть до 1,5 раз). При сглаживании яркости отрезков выравниваются.
Рассмотрим ряд алгоритмов сглаживания, наиболее часто используемых на практике.
2.4.1. Алгоритм Брезенхема для сглаживания
ребер многоугольников
Для начала необходимо познакомиться с тем, как, собственно,
производится разложение в растр простейших геометрических
примитивов, например, отрезков прямых линий.
Одним из наиболее эффективных и простых для понимания алгоритмов решения задачи воспроизведения отрезка прямой является
168
алгоритм Брезенхема [14]. Данный
Y
(1, 1)
алгоритм выбирает оптимальные 1
a
координаты для представления отрезка. В процессе работы в зависимости от углового коэффициента
b
наклона отрезка либо координата
(1, 0) X
x, либо координата y уменьшается или увеличивается на 1. Изме0
1
нение другой координаты зависит
Рис. 2.16
от расстояния между действительным положением отрезка и ближайшими координатами растровой
сетки. Это расстояние будем называть ошибкой. Алгоритм Брезенхема организован таким образом, что требуется проверять лишь
знак этой ошибки. На рис. 2.16 видно, что если угловой коэффициент больше 1/2 (луч а), то точка пересечения отрезка с прямой x
= 1 будет расположена ближе к прямой y = 1, чем к прямой y = 0.
Следовательно, точка с координатами (1,1) лучше аппроксимирует
ход отрезка, чем точка с координатами (1,0). Если же угловой коэффициент меньше 1/2 (луч b), то верно обратное.
Поскольку эффективнее проверять не величину ошибки, а ее
знак, то ошибка первоначально устанавливается равной – 1/2.
Итак, ошибка – это интервал, отсекаемый по оси Y рассматриваемым отрезком в каждом растровом элементе (относительно – 1/2).
Для разложения в растр отрезков прямых в первом октанте декартовой системы координат алгоритм Брезенхема может быть
представлен следующим образом (алгоритм 1):
x = x1, y = y1, X = x2 – x1
/* Инициализация переменных */
Y = y2 – y1, e = Y/X – 0.5
for i = 1 to X
/* Основной цикл */
Plot (x,y) /* Подсветка пикселя с координатами (x,y) */
while (e >= 0)
y=y+1
e=e–1
endwhile
x=x+1
e = e + Y/X
next i
stop
Здесь для простоты принято, что отрезок начинается и заканчивается точно в точках растра (точки с координатами (x1,y1) и (x2,y2)
169
являются соответственно точками начала и окончания отрезка
прямой).
Быстродействие данного алгоритма можно увеличить за счет отказа от арифметики с плавающей точкой и операции деления. Для
этого используется преобразование e = 2·e·X, и при инициализации
вместо e = Y/X – 0.5 инициируется e = 2·Y – X, а вместо выражений
для e в 7-й и 10-й строках предыдущей программы следует соответственно использовать выражения e = e – 2·X и e = e + 2·Y.
Для полной реализации этого алгоритма необходимо обрабатывать отрезки прямых во всех октантах. Обобщенный целочисленный
алгоритм Брезенхема может быть представлен следующим образом.
Пусть точки с координатами (x1,y1) и (x2,y2) являются соответственно точками начала и окончания отрезка прямой и пусть
ïìï-1, åñëè x < 0;
ï
sign(x) = ïí1, åñëè x > 0;
ïï
ïïî0, åñëè x = 0.
Тогда обобщенный целочисленный алгоритм выглядит таким
образом (алгоритм 2):
x = x1, y = y1, X = |x2–x1|,
/* Инициализация переменных */
Y = |y2–y1|, s1 = sign(x2 –x1), s2 = sign(y2 –y1)
/* Обмен зна
/ чений X и Y в зависимости от углового
/ коэффициента наклона отрезка */
if Y > X then A = X, X = Y, Y = A, Flag = 1
else Flag = 0
endif
e = 2Y – X
/* Инициализация e с поправкой на полпикселя*/
for i = 1 to X /* Основной цикл */
Plot(x,y)
/* Подсветка пикселя с координатами (x,y) */
while (e >= 0)
if Flag = 1 then x = x + s1
else y = y + s2
endif
e = e – 2X
endwhile
if Flag = 1 then y = y + s2
else x = x + s1
endif
e = e + 2Y
next i
stop
170
Результат работы алгоритма для отрезка прямой, направленного из точки с координатами (0,0) в точку с координатами (–8,–4)
приведен на рис. 2.17.
Изменения значений переменных в процессе работы алгоритма
для данного примера представлены в табл. 2.1.
–8
–7
–6
–5
–4
–3
–2
–1
0
X
0
–1
–2
–3
–4
Y
Рис. 2.17
Таблица 2.1
I
1
Координаты изображаемого пикселя
x
y
0
0
–16
–8
0
0
–1
–1
0
–2
–1
–16
–8
–2
–3
–2
–2
0
–4
–2
–16
–8
–4
–5
–3
–3
0
–6
–3
–16
–8
–6
–7
–4
–4
0
–8
–4
(0, 0)
2
(–1, –1)
3
(–2, –1)
4
(–3, –2)
5
(–4, –2)
6
(–5, –3)
7
(–6, –3)
8
e
0
(–7, –4)
(–8, –4)
171
Как видно из приведенного
примера, результирующий отрезок прямой является, строго говоря, ступенчатой линией. Улучшить ее визуальное восприятие
X
0
1
2
3
4
5
6
7
можно, используя алгоритм сглаY
живания. Предположим, что вы3
1,9 40 89
водимый отрезок прямой являет2
0,8 36 86
ся ребром многоугольника.
1
0,2 31 82
Основная идея алгоритма Бре0 26 78
X
зенхема
для сглаживания ребер
Y 0 1 2 3 4 5 6 7
многоугольников состоит в том,
3
64
чтобы для ребер многоугольника
2
7,1 59
устанавливать яркость пикселя
1
2,3 55
пропорционально площади пик0 26
X
селя, попавшей внутрь многоу0 1 2 3 4 5 6 7
Пиксели,
гольника.
Полностью
закрашенные XX закрашенные на
Этот алгоритм используется
пиксели
XX %яркостью
при наличии нескольких интенРис. 2.18
сивностей или оттенков цвета.
При этом внешний вид ребра или
отрезка может быть улучшен вследствие размывания краев. На
рис. 2.18 приведен результат построения ребра многоугольника с
тангенсом угла наклона 11/21.
Верхний фрагмент рис. 2.18 – результат генерации многоугольника с использованием стандартного алгоритма Брезенхема
при двухуровневом изображении (пиксель либо закрашен, либо
нет).
Средний фрагмент – результат генерации многоугольника с вычислением интесивности пикселей, через которые проходит ребро
многоугольника. Интенсивность пикселя пропорциональна площади части этого пикселя, попавшей внутрь многоугольника.
Нижний фрагмент содержит результат генерации многоугольника с вычислением интесивности пикселя, через который проходит ребро многоугольника, в соответствии с алгоритмом Брезенхема. В этом алгоритме Брезенхем учитывал, что при построении
ребра многоугольника с тангенсом угла наклона t(0 ≤ t ≤ 1) могут
захватываться либо один пиксель (пиксели (0,0), (2,1), (4,2), (6,3))
либо два пикселя (пиксели (1,0) и (1,1), (3,1) и (3,2), (5,2) и (5,3)).
Если захватывается один пиксель (рис. 2.19, a), то часть его плоY
3
2
1
0
172
a)
б)
S2 = (dy −1 + t)
2t
dy
2dy + t
S=
2
dy
S1 = 1 −�
2
(1−dy) 2
2t
Рис. 2.19
2dy + t
. Если же за2
хватывается два пикселя (рис. 2.19, б), то часть площади нижне(1 - dy)2
го пикселя, попавшая внутрь многоугольника S1 = 1 ,
2t
2
(dy -1 + t)
а верхнего – S2 =
. Суммарная площадь частей для двух
2t
t
пикселей, попавшая внутрь многоугольника, равна dy + . Здесь
2
всюду dy – длина отрезка, отсекаемая реальной прямой по оси ординат от левой границы пикселя.
В результате простой модификации рассмотренного ранее алгоритма Брезенхема для генерации отрезка прямой можно получить аппроксимацию площади части пикселя, находящейся внутри многоугольника. Эту аппроксимацию можно использовать для
определения интенсивности каждого изображаемого пикселя.
Если в приведенном алгоритме Брезенхема (алгоритм 1) ошибку
e заменить на e′ = e + (1 – t), где t – тангенс угла наклона отрезка
(0 ≤ t ≤ 1), то тогда e′ будет лежать в диапазоне 0 ≤ e′ ≤ 1 и, по существу, будет иметь значение той части пикселя, которая находится
внутри многоугольника.
Для того, чтобы превратить алгоритм в целочисленный, достаточно домножить величины тангенса угла наклона (t), начального
(е′) и максимальное (W) значения ошибки на максимальное число
уровней интенсивности L.
Модифицированный алгоритм Брезенхема с устранением ступенчатости для первого октанта выглядит следующим образом:
щади, попавшая внутрь многоугольника, S =
x = x1, y = y1, X = x2 – x1
/* Инициализация переменных */
Y = y2 – y1, e = 2Y–X
t=L(Y/X); W = L–t; e’ =L/2
Plot(x, y, t/2)
for i = 1 to X
/* Основной цикл */
If e’<W then (x=x+1; e’=e’+t)
else (x=x+1; y=y+1; e’ = e’–W)
endIf
173
Plot (x, y, e’)
next i
stop
Интенсивность для первого пикселя предполагает, что отрезок
начинается в точке, координаты которой точно совпадают с пикселем. Распространить работу алгоритма на другие октанты можно
тем же способом, что и для базового алгоритма Брезенхема (алгоритм 2) [14].
2.4.2. Алгоритм Ву
Приведенный алгоритм Брезенхема устраняет лестничный эффект для ребер многоугольников. В этом разделе рассмотрим алгоритм, который сочетает в себе скорость, близкую к скорости алгоритма Брезенхема без сглаживания и качественное устранение
«лестничного» эффекта на отрезках прямых, которые не являются
ребрами граней многогранника.
Идея алгоритма Ву состоит в следующем: при рисовании линии
на каждом шаге вдоль основной оси рисуются две точки вдоль неосновной. При рисовании этих двух точек их интенсивность выбирается пропорционально расстоянию от центра точки до идеальной
линии. Чем больше данное расстояние, тем меньше интенсивность
соответствующего пикселя. Сумма интенсивностей этих двух пикселей всегда равна единице (рис. 2.20). Такое распределение придает линии одинаковую интенсивность на всем ее протяжении, создавая при этом иллюзию, что точки расположены вдоль линии не
по две, а по одной. Горизонтальные, вертикальные и диагональные
линии не требуют никакого сглаживания, поэтому их рисование
Интенсивность пикселей в % от
максимальной
80%
20%
50%
y +1
Идеальная
0,2
линия
0,5
0,8
0,8
0,5
0,2
20%
50%
y
80%
Расстояния от пикселя до идеальной линии
x
X
y
Рис. 2.20
174
выносится в отдельную функцию программы растровой развертки
отрезков. Что касается других линий, то алгоритм Ву проходит их
вдоль основной оси, подбирая координаты по неосновной оси, аналогично алгоритму Брезенхема. Отличие состоит в том, что в алгоритме Ву на каждом шаге устанавливается не одна, а две точки.
Например, если основной осью является Х, то рассматриваются
точки с координатами (х,у) и (х,у + 1). В зависимости от величины
ошибки, которая показывает, как далеко ушли пиксели от идеальной линии по несновной оси, распределяется интенсивность между
этими двумя точками (рис. 2.20).
2.4.3. Улучшение качества изображения фильтрацией
Рассматриваемые в данном подразделе алгоритмы также основаны на «размывании» границы. Первый из них заключается в
том, что изображение строится с большим пространственным разрешением, чем позволяет монитор, т. е. в этом методе улучшение
визуального восприятия достигается за счет ухудшения пространственного разрешения. При выводе на экран атрибуты пикселя
экрана вычисляются усреднением по группе пикселей изображения, построенного с большим разрешением: т. е. пиксели изображения рассматриваются как субпиксели соответствующих пикселей экрана. Усредняющая маска перемещается по изображению с
шагом, равным ее размеру.
Второй метод заключается в усреднении изображения без изменения его разрешения. В этом случае усредняющая маска перемещается по изображению с единичным шагом.
Очевидно, что второй метод должен давать более качественное
изображение, но при больших вычислительных затратах. Для
усреднения по группе пикселей изображения используются различные маски. Простейшее усреднение – равномерное (рис. 2.21).
При этом в случае использования маски (a) разрешение уменьшается в два раза, а при использовании маски (б) – в четыре.
Улучшить усреднение можно за счет использования весов, задающих влияние отдельных субпикселей на атрибут (интенсивность
цвета) пикселя экрана (рис. 2.22). Здесь также разрешение уменьшается в два раза при использовании маски (a), и в четыре раза при
использовании маски (б).
175
Для того чтобы средняя яркость изображения не менялась, используемые для усреднения маски должны быть пронормированы
для получения единичного коэффициента передачи. Нормирующий коэффициент равен единице, деленной на сумму членов маски.
2.2.4. Сглаживание методом усреднения по площади
Для устранения нежелательных визуальных эффектов путем
сглаживания часто используется алгоритм усреднения по площади
(area averaging). Цвет пикселя определяется тем, насколько каждый полигон перекрывает данный пиксель. На рис. 2.23 приведен
пример, где пиксель перекрывают два полигона: А и В. Пусть полигон А занимает 30% площади пикселя, а полигон В – 70%. Результирующий цвет в этом случае определяется цветами А и В с весовыми коэффициентами 30% и 70% соответственно (т. е. проводится
операция альфа-смешения, которая уже рассматривалась в разд.
2.1 пособия). Данная операция, к сожалению, приводит к появлению артефакта под названием bleeding – окрашивание внутренних
ребер в цвет фона. Этот артефакт характерен тем, что между гранями образуется тонкий просвет (шириной меньше пикселя).
2.4.5. Субпиксельное сглаживание
Алгоритм субпиксельного сглаживания позволяет устранить
тонкий просвет между гранями, появляющийся в результате работы алгоритма сглаживания методом усреднения по площади. При
этом каждый пиксель разбивается на субпиксели. Один из методов
субпиксельного сглаживания состоит в том, что полигоны подвергаются рендерингу от ближайших к наблюдателю к более отдаленным (front-to-back). Рассмотрим пример, приведенный на рис. 2.24.
При обработке переднего полигона субпиксели 2, 3, 4, 7, 8, 12
окрашиваются в цвет переднего полигона. При этом запоминается, какие субпиксели попали в передний полигон (так называемая
маска). Эта маска проверяется, когда обрабатывается задний полигон. Субпиксели 1, 5, 6, 9 окрашиваются в цвет заднего полигона.
Субпиксели 2 и 3, принадлежащие обоим полигонам, не изменяют
цвет (они находятся в маске) и таким образом остаются с цветом
176
(xi,yi,zi)
Точка
наблюдения
Промежуточная
поверхность T ¢
(x,y,z)
Объект
N(x,y,z)
(xi,yi,zi)
(x,y,z)
(xi,yi,zi)
(x,y,z)
Центр тяжести
N(x,y,z)
(xi,yi,zi)
(x,y,z)
Рис. 2.3
U y gr
xgr
n
V
Карта высот
Исходный вектор
нормали
n
n new
Скорректированный
вектор нормали
Рис. 2.6
177
а)
1
1
1
1
б)
a) 1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
б) 1 2 3 4 3 2 1
2 4 6 8 6 4 2
1 2
3 6 9 12 9 6 3
1
1
2 1
2 4 2
1
2 12 8 4
4 8 12 16
3 6 9 12 9 6 3
2 4 6 8 6 4 2
1 2 3 4 3 2 1
– центр экранного пикселя
– центр экранного пикселя
Рис. 2.21
Рис. 2.22
B
70%
30%
A
Рис. 2.23
Субпиксели
Задний полигон
13
14
15
16
9
10
11
12
5
6
7
8
1
2
3
4
Пиксель
Передний полигон
Рис. 2.24
178
переднего полигона. В результате артефакт, называемый bleeding,
подавляется.
К недостаткам данного метода можно отнести необходимость
хранения маски для каждого пикселя и требование сортировки полигонов по глубине. Второе требование можно обойти, сохраняя
z-координату для каждого субпикселя. Но хранение z-координаты
для каждого субпикселя на экране требует достаточно большого
объема видеопамяти. Субпиксельное сглаживание с z-буферизацией
можно реализовать методом аккумулятора. Суть его сводится к
тому, что обработка ведется последовательно для каждого пикселя
и при этом используется одна и та же память. Однако и данный метод имеет существенный недостаток: требование последовательной
обработки приводит к невозможности аппаратного распараллеливания и как следствие – к уменьшению производительности в число раз, равное числу субпикселей в пикселе. Так, субпиксельное
сглаживание 4×4 снижает производительность в 16 раз.
179
Заключение
Предложенные в пособии алгоритмы реализации графического
конвейера являются лишь примерами процедур, реализующих ту
или иную стадию генерации графического изображения на экране
монитора. При написании пособия автором не ставилась задача рассмотрения всего множества алгоритмов и математических методов,
используемых в настоящее время для создания трехмерных графических пакетов. Выбор конкретных алгоритмов из всего множества
разработанных методов решения задачи создания реалистичного
изображения определяется рядом факторов, в частности, таких
как: тип объектов в пространственной сцене, их взаимное расположение, количество и расположение источников света, оптические
свойства изображаемых объектов, заданная степень реалистичности изображения, имеющийся в наличии объем памяти, вычислительная эффективность алгоритма, простота его программной или
аппаратной реализации и т. д. Помимо рассмотренных в пособии
алгоритмов, существует немало других методов и процедур, решающих задачу реализации графического конвейера. Выбор для изложения именно тех алгоритмов, которые представлены в пособии,
вызван, во-первых, их наиболее частым использованием на практике, и, во-вторых, желанием показать различные (подчас весьма
оригинальные) подходы к решению поставленной задачи.
В заключение хотелось бы отметить, что немалый опыт преподавания курса «Компьютерная графика» в Санкт-Петербургском
государственном университете аэрокосмического приборостроения
и общение со специалистами, реализующими достаточно сложные
графические системы, неоднократно подтверждало тот факт, что
подчас простые вопросы, касающиеся математических процедур,
выполняющих весьма несложные графические преобразования,
ставят собеседников в тупик… И этот пробел в знаниях наблюдается не только у начинающих программистов, но и нередко у так
называемых «продвинутых» разработчиков графических пакетов.
Овладев технологией создания изображения сложных пространственных сцен и имитацией всевозможных зрительных эффектов,
разработчики часто имеют достаточно приблизительное представление о тех математических методах и алгоритмах, которые лежат
в основе создания всех этих «красот». Их знания не распространяются дальше владения (иногда весьма виртуозного) технологиями
программирования с использованием тех или иных средств разра180
ботки, знаниями и навыками применения разнообразных функций
и процедур из набора специализированных графических библиотек
(что само по себе не плохо, а, может быть, иногда и достаточно). Однако уровень знаний математических основ компьютерной графики у многих пользователей и разработчиков графических пакетов
находится, на мой взгляд, на неприемлемо низком для современного специалиста уровне.
Одна из причин этого, по-видимому, заключается в недостатке
на рынке учебной литературы книг, посвященных базовым математическим основам компьютерной графики, и ориентированных
на пользователей, находящихся в начале пути постижения стремительно развивающейся области знаний под общим названием
«Компьютерная графика». Скорректировать сложившуюся ситуацию надеюсь поможет предлагаемое пособие.
181
Библиографический список
1. Аммерал Л. Принципы программирования в машинной графике. – М.: Сол. Систем, 1992. 224 с.
2. Боресков А. В., Шикин Е. В., Шикина Г. Е. Компьютерная графика: первое знакомство. М.: Финансы и статистика, 1996. 176 с.
3. Гилой В. Интерактивная машинная графика: Структуры данных, алгоритмы, языки: пер. с англ. М.: Мир,1981. 384 с.
4. Голованов Н. Н. Геометрическое моделирование. М.: Изд-во
физико-математической литературы, 2002. 472 с.
5. Гук M. Аппаратные средства IBM PC: энциклопедия. СПб.:
Питер, 2006. 1072 с.
6. Иванов В. П., Батраков А. С. Трехмерная компьютерная графика. М.: Радио и связь, 1995. 213 с.
7. Кроновер Р. М. Фракталы и хаос в динамических системах.
Основы теории. М.: Постмаркет, 2000. 352 с.
8. Лапшин Е. Компьютерная графика IBM PC от точки к виртуальной реальности. М.: Солон, 1995. 195 с.
9. Макаренко В. Н., Либрович Л. В. Компьютерная графика. Алгоритмы преобразования изображений: метод. указ. к вып. лаб. работ/СПб., СПГААП. 1993. 31 с.
10. Мандельброт Б. Б. Фрактальная геометрия природы. М.,
2002. 656 с.
11. Морозов А. Д. Введение в теорию фракталов. М., 2002. 162
с.
12. Никулин Е. А. Компьютерная геометрия и алгоритмы машинной графики. СПб.: БХВ – Петербург, 2003. 560 с.
13. Ньюмен У., Спрулл Р. Основы интерактивной машинной графики: пер. с англ. М.: Мир, 1976. 573 с.
14. Павлидис Т. Алгоритмы машинной графики и обработки
изображений: пер. с англ. М.: Радио и связь, 1986. 400 с.
15. Порев В. Н. Компьютерная графика. СПб.: БХВ – Петербург, 2004. 432с.
16. Роджерс Д. Алгоритмические основы машинной графики.
М.: Мир, 1989. 504 с.
17. Роджерс Д., Адамс Дж. Математические основы машинной
графики. М.: Мир, 2001. 604 с.
18. Фоли Дж., вэн Дэм А. Основы интерактивной машинной графики: В 2-х кн. М.: Мир, 1985.
19. Шикин Е. В., Плис А. И. Кривые и поверхности на экране
компьютера. Руководство по сплайнам для пользователей. М.:
ДИАЛОГ-МИФИ, 1996. 240 с.
182
20. Шикин Е. В., Боресков А. В. Компьютерная графика. Динамика, реалистические изображения. М.: ДИАЛОГ-МИФИ, 1995.
178 с.
21. Шикин Е. В., Боресков А. В. Компьютерная графика. Полигональные модели. М.: ДИАЛОГ-МИФИ, 2000. 464 с.
22. Энджел И. Практическое введение в машинную графику:
пер. с англ. М.: Радио и связь, 1984. 136 с.
183
Содержание
Введение...................................................................................3
1. Стадия геометрических преобразований....................................7
1.1. Моделирование...........................................................7
1.1.1. Тесселяция.........................................................8
1.1.2. Моделирование с использованием кривых и поверхностей
20
1.1.3. Моделирование с использованием методов фрактальной
геометрии. ................................................................ 44
1.2. Модельные преобразования........................................ 63
1.2.1. Преобразования изображений............................. 63
1.2.2. Алгоритмы удаления невидимых линий и поверхностей
80
1.3. Модели освещенности.............................................. 109
1.3.1. Диффузное отражение...................................... 109
1.3.2. Зеркальное отражение...................................... 111
1.3.3. Преломление света........................................... 112
1.3.4. Модель освещенности Фонга ............................. 114
1.3.5. Модель освещенности со специальными эффектами (модель направленного освещения).................................. 115
1.3.6. Учет свойств вещества отражающей поверхности в модели освещенности...................................................... 117
1.3.7. Методы трассировки лучей............................... 118
1.4. Тени ..................................................................... 124
1.4.1. Преобразование «на землю».............................. 125
1.4.2. Совмещение процедур удаления невидимых поверхностей
и построения теней................................................... 129
1.4.3. Алгоритм построения полутеней (алгоритм Кука).135
2. Рендеринг......................................................................... 140
2.1. Cортировка по Z-буферу и смешение текстур.............. 140
2.2. Наложение текстуры............................................... 141
2.2.1. Точное текстурирование (point-sampling)............ 142
2.2.2. Аффинное текстурирование.............................. 146
2.2.3. Перспективно-корректное текстурирование........ 147
2.2.4. Параболическое текстурирование...................... 147
2.2.5. Билинейная фильтрация текстур....................... 148
2.2.6. Мипмэппинг...............................................................150
2.2.7. Трилинейная фильтрация текстур..................... 152
2.2.8. Рельефное текстурирование(Bump mapping)........ 152
2.3. Методы закраски.................................................... 154
2.3.1. Закраска Ламберта .......................................... 154
2.3.2. Закраска Фонга............................................... 155
2.3.3. Закраска Гуро................................................. 160
2.4. Алгоритмы сглаживания (аnti-aliasing)..........................167
184
2.4.1. Алгоритм Брезенхема для сглаживания ребер многоугольников............................................................... 168
2.4.2. Алгоритм Ву................................................... 174
2.4.3. Улучшение качества изображения фильтрацией.. 175
2.2.4. Сглаживание методом усреднения по площади.... 176
2.4.5. Субпиксельное сглаживание............................. 176
Заключение................................................................. 180
Библиографический список............................................ 182
185
Учебное издание
Макаренко Валерий Николаевич
МАТЕМАТИЧЕСКИЕ МЕТОДЫ И
АЛГОРИТМЫ КОМПЬЮТЕРНОЙ ГРАФИКИ
Учебное пособие
Редактор В. П. Зуева
Верстальщик А. Н. Колешко
Сдано в набор 18.01.10. Подписано к печати 25.05.10.
Формат 60×84 1/16. Бумага офсетная. Усл. печ. л. 9,77.
Уч.-изд. л. 11,06. Тираж 100 экз. Заказ № 225.
Редакционно-издательский центр ГУАП
190000, Санкт-Петербург, Б. Морская ул., 67
Документ
Категория
Без категории
Просмотров
1
Размер файла
10 628 Кб
Теги
makarenkoindd
1/--страниц
Пожаловаться на содержимое документа