Использование алгоритма обратной трассировки лучей при построении реалистичного изображения. Метод обратной трассировки

Не так давно 4A Games, создатель удивительно реалистичных игр Metro, выпустила видеоролик с использованием технологии RTX от Nvidia на примере METRO: EXODUS. Это графическое нововведение является большим и уверенным шагом вперед в вопросах трассировки лучей. Но что это все это значит?

За завесой тайны

Начнем с самого начала. Во-первых, рендеринг-трассировка лучей – это один из базовых видов визуализации, который применяется в фильмах и разных видах дизайна: от промышленности до архитектуры. То есть то, что вы видите на сайтах в качестве фотографий техники – это именно 3d рендер.

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

Это компьютерное изображение, созданное Enrico Cerica с использованием OctaneRender, показывает лучи, тени и отражения на сложной поверхности пола

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


Упрощенная схема трассировки лучей

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

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

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

Особенно заметно, что в матовых площадках отражение сильно зависит от близости объекта к поверхности. То есть, чем объект дальше от поверхности, тем он сильнее становится размытым. Это важное свойство, которое в жизни мы даже не замечаем, хотя оно есть.

Но самое важное – это тени. Нет ничего более некачественного, чем тени в любых играх.

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


Чтобы создать мягкие тени или диффузные отражения (например, те, которые вы видите в матовом металле, например), необходимы более совершенные методы трассировки лучей

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

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

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

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

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

Две половинки одного целого

Если внимательно проследить, как поэтапно рендерится картинка, то можно увидеть, что где-то после пятой интеграции сами тени и свет уже едва заметно меняются. Становится понятно, где, что и как будет выглядеть в финальном виде. Для этого в принципе и нужен в софте real-time, чтобы можно было покрутить источники света, понять где будут какие-то блики и затем запустить финальную отрисовку. Остается узнать, как по мутной картинке можно понять финальный кадр. На самом деле компьютер сначала моделирует исходную зашумленную картинку, затем анализирует ее и на основе полученных данных рисует уже другую – итоговую. Как показала практика, такой подход проще в плане ресурсных затрат.

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

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

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


Отражение лучей света от поверхности

В деморолике такого эффекта не было. Вместо светоотражения и изменения световой картины кадра в зависимости от источника света, все пространство заполнили яркими картинками, от чего свет и кажется динамичным. На самом же деле разработчики не применяли трассировку лучей на такие детали как дымка и языки пламени.

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

Когда мы увидим выгоду?

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

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

Текст: Алексей Харитонов, QA, Bytex

В данной статье речь пойдёт о применении метода обратной трассировки лучей для визуализации изображений в компьютерных играх. Рассматриваются его преимущества и недостатки по сравнению с традиционной технологией. Рассказывается о концептуальной 3D игре, в которой впервые используется графический движок, полностью построенный на принципе обратной трассировки лучей. Также затрагиваются вопросы развития игровых видео ускорителей.

Традиционная технология

Для тех, кто не знаком с теорией 3D графики, я коротко поясню, в чём заключается метод обратной трассировки лучей, и каково его отличие от традиционного метода игровой графики. В традиционном методе визуализации изображения в компьютерных играх сцена или, если угодно, игровой мир, представляется набором треугольников. Для каждого треугольника задаются текстуры и степень освещённости. Далее треугольники скопом заталкиваются в 3D ускоритель и отрисовываются, примерно, как художник чертит на листе бумаги сплошной треугольник. Отличие состоит в использовании буфера глубины. Буфер глубины требуется, что бы не рисовать треугольники, которые закрыты другими объектами сцены. При отрисовке точек нового треугольника проверяется соответствующее значение буфера глубины. В буфере глубины, или ещё его называют Z-буфер, хранится дальность от наблюдателя до уже нарисованного изображения. Если дальность до точки нового треугольника меньше записанного в Z-буфере значения, то эта точка не накрыта точками более близко расположенных треугольников, и её можно рисовать, при этом так же обновляется значение буфера глубины. Этот метод позволяет построить изображение состоящей из треугольников сцены произвольной сложности. Одно из достоинств этого метода состоит в том, что его можно было реализовать - то есть, визуализировать достаточно содержательную игровую сцену в реальном времени и в высоком разрешении - на "древних" процессорах поколения i386, i486.

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

Однако, трёхмерная сцена состоит не только из одних геометрических деталей, она не мыслима без света, поскольку иначе мы её просто бы не увидели. А метод Z-буфера позволяет нарисовать только геометрию сцены. Что же делать? Точная физическая модель распространения света очень сложна, речь может идти о неких приближениях к естественному освещению. Требуется, чтобы в затенённых местах, куда не попадают прямые световые лучи, было темно, рядом с источниками света - светло. Для создания реалистичного, с точки зрения освещённости, изображения сцены стали использовать заранее просчитанные текстуры, так называемые lightmap, содержащие значения освещения статических объектов сцены. Такая текстура накладывается в месте с обычной текстурой материала и затемняет её в зависимости от положения объекта на сцене, его освещённости. Естественно, при этом требуется полная статичность сцены и источников света, поскольку просчёт этих lightmap происходит крайне долго. Эта технология используется в компьютерных играх уже много лет, и её использование привело к тому, что трёхмерные игры в части графического движка стали отличаться лишь количеством треугольников и текстур на уровне. Как не было динамических источников света и возможности разрушать уровень, так её и нет, поскольку нет динамического расчёта освещённости-затенённости. Если вы передвинете светильник или закроете окно, освещённость сцены никто не изменит, поэтому такой возможности в играх нет. Есть только так называемые fake решения, когда что-то можно сделать в определённом месте, потому что эта возможность заранее предусмотрена и всё заранее рассчитано.

Только недавно стали появляться тени от динамических моделей, всяких монстров, ботов. Мы ещё затронем тему, каким образом эти тени рассчитываются, но часто они выглядят не естественно, поскольку, например, источников света много, а тень идёт только от одного, резкая и не красивая.
Прогресс игровой графики уже много лет связывают исключительно с появлением новых поколений графических ускорителей. Действительно, оказалось очень удобным переложить работу по рисованию треугольников на акселератор. Задача растеризации и текстурирования треугольника лежит в основе игровой графики, поэтому естественно, что эту очень частную и специфическую операцию удалось кардинально ускорить созданием специально оптимизированного железа. Однако, применение ускорителей привело лишь к улучшению качества изображения, качественным режимам наложения текстур, три линейной и анизотропной фильтрации, возможности использовать большие разрешения и полноэкранное сглаживание изображения. В части расчёта освещённости и динамичности сцены до сих пор ничего не поменялось. Отсутствие динамического света делает уровни современной игры скучными. Статичность освещения и сцены постепенно может надоедать. Как будто время остановилось, и играющие бегают в этом остановленном времени. Сейчас при исследовании возможностей новых ускорителей любят рассматривать экран под лупой, выискивая очередное уже незначительное увеличение качества изображения, которое в игре различить крайне трудно.

Метод трассировки лучей


Интересно, а каким же методом рассчитывают реалистичное освещение при рендеренге реалистичных сцен, мультиков, анимационных сцен, какой принцип лежит в основе построения тех же lightmap? В этой области получил распространение метод трассировки лучей и его модификации.

В обзорах процессоров часто упоминаются результаты тестирования в пакетах 3D графики, таких как 3DMax, LightWave и другие. Замеряется время отрисовки какой-нибудь сложной сцены с реалистичным освещением, отражением и преломлением света. Вот как раз сцена и рисуется с помощью метода трассировки лучей.

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

Однако, легко понять, что этот метод крайне вычислительно сложен. Можно обратить внимание в тестах процессоров в программах 3D моделирования, как долго считается даже 1 кадр. Никаким реальным временем тут и не пахнет. Тем более, раньше на персональных компьютерах он выполнялся ещё медленнее, что не оставляло возможностей для его применения в компьютерных играх.
Но за последние несколько лет мощность персональных компьютеров серьёзно возросла и позволила осуществлять метод трассировки лучей почти в реальном времени, правда, с большими ограничениями по качеству изображения и разрешению.

Поскольку для каждой точки экрана нужно осуществить очень сложную процедуру трассировки луча, то скорость трассировки очень сильно зависит от разрешения экрана, от его площади. То есть, построение изображения размером 1024x768 будет занимать в 10 раз больше времени, чем отрисовка изображения в разрешении 320x240. Реализовать метод трассировки лучей в реальном времени можно, весь вопрос, в каком разрешении и с каким качеством изображения.


До последнего времени трассировка лучей в реальном времени на PC была уделом небольших демо - программ, рисующих красивые изображения, но работающих с низкой скоростью и в низких разрешениях. Таких программ полным полно на www.scene.org . Однако, мне удалось, временно пожертвовав многими прелестями метода трассировки лучей, создать полноценный 3D-движок и на его основе первую компьютерную игру, использующую трассировку лучей в реальном времени.

Concept game с 3D движком на основе метода обратной трассировки лучей

На разнообразных автомобильных выставках демонстрируются так называемые concept-car, реальные прототипы будущих серийных автомобилей. Они крайне дороги, не отлажены с потребительской точки зрения, но олицетворяют собой новые идеи. Я же создал concept-game. Что же получилось реализовать, что бы работало в реальном времени на современных персональных компьютерах?
Для движка на трассировки лучей было изначально установлено два главных требования: чтобы расчёт всей освещённости сцены происходил в реальном времени, и чтобы не использовалась никакая заранее рассчитанная информация об уровне. Всё это должно позволить произвольно изменять уровень в динамике. То, что не могут обеспечить современные движки.
Вкупе с динамическим расчётом освещения отсутствие предварительной информации позволяет довольно просто рисовать бесконечные миры, поскольку нужно хранить только не очень объёмную информацию о геометрии уровня.

Выполнение этих строгих требований на современных процессорах потребовало введения других серьёзных ограничений, к счастью, не принципиальных. Однако, с ростом доступной вычислительной мощности эти ограничения будут сниматься, а суть - оставаться.
В первую очередь, я отказался от моделирования именно земной реальности в пользу инопланетных миров. Это позволило отказаться от использования не очень удобного для рейтрейсинга треугольника в качестве основного примитива для конструирования сцены. Инопланетный мир не обязан быть угловатым, пусть он будет круглым. В качестве примитива для построения сцены была выбрана сфера. Поскольку современные игры должны работать в высоких разрешениях, таких, как 1024x768, пришлось отказаться от расчёта отражений и преломлений, поскольку это очень сильно усложняло обработку соответствующего точке экрана луча. Но с ростом вычислительной мощности можно будет расширить как множество примитивов, так и глубину трассировки луча, то есть, добавить отражения, преломления и т.п.

Итак, каковы основные характеристики VirtualRay - 3D движка, построенного на методе трассировки лучей? На самых современных процессорах для персональных компьютеров он работает с более-менее приемлемой скоростью в разрешении 1024x768x32. Будем исходить, что используется именно это разрешение, поскольку если использовать меньшее разрешение, то параметры производительности могут быть другими.

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

Покадровый расчёт всей освещённости и затенённости. Все источники света - динамические (даже статические), поскольку они на самом деле динамические, только не изменяющие положение от кадра к кадру.

Попиксельный расчёт освещённости и попиксельное наложение теней, естественно, динамических.

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

До 8 источников света может освещать одну сферу, соответственно, одна сфера может отбрасывать до 8 теней. Это не принципиальное ограничение, просто, когда в одной области много источников света, всё, конечно, сильно замедляется.

Поддержка точечных источников света и бесконечно удалённых источников света типа солнца. Как правило, сцену освещает один "солнечный" источник света, и несколько локальных.

Полностью динамическая сцена, то есть, положение объектов может меняться произвольным образом.

Наложение и билинейная фильтрация текстур.

Ограниченное использование прозрачных сфер с динамическим коэффициентом прозрачности.

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

К локальным недостаткам движка в первую очередь можно отнести то, что он скуп на "дешёвые" эффекты, вроде спрайтовых вспышек и т.п., которые так замечательно делают современные видео ускорители.
Какую же игру оказалось возможным создать с использованием движка VirtualRay? Вообще, на нём можно сделать великое множество игр, начиная от космического симулятора и заканчивая многопользовательской онлайновой вселенной. Кстати, в последнем типе особенно проявляются преимущества движка по реализации динамического изменения сцены. В качестве "концептуальной игры" я создал проект под названием AntiPlanet - простенький 3D shooter с прямолинейными монстрами с поведением в духе Doom. Уровни к игре представляют собой разного размера куски инопланетной местности, освещаемой местными солнцами. Кстати, Солнце совершает движение по небу в соответствии с которым меняется освещение и затенение сцены. Всего в текущей версии игры доступно 5 уровней, один из которых - indoor, лабиринт из пещер. Остальные, в основном, открытые. Движок достаточно универсален, чтобы без специальных оптимизаций рисовать как открытые, так и закрытые сцены.

Есть 5 видов охотящихся за играющим монстров, монстры отличаются типом используемого оружия, скоростью и силой. Кстати в распоряжении играющего - десять видов оружия, стреляющего разнообразными снарядами, ракетами и бомбами. Сферическая природа оружия делает его несколько однообразным, зато снаряды при взрыве разлетаются на кучу осколков. Есть 3 основных вида игры - просто охота на монстров, когда игроку требуется за определённое время уничтожить определённое количество монстров. Второй вид игры состоит в нахождении спрятанных на уровне специальных артефактов. И в третьем случае играющему просто предстоит выжить определённое время на неизвестной планете. При выборе игры можно самому установить количество аптечек, оружия и монстров на уровне, они будут расставлены в случайные места. Конечно, если задать очень большое количество монстров, игра будет работать медленно.

К сожалению, игра не раскрывает весь потенциал движка, поскольку мы с моделлером просто не успели это сделать. Например, нет разрушения уровня, только отдельные динамические части, поскольку тогда тупые монстры дороги не найдут, с другой стороны, это не предусмотрено идей игры. Не полностью реализованы возможности движка по части анимации моделей. Движок позволяет произвольное независимое изменение моделей на каждом кадре, что делает возможным реализацию самой изощрённой анимации.
Я решил не приводить ни каких скриншотов из игры, поскольку они совершенно не передают достоинства движка, как-то динамическое освещение и мягкие тени. Скачайте демо-версию, она занимает всего несколько мегабайт. А так представьте себе сюрреалистическую инопланетную местность, состоящую из огромного количества шаров, монстров из небольших сфер, которые при взрыве разлетаются на мелкие кусочки. Скачать текущую демо-версию можно по этой ссылке .

Для игры требуется Windows95 и выше, желательно больше 128 мегабайт памяти, иначе отключите музыку, DirectX, видео карта с поддержкой 32-битного цвета, и, самое главное, процессор помощнее. Например, процессор Intel Pentium 4 с поддержкой технологии Hyper-Threading, или новый AthlonXP. Игра должна запускаться на любом процессоре с технологией MMX, однако для полной функциональности нужна поддержка SSE, то есть, процессор начиная с Pentium-III. Видео ускоритель не требуется. Кстати, движок поддерживает многопроцессорность, в том числе, и технологию Hyper-Threading. Не вся программа использует несколько потоков для успешного использования Hyper-Threading, но главный цикл трассировки лучей распараллелен, и достигается выигрыш в несколько десятков процентов. А на многопроцессорной системе выигрыш пропорционален количеству процессоров.

Развитие движка VirtualRay

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

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

Кстати, о качестве. Тут есть большой резерв для улучшения. Дело в том, что процедура текстурирования выполняется всего один раз на точку и не отнимает много времени. Сейчас на текстурирование тратится около 10% времени рендеренга. Так что, для улучшения качества текстурирования планируется реализовать попиксельную трилинейную фильтрацию, это не должно существенно понизить скорость.

Рейтрейсинг и современные 3D-ускорители

Последнее время индустрия 3D-ускорителей совершает переход к повсеместному использованию так называемых пиксельных и вертексных шейдеров. При растеризации треугольника для каждого фрагмента изображения ускоритель выполняет заранее заданную программку, которая изменяет сложным образом цвет фрагмента. Она может ещё много чего делать, например, какие-то промежуточные вычисления записывать в текстуры, которые потом будут читаться и использоваться при отрисовке чего-то другого. Типичным примером современного пиксельного, или как его ещё называют, fragment шейдера является шейдер, вычисляющий освещение данной точки треугольника. Он устроен следующим образом: берётся вектор - глобальная позиция источника, берётся текущая координата точки треугольника в трёхмерном пространстве, которая вычисляется в чипе ускорителя при растеризации треугольника, и нормаль к треугольнику в данной точке. Далее вычисляется вектор из данной точки в направлении на источник света и в зависимости от угла, который он образовывает с нормальным перпендикулярным вектором, высчитывается освещённость. Чем под большим углом падает свет, тем меньше его интенсивность.
Как мы видим, современный шейдер может быть содержательной геометрической программой. Сейчас принято тестировать новые ускорители путём измерения скорости выполнения таких вот и более сложных шейдеров. Производительность получается очень большой. Шейдер, выполняющий попиксельное освещение работает в разрешении 1024x768 со скоростью 100-200 кадров в секунду на последних акселераторах, таких, как Radeon9700 или GeForceFX. Имеется ввиду только время работы непосредственно шейдера. В связи с этим давно уже появилась мысль использовать такую немалую вычислительную мощность в самых разнообразных целях, даже далёких от 3D графики. И, в том числе, попытаться использовать для реализации метода трассировки лучей.

Однако, если рассмотреть эту мощность с точки зрения количества скалярных и векторных вычислений с плавающей точкой в единицу времени, то она оказывается сравнимой с вычислительной мощностью современных процессоров. Возьмём самый новый на сегодняшний день ускоритель GeForceFX5900Ultra, он имеет частоту 450MHz, 4 пиксельных процессора, каждый из которых может совершать 1 векторную операцию за такт. На самом деле, операций за такт может быть больше, но нам интересны только вычисления с полной точностью float32, поскольку вычисления с меньшей точностью имеют смысл в основном для вычисления цвета, диапазон которого всё равно ограничен не очень большим цветовым разрешением монитора. А для геометрических расчётов требуется хорошая точность. Получается 450Mx4=1800 миллионов векторных операций в секунду как грубая оценка производительности. Если же взять Pentium 4, то при использовании SSE можно достичь одной векторной операции за полтора такта, то есть при частоте 2700MHz получим те же 1800 миллионов векторных операций в секунду. В обоих случаях имеет в виду, естественно, пиковая производительность, когда весь код только и состоит из вычислений.
Видно, что превосходства в вычислительной мощности у VPU нет. Его преимущество в графике заключается в умении параллельно с вычислениями шейдера производить сопутствующие вычисления, необходимые для растеризации треугольника. Как-то вычислять значение буфера глубины, интерполировать по поверхности треугольника заданные в вершинах значения, и осуществлять за такт выборку и фильтрацию текстур. Всё это осуществляется различными параллельно работающими блоками видео ускорителя.

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

Расчёт освещения с помощью современных ускорителей

Хорошо, а каким же образом предлагается рассчитывать затенённость сцены в новых играх с динамическими источниками света, такими, как Doom III? Неужели мы теперь навсегда обречены видеть в компьютерных играх заранее рассчитанное статическое освещение? Нет, давно известны интересные методы расчёта теней на основе использования стандартного метода рисования текстурированых треугольников с помощью z-буфера. Известны они давно, но они такие требовательные к вычислительным ресурсам, что их применение в компьютерных играх, и то, ограниченное, стало возможным только недавно с появлением нового поколения видео ускорителей.

Рассмотрим для начала метод, с помощью которого рисуются динамические тени в вышеупомянутой игре Doom III. Игре, которую очень ждут многие геймеры. Этот метод называется методом Теневых объёмов, или методом отрисовки теней с помощью стенсил - буфера. Вот принципиальная схема его работы: сначала рисуется не освещённая сцена, далее для каждого отбрасывающего тень объекта сцены строится его теневой объём. Теневой объём - это фигура, ограничивающая теневую область, ту область пространства, в которую не попадает свет, которая затенена данным объектом. Мы как бы представляем простирающуюся за объектом черноту в виде тела. Теневой объём можно даже в реальности увидеть, если осветить резким светом комнату, в которой летают частички пыли. Не затенённые частицы будут светиться, а затенённые будут образовывать черную область за загораживающим свет объектом. Следующий шаг состоит в отрисовке треугольников, составляющих границу этого теневого объёма. Путём сравнения значения буфера глубины с глубиной передней и задней стенок теневого объёма определяется, лежит ли данная точка в теневом объёме и, таким образом, затеняется, или нет. Вот при сравнении глубины стенок теневого объёма и глубины изображения используется стенсил буфер - отвечающий экранным пикселям массив значений. В нём хранятся промежуточные результаты сравнения глубины стенок теневого объёма с глубиной изображения. Этот метод "хорош" тем, что вовсю использует fillrate ускорителя, поскольку теневые объёмы, как правило, имеют большую площадь на экране, чем отбрасывающий тень объект. Метод был доступен для реализации ещё на ускорителях Riva TNT2, но он такой требовательный, что его применение стало возможным только недавно.

С другой стороны, построение оптимальных теневых объёмов для сложных не выпуклых объектов является непростой с вычислительной точки зрения задачей. Решение "в лоб" приведёт к возникновению большого количества лишних стенок теневого объёма, отрисовка которых потребует дополнительных ресурсов. Время нахождения эффективного объёма очень быстро растёт со степенью детализации модели. Возможно, именно благодаря этому модели монстров в NewDoom менее детализированы, чем ожидалось.
Но это ещё не все недостатки. У многих небольших объектов площадь стенок теневого объёма может достигать гигантской величины. Например, у расчески. Её теневая область не велика, но очень извилиста. Далее, метод не очень хорошо совместим с прозрачными поверхностями. Например, если в теневой объём попадает прозрачная поверхность, тогда находящийся за ней объект не оставляет своей информации в буфере глубины, поскольку эта информация затёрлась глубиной прозрачной поверхности. И определить, лежит ли объект в теневом объёме, невозможно. Все случаи такого рода придётся обрабатывать отдельно, что будет приводить к увеличению количества проходов рендеренга.

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

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

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

Я даже не знаю, какой из выше описанных методов более требователен к fillrate ускорителя. Дело в том, что для получения хорошего качества тени, требуется, чтобы теневая текстура была очень большого разрешения. В новых играх, вроде Splinter Cell, используются текстуры размером несколько тысяч пикселей. Причина заключается в том, что при проецировании самые мелкие детали многократно увеличиваются в размере. Становятся видны составляющие изображение пиксели. Таким образом, этот метод можно использовать только для наложения теней на близко расположенные объекты. Вторым недостатком этого метода является невозможность самозатенения объекта, требуется точно выделять отбрасывающий тень объект, и его части не будут отбрасывать тень друг на друга. И в дополнение, естественно, никакого обобщения для расчёта вторичной освещённости, отражений и преломления света, этот метод не предполагает.

И, наконец, рассмотрим самый, на мой взгляд, перспективный для использования в современных играх метод построения теней. Он является развитием предыдущего проективного метода. Только вместо силуэта объекта в теневую текстуру записывается расстояние от точек объекта до источника света. Далее, при проецировании теневой текстуры эта информация используется для определения, лежит ли точка потенциально затеняемого объекта дальше, или ближе к источнику света, чем затенитель. Преимущество этого метода состоит в корректном самозатенении объекта. А недостатки у него аналогичны предыдущему методу. Этот способ построения динамических теней не пользуется популярностью у разработчиков игр. "Вина" метода заключается в том, что он требует специфических возможностей видеокарты, которые впервые появились в GeForce3 - Geforce4, но были изъяты из Geforce4MX - сокращённой версии Geforce4. Без поддержки железа метод реализовать невозможно, так что приходится использовать способ, осуществимый на всех популярных видео картах.

Преимущество всех выше названных методов заключается в хорошей совместимости с существующим "железом". Для них, по сути, ничего не надо, кроме fillrate и простейших операций. В итоге, можно сделать вывод о том, что видео ускорители даже сейчас далеки от расчёта освещения сцены в реальном времени. И ничего революционного не предвидится. Появились тени от некоторых динамических объектов, ограниченный динамический свет в новом Doom III, вот эти технологии будут осваиваться в течение долгого периода времени.

Развитие ускорителей с точки зрения рейтрейсинга

Как я уже упоминал, современные ускорители становятся всё более и более программируемыми и мощность их неуклонно растёт. Производители видеокарт даже используют термин "Визуальный процессор" применительно к новым изделиям. Действительно, по своим возможностям, ускорители всё больше и больше напоминают обычные процессоры для персональных компьютеров. Вот именно с увеличением степени программируемости VPU связываются надежды по реализации интеллектуальных методов построения изображений, таких, как метод трассировки лучей. Что бы ускоритель можно было перепрограммировать подходящим образом.

Оценим перспективы развития ускорителей в этом направлении. Сейчас новейшие ускорители работают на частотах около 500MHz, как процессоры пятилетней давности, и имеют 4-8 параллельно работающих конвейеров. Сейчас большинство шейдерных векторных операций, сложение, скалярное произведение, выполняется за такт. Многие вспомогательные операции, вроде интерполяции значений по поверхности треугольника, тоже выполняются за такт. Вычисление тригонометрических функций, таких, как sin и cos, правда приближённое, выполняется тоже за такт. При этом используются выборки из таблиц с заранее просчитанными значениями, но, всё равно, производительность удивительна. Тем более, странно, что современные CPU для персональных компьютеров ничего подобного не умеют. Наоборот, наблюдается тенденция по избавлению от сложных команд и замене их несколькими простыми. Эти меры требуются для возможности наращивания частоты. Не вдаваясь в технические тонкости, можно сказать, что всё более и более уменьшающийся с ростом частоты процессорный такт требует более коротких команд. Сложные инструкции всё равно расщепляются внутри современных процессоров на микро операции. Это расщепление - тоже отдельная проблема, ей занимаются целые блоки процессора.

А что же видео ускорители? Вероятно, что для увеличения частоты придётся серьёзно переработать архитектуру современных VPU. Но это ещё полбеды. Для истинной программируемости требуется исполнение процессором ветвлений, то есть, команд управления выполнением программы. А с этим - всегда самые большие проблемы. Как современные процессоры страдают от непредсказуемых условных переходах в программах? Вот вершинные шейдеры в GeForceFX получили команды условных переходов, вы можете посмотреть свежие тесты, как сильно "просела" производительность. И это на сравнительно невысокой частоте ниже 500MHz. А с ростом частоты потери от условных переходов только увеличатся, да и сама их реализация - труднее. Кстати, фантастическая производительность акселераторов достигается при исполнении так называемых потоковых операций, когда данные идут сплошной полосой и обрабатываются по жёстко определённой схеме, никаких тебе случайных условных переходов и т.п. Все эти факты говорят о том, что увеличения частоты видео ускорителей ожидать в ближайшее время не приходится.

Важным параметром видеокарты является количество пиксельных процессоров. Они параллельно закрашивают пиксели, поэтому, чем их больше, тем лучше. На самых новых Radeon их аж восемь. От новых ускорителей ожидают всё большего количества fragment процессоров. Но не всё так просто. Дело в том, что когда размеры треугольника соизмеримы с количеством пиксельных конвейеров, они не могут все работать вместе. В маленьком треугольнике им не хватает места. В том числе, по этой причине производители видео ускорителей так любят режимы анти-алиасинга с отрисовкой всей сцены с удвоенным разрешением. Тогда маленькие треугольники становятся больше. Действительно, если сцену из больших треугольников разбить на более мелкие без изменения формы, то производительность выполнения пиксельных шейдеров существенно снизится, хотя общая площадь треугольников останется прежней.

Развитие современных ускорителей игровой графики и так сопряжено с большими трудностями, и идёт практически только за счёт усовершенствования технологического процесса производства видео чипов. Вся NVIDIA и ATI думают о том, как сделать эффективно простые динамические тени. Хорошего решения нет - им не до рейтрейсинга.

Специализированный ускоритель для рейтрейсинга

Если современные игровые VPU изначально проектировались для ускорения стандартного алгоритма рисования треугольников и мало пригодны для реализации трассировки лучей, то, может быть, имеет смысл изначально строить ускоритель для реализации рейтрейсинга? Увы, ускорять трассировку лучей - неблагодарное занятие.


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


Зато у трассировки лучей есть другое достоинство - она хорошо распараллеливается. Каждый луч можно рассчитывать независимо, что позволяет эффективно реализовать алгоритм на мультипроцессорных системах. В качестве дешевого ускорителя трассировки лучей можно рассматривать знаете что? Систему на четырёх Celeron частотой от 3 гигагерц, или четырёх AthlonXP с урезанным кэшем. Алгоритм трассировки лучей при правильной оптимизации не требователен к большому размеру кэша, так что получится дёшево и многофункционально. Совокупная вычислительная мощность будет намного превосходить текущие настольные компьютеры. Но этого не будет, поскольку многопроцессорные системы предназначены для другого рынка, не для домашних систем.

Заключение

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

Ссылки


http://www.art-render.com/

Сайт производителей "ускорителей рейтрейсинга" для оптимизации рендеренга в 3DMax и других графических редакторах. Ускоритель - это набор нескольких, от 8, оптимизированных для рейтрейсинга процессоров. Они умеют выполнять типичную для трассировки операцию - находить пересечение луча с треугольником - за один такт. Но, по-видимому, работают на не очень высокой частоте. Ускорение достигается за счёт параллельной работы. Сейчас на сайте трудно найти цены, но раньше я их видел, они совсем не маленькие.


http://www.acm.org/tog/resources/RTNews/html

Обширный список разнообразных ресурсов на тему трассировки лучей.


http://www.realstorm.com/

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


http://www.kge.msu.ru/workgroups/compcenter/dmitri/projects/sphericworld/index.htm

http://www.kge.msu.ru/workgroups/compcenter/dmitri/projects/polyworld/index.htm

Ещё один проект, посвящённый методу трассировки лучей. Реализован сферический и полигональный рейтрейсер, строящий очень качественные реалистичные изображения, но медленно в больших разрешениях.


http://www.virtualray.ru/

Это, собственно, сайт, посвящённый предмету статьи - движку VirtualRay и игре AntiPlanet - первому 3D shooter на основе ray trace движка.

Метод обратной трассировки

Метод обратной трассировки лучей позволяет значительно сократить перебор световых лучей. Метод разработан в 80-х годах, основополагающими считаются работы Уиттеда и Кея. Согласно этому методу отслеживание лучей производится не от источников света, а в обратном направлении - точки наблюдении. Так учитываются только те лучи, которые вносят вклад в формирование изображения.

Рассмотрим, как можно получить растровое изображение некоторой трёхмерной сцены методом обратной трассировки. Предположим, что плоскость проецирования разбита на множество квадратиков - пикселов. Выберем центральную проекцию с центром схода на некотором расстоянии от плоскости проецирования. Проведем прямую линию из центра схода через середину квадратика (пиксела) плоскости проецирования. Это будет первичный луч обратной трассировки. Если прямая линия этого луча попадает в один или несколько объектов сцены, то выбираем ближайшую точку пересечения. Для определения цвета пиксела изображения нужно учитывать свойства объекта, а также то, какое световое излучение приходится на соответствующую точку объекта.

Если объект зеркальный (хотя бы частично), то строим вторичный луч - луч падения, считая лучом отражения предыдущий, первичный трассируемый луч. Выше мы рассматривали зеркальное отражение и получили формулы для вектора отражённого луча по заданным векторам нормали и луча падения. Но здесь нам известен вектор отражённого луча, а как найти вектор падающего луча? Для этого можно использовать ту же формулу зеркального отражения, но определяя необходимый вектор луча падения как отражённый луч. То есть отражение наоборот, i.

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

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

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

Когда выясняется; что текущий луч обратной трассировки не пересекает какой-либо объект, а уходит в свободное пространство, то на этом трассировка для этого луча заканчивается.

Рис. 14.1 Пример обратной трассировки лучей.

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

Принцип работы метода трассировки лучей:

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

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

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

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

5. Влияние всех лучей, сгенерированных явно или неявно с помощью начального луча, суммируется и результат определяет RGB-значение данной точки.

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

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

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

Метод обратной трассировки лучей позволяет значительно сократить перебор световых лучей. Этот метод разработали в 80-х годах Уиттед и Кэй. В этом методе отслеживаются лучи не от источников, а из камеры. Таким образом, трассируется определенное число лучей, равное разрешению картинки.

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

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

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

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

Главной процедурой обратной трассировки лучей в моей программе является процедура Ray. Она имеет следующую структуру:

Если поколение луча равно максимальной глубине рекурсии, то возвращаем среднюю яркость по всем составляющим. Если нет, то идем дальше

Определяем ближайший треугольник, с которым пересекается луч.

Если такого треугольника нет, возвращаем цвет фона, если есть, идем дальше.

Если поверхность, с которой было найдено пересечение, отражает, то формируем отраженный луч и вызываем рекурсивно процедуру Ray с поколением луча, увеличенным на 1.

Если поверхность, с которой было найдено пересечение, преломляет, то формируем преломленный луч и вызываем рекурсивно процедуру Ray с поколением луча, увеличенным на 1.

Определяем итоговую освещенность пиксела, учитывая расположение источников, свойства материала, а так же интенсивности отраженного и преломленного луча.

Я уже рассмотрели ряд ограничений метода трассировки, когда говорили о диффузном преломлении и о неровном зеркале. Рассмотрим и некоторые другие.

Освещать сцену могут только специальные объекты - источники света. Они точечные и не могут поглощать, преломлять и отражать свет.

Свойства отражающей поверхности состоят из двух компонент - диффузной и зеркальной.

При диффузном отражении учитываются только лучи от источников света. Если источник освещает точку, через зеркало (зайчиком), то считается, что точка не освещена.

Зеркальность тоже делится на две составляющие.

reflection - учитывает отражение от других объектов (не источников света)

specular - учитывает блики от источников света

В трассировке не учитываются зависимости от длины волны света:

коэффициента преломления

коэффициента поглощения

коэффициента отражения

Так как я не моделирую диффузное отражение и преломление, то не смогу получить фоновую подсветку. Поэтому вводим минимальную фоновую освещенность. Часто она позволяет просто значительно улучшить качество изображения.

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

В моей программе есть возможность включить сглаживание изображения. Сглаживание заключается в том, что для определения цвета пиксела. пускается не один луч, а четыре и определяется среднее значение цвета у этих лучей. Если необходимо найти цвет пиксела (i,j), то пускаются 4 луча в точки экранной плоскости с координатами (i-0.25,j-0.25), (i-0.25,j+0.25), (i+0.25,j-0.25), (i+0.25,j+0.25).

Методы трассировки лучей (Ray Tracing ) на сегодняшний день считаются наиболее мо­щными и универсальными методами создания реалистичных изображений. Известно много примеров реализации алгоритмов трассировки для качественного отображения самых слож­ных трехмерных сцен. Можно отметить, что универсальность методов трассировки взначительной мере обусловлена тем, что в их основе лежат простые и ясные понятия, кото­рые отражают наш опыт восприятия окружающего мира.

Рис. 8.12. Модели отражения: а – идеальное зеркало, б - неидеальное зеркало, в – диффузное, г – сумма диффузного и зеркального, д – обратное, е - сумма диффузного, зеркального и лбратного

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

    излучают;

    отражают и поглощают;

    пропускают сквозь себя.

Рис. 8.13. Излучение – а – раномерно во все тороны, б - направленно

Каждое из этих свойств можно описать некоторым набором характеристик. Например, излучение можно охарактеризовать интенсивностью, направленностью, спектром. Излуче­ние может исходить от условно точечного источника (далекая звезда) или от источника рас­сеянного света (скажем, от расплавленной лавы, извергающейся из кратера вулкана). Рас­пространение излучения может осуществляться вдоль довольно узкого луча (сфокусиро­ванный луч лазера) или конусом (прожектор), или равномерно во все стороны (Солнце), или еще как-то. Свойство отражения (поглощение) можно описать характеристиками диффуз­ного рассеивания и зеркального отражения. Прозрачность можно описать ослаблением ин­тенсивности и преломлением.

Распределение световой энергии по возмож­ным направлениям световых лучей можно ото­бразить с помощью векторных диаграмм, в кото­рых длина векторов соответствует интенсивно­сти (рис. 8.12 – 8.14).

В предшествующих параграфах мы с вами уже ознакомились с видами отражения, которые упоминаются наиболее часто - зеркальным и диффузным. Реже в литературе поминается обратное зеркальное или антизеркальное от­ ражение, в котором максимум интенсивности отражения соответствует направлению на источник. Обратное зеркальное отражение имеют некоторые виды растительности на по­верхности Земли, наблюдаемые с высоты рисовые поля.

Два крайних, идеализированных случая пре­ломления изображены на рис. 8.13.

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

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

Рис. 8.14. Преломление а – идеальное, б - дифузное

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

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

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

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

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

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

Рис. 8.15. Схема обратной трассировки лучей

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

Метод обратной трассировки лучей позволяет значительно сократить перебор свето­вых лучей. Метод разработан в 80-х годах, основополагающими считаются работы Уитте-да и Кэя . Согласно этому методу отслеживание лучей осуществляется не от источ­ников света, а в обратном"направлении - от точки наблюдения. Так учитываются только те лучи, которые вносят вклад в формирование изображения.

Рассмотрим, как можно получить растровое изображение некоторой трехмерной сцены методом обратной трассировки. Предположим, что плоскость проецирования разбита на множество квадратиков - пикселов. Выберем центральную проекцию с центром схода на некотором расстоянии от плоскости проецирования. Проведем прямую линию из центра схода через середину квадратика (пиксела) плоскости проецирования (рис. 8.15). Это будетпервичный луч обратной трассировки. Если прямая линия этого луча попадает в один или несколько объектов сцены, то выбираем ближайшую точку пересечения. Для определения цвета пиксела изображения нужно учитывать свойства объекта, а также то, какое световое излучение приходится на соответствующую точку объекта.

Рис. 8.16. Обратная трассировка для объектов, имеющих свойства зеркального отражения и преломления

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

Для идеального зеркала дос­таточно потом проследить лишь очередную точку пересечения вторичного луча с некоторым объектом. Что означает термин "идеальное зеркало"? Будем считать, что такое зеркало имеет идеально равную отполированную поверхность, поэтому одному отраженному лучу соответствует только один падающий луч. Зеркало может быть затемненным, то есть поглощать часть световой энергии, но все равно выполняется правило: один луч падает - один отражается. Можно рассматривать также "неидеальное зеркало".Это будет означать, что поверхность неровная. Направлению отраженного луча будут соот­ветствовать несколько падающих лучей (или наоборот, один падающий луч порождает не­сколько отраженных лучей), которые образуют некоторый конус, возможно, несимметрич­ный, с осью вдоль линии падающего луча идеального зеркала. Конус соответствует некото­рому закону распределения интенсивностей, простейший из которых описывается моделью Фонга - косинус угла, возведенный в некоторую степень. Неидеальное зеркало резко ус­ложняет трассировку - нужно проследить не один, а множество падающих лучей, учиты­вать взнос излучения от других видимых из данной точки объектов.

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

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

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

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

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

1. Среди всех типов объектов выделяются некоторые, которые назовем источниками све­та. Источники света могут только излучать свет, но не могут его отражать или прелом­лять (будем рассматривать толькоточечные источники света).

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

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

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

5. Для прозрачных (1гап5рагеп() объектов обычно не учитывается зависимость коэффици­ента преломления от длины волны. Иногда прозрачность вообще моделируют без пре­ломления, то есть направление преломленного луча I совпадает с направлением падаю­щего луча.

    Для учета освещенности объектов светом, который рассеивается другими объектами, вводится фоновая составляющая(ат bient ).

7. Для завершения трассировки вводят некоторое предельное значение освещенности, ко­торое уже не должно вносить взнос в результирующий цвет, или ограничивают количе­ство итераций.

Согласно модели Уиттеда цвет некоторой точки объекта определяется суммарной интенсивностью

I() = KaIa()C() + KdId()C() + KsIs() + KrIr() + KtIt()

где λ - длина волны,

С (λ) - заданный исходный цвет точки объекта,

К а,K d ,K s ,K r и К t - коэффициенты, учитывающие свойства конкретного объекта через параметры фонового подсвечивания, диффузного рассеивания, зеркальности, отражения и прозрачности,

I a - интенсивность фонового подсвечивания,

I d - интенсивность, учитываемая для диффузного рассеивания,

I s - интенсивность, учитываемая для зеркальности,

I r - интенсивность излучения, приходящего по отраженному лучу,

I t - интенсивность излучения, приходящего по преломленному лучу.

Интенсивность фонового подсвечивания (1 а ) для некоторого объекта обычно константа. Запишем формулы для других интенсивностей. Для диффузного отражения

I d =

где I i (λ) - интенсивность излученияi - ro источника света, θ i - угол между нормалью к по­верхности объекта и направлением наi - vi источник света.

Для зеркальности:

I d =

где р - показатель степени от единицы до нескольких сотен (согласно модели Фонга),α i -угол между отраженным лучом (обратной трассировки) и направлением на г"-й источник света.

Интенсивности излучений проходящих по отраженному лучу (I r ), а так же по преломленному лучу (I t ) , умножают на коэффициент, учитывающий ослабление интенсивности в зависимости от расстояния, пройденного лучом. Такой коэффициент записывается в виде е - d где d - пройденное расстояние, – параметр ослабления, учитывающий свойства среды, в которой распространяется луч.

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

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

Известно несколько способов проверки произвольной точки на принадлежность полиго­ну. Рассмотрим две разновидности, в сущности, одного и того же метода (рис. 8.17).

Первый способ. Находятся все точки пересечения контура горизонталью, которая соответствует координатеYзаданной точки. Точки пересечения сортируются по возрастанию значений координат Х. Пары точек пересечения образуют отрезки. Если точка, которая проверяется, принадлежит одному из отрезков (для этого сравниваются координаты Х заданной точки и концов отрезков), то она – внутренняя.

Рис. 8.17. Точка – внутренняя, если: а - точка принадлежит секущему отрезку, б – число пересечений нечетное

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

Если луч пересекает несколько объектов, то выбирается ближайшая точка по направлению текущего луча.

Сделаем общие выводы о относительно метода обратной трассировки лучей.

Положительные черты

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

2. Даже усеченные варианты данного метода позволяют получить довольно реалистичные изображения. Например если ограничится только первичными лучами(из точки проецирования), то это дает удаление невидимых точек. Трассировка уже одного – двух вторичных лучей дает тени, зеркальность, прозрачность.

3. Все преобразования координат (если таковые имеются) линейные, поэтому довольно просто работать с текстурами.

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

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

Недостатки

1. Проблемы с моделированием диффузного отражения и преломления

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