В настоящее время существует множество задач компьютерной графики, требующих построения в реальном времени фотореалистичных и точных с точки зрения законов оптики изображений. Для решения таких задач применяются современные графические процессоры (GPU), обладающие программируемыми вершинными и пиксельными конвейерами, позволяющими разгрузить центральный процессор и значительно ускорить расчет изображения.
Одна из таких задач - моделирование дисперсии света в призме и аналогичных по оптическим свойствам предметах. Когда белый свет проходит через призму, составляющие его волны преломляются по-разному в зависимости от своей длины. Поэтому при наблюдении белого света через призму возникает «радуга», так как волны разной длины после внутренних отражений выходят из призмы из разных точек.При решении подобной задачи может возникнуть проблема, связанная с тем, что окружающая среда, в которой находится призма, задана не в виде спектральной панорамы, а в виде панорамы RGB. Такое задание панорамы является сейчас наиболее часто применяемым, так как создание и использование RGB-панорам довольно просто и не требует особых затрат (для создания такой панорамы можно использовать обычный цифровой фотоаппарат).
Однако для задачи моделирования дисперсии света такой способ задания окружения объекта не подходит, так как для моделирования правильного с оптической точки зрения эффекта дисперсии необходима более точная информация о свете, чем та, которая описывается компонентами RGB. Идеальным решением было бы использование непрерывного спектра, но на практике это решение является довольно сложным в реализации. Вполне приемлемым является решение об использовании дискретного спектра, то есть спектра, заданного на некотором определенном количестве длин волн с равными интервалами, например, на двадцати или восьмидесяти длинах волн (здесь спектр можно считать функцией, которая ставит в соответствие длине волны ее интенсивность). В этом случае цвет, заданный тремя параметрами RGB, можно рассматривать как спектр, заданный на трех длинах волн (на длинах, соответствующих красному, зеленому и синему). Но такого задания спектра для моделирования радуги, похожей на настоящую, не достаточно. Количество полутонов в радуге напрямую зависит от количества длин волн, для которых мы рассчитываем преломления. Соответственно, появляется задача по имеющимся значениям RGB некоторым образом реконструировать значения интенсивностей для остальных длин волн, чтобы получить более полную информацию о спектре цвета.
Для решения задачи моделирования эффекта дисперсии предлагается рассчитывать преломления лучей только в вершинах объекта (при этом необходимо рассчитывать преломления для разных длин волн), находить точки и направления, с которыми эти лучи после ряда внутренних отражений вышли из объекта, затем по этим направлениям производить выборку из панорамы (сцены, в которой находится объект), преобразовывать ее попиксельно к спектральному представлению, а затем из полученного спектра выбирать только ту интенсивность, для которой мы проводили преломление лучей. Полученную интенсивность необходимо снова преобразовать к RGB, и набор полученных изображений грани после преломления лучей для разных длин волн необходимо просуммировать для получения результирующего изображения исходной грани, через вершины которой мы трассировали лучи.
Спектр в общем случае - это совокупность значений или их распределение по какому-либо параметру, которую может принимать наблюдаемая величина.
Свет имеет волновую природу. А именно, свет - это видимая часть спектра электромагнитных волн. Каждая волна характеризуется своей длиной. Область электромагнитного спектра, которую может воспринимать человеческий глаз, находится в промежутке приблизительно от 400 до 700 нанометров.

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

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

Рис. 3. Спектрофотометр X-Rite DTP41
Такие устройства позволяют получить спектр цвета в локальных масштабах, то есть при близком контакте с объектом, свойства которого мы хотим изучить. В случае, если нам необходимо получить целую панораму, каждый пиксель которой представлен в виде спектра, этот метод не подходит. Для этого применяется другой, менее точный, зато гораздо более легко применимый на практике подход. Для съемки панорамы необходимо воспользоваться набором объективов-фильтров для фотоаппарата, позволяющих на кадре оставить только волны определенного участка видимого спектра. Но такой подход все равно достаточно трудоемок, так как для получения панорамы нам нужно сделать множество снимков для разных направлений, и для каждого направления делать столько снимков, сколько фильтров мы хотим использовать.
При решении задачи восстановления спектра по значениям RGB авторами было рассмотрено два подхода.
Первый подход заключается в применении так называемых весовых функций, отвечающих за вклад каждой из компонент RGB (красного, зеленого, синего) в спектр цвета. Этот подход основывается на том предположении, что значения, заданные в качестве компонент R, G и B, отражают не только интенсивность спектра на соответствующих длинах волн, но и интенсивности для других длин волн. А вклад каждой компоненты в интенсивность на определенной длине волны и определяется значением весовой функции на этой длине волны. То есть, весовая функция для данной компоненты RGB фактически является спектром цвета, у которого данная компонента равна единице, а все остальные компоненты равны нулю.
Второй подход заключается в использовании альтернативного цветового пространства, а именно HSL (Hue, Saturation, Lightness). По цвету, заданному в системе HSL, можно практически напрямую построить спектр, излучаемый источником с данным цветом.
Основная идея данного подхода заключается в присваивании каждой компоненте цвета, заданного в пространстве RGB, своей весовой функции, которая определяет вклад этой компоненты в результирующий спектр.
Основным плюсом такого подхода является возможность задания различных функций в качестве весовых, и тем самым, возможность моделировать различные источники света путем задания различных функций. Здесь предполагается, что панорама, задающая окружение, в котором находится объект, является распределенным источником света, и каждая ее точка излучает свет, соответствующий цвету этой точки на панораме.
В качестве исходных данных для работы алгоритма необходимо задать три весовых функции. Значения этих функций сохраняются в RGB-текстуру, при этом длина волны изменяется вдоль оси ОХ от значения, соответствующего ультрафиолетовому излучению, до значения, соответствующего инфракрасному излучению (то есть значение длины волны пробегает по всему видимому спектру). Для каждой длины волны в соответствующем пикселе хранится цвет в пространстве RGB, при этом значение R-компоненты расценивается как значение в данной точке весовой функции для красного, значение G-компоненты - как значение весовой функции для зеленого, и значение B-компоненты - как значение весовой функции для синего. На рисунке 1 показан пример задания трех весовых функций. В верхней части изображена текстура, которая должна быть подана на вход алгоритму построения спектра, а в нижней части - три весовые функции.

Рис. 4. Весовые функции, соответствующие излучению лампы накаливания
Такое задание функций является дискретным, так как мы фактически задаем значения функции на ограниченном количестве текселей текстуры. Однако, в силу того, что к текстуре применяется фильтрация, значения цветов между соседними текселями будут проинтерполированы, что создаст ощущение непрерывности задания весовых функций.
Необходимость использования именно текстур в качестве способа передачи алгоритму информации исходит из того, что все вычисления, связанные с построением спектра, реализованы на пиксельных шейдерах, и текстуры являются единственным способом передачи в пиксельный шейдер информации такого рода.
В начале работы пиксельного шейдера ему на вход, помимо текстуры с весовыми функциями, поступает также текстура с панорамой, задающей распределенный источник освещения, вектор, показывающий, из какого направления в многогранник попадает свет, который виден в данном пикселе экрана, а так же длина волны (или набор таких длин, если мы рассматриваем целый участок спектра), для которой был рассчитан этот вектор.
Первое действие, которое осуществляется в шейдере - это выборка из панорамы (которая предварительно преобразуется в кубическую текстуру) цвета, соответствующего заданному вектору направления.
В самом шейдере создаются два массива - массив чисел типа float для хранения интенсивностей построенного спектра и массив элементов типа RGB для хранения взятых из текстуры значений весовых функций. Размеры этих массивов зависят от количества длин волн, на которых мы хотим построить спектр цвета (поскольку в начале было оговорено, что алгоритм должен строить дискретный спектр). Чем больше эти массивы, тем точнее нам удастся приблизить дискретный спектр к непрерывному спектру (это произойдет из-за увеличения частоты дискретизации). Однако на практике увеличение числа рассматриваемых длин волн влечет за собой сильное увеличение времени построения спектра, так как для каждого элемента массива, содержащего значения весовых функций, приходится использовать очень затратную по времени операцию - выборку цвета из текстуры. На практике используется двадцать либо восемьдесят длин волн.
В массив из элементов типа RGB предварительно загружаются соответствующие значения весовых функций. Затем в шейдере происходит построение спектра цвета, который является, фактически, суммой этих весовых функций, умноженных на коэффициенты, равные интенсивностям красного, зеленого и синего.
Если записать это в виде формулы, то выражение для i-го элемента массива будет выглядеть так:
Ii = R * FR (xi) + G * FG (xi) + B * FB (xi),
где Ii - i-ый элемент массива интенсивностей, xi - длина волны, соответствующая этому элементу, R, G и B - значения составляющих цвета данного пикселя, а FR, FG и FB - соответствующие им весовые функции.
Затем полученный спектр преобразуется в соответствии с данными о том, с какой длиной волны (или с какими длинами волн) в данный момент идет работа. Для этого обнуляются все значения интенсивностей, которые не входят в список текущих длин волн. Таким образом, ненулевым остается только тот участок, для которого был рассчитан вектор преломления.
Следующая задача - восстановить значения R, G и B, используя только полученную нами функцию спектра и весовые функции. Решение этой задачи - использование свертки. То есть, чтобы получить значение компоненты красного из спектра, необходимо произвести свертку по этому спектру, взяв в качестве ядра свертки весовую функцию красного цвета. Результатом свертки будет число, равное сумме по всем фракциям произведений интенсивности спектра для данной длины волны на значение весовой функции для данной длины волны.
Сама формула свертки для каналов R, G и B выглядит так:
R = ∑20i=0 (Ii * FR (xi)),
G = ∑20i=0 (Ii * FG (xi)),
B = ∑20i=0 (Ii * FB (xi)).
По этим формулам можно рассчитать результирующее значение цвета в данной точке экрана, и добавить его в буфер, в котором накапливается результат преломлений света для разных длин волн.
Альтернативным методом построения спектра цвета, заданного в пространстве RGB, является использование альтернативных цветовых пространств, построенных по другому принципу, нежели пространство RGB. Такие пространства (в данной статье используется пространство HSL - Hue, Saturation, Lightness) основываются на интуитивно понятном человеку способе описания цвета - они оперируют понятием основного оттенка, насыщенности цвета и яркости цвета.
Эти параметры очень удобно использовать при построении спектра, так как из них практически напрямую можно получить основные параметры функции, описывающей спектр. На рисунке 2 показано цветовое пространство HSL и то, как влияют параметры hue, saturation и lightness на получаемый цвет.

Рис. 5. Схематическое изображение цветового
пространства HSL
Основной идеей данного подхода к построению спектра является преобразование цвета каждого пикселя из пространства RGB в пространство HSL, и дальнейший анализ параметров hue, saturation и lightness для построения спектра цвета.
Как и в первом подходе, на вход шейдеру подается кубическая текстура, содержащая информацию об окружающей среде, а так же вектор, характеризующий направление, по которому лучи света из этого окружения попадают в многогранник, и длина волны (или набор длин волн), для которой был рассчитан данный вектор.
Первая операция, которую производит шейдер - это выборка по данному вектору направления цвета из кубической текстуры. Затем полученный цвет (в пространстве RGB) преобразуется к цветовому пространству HSL. Рассмотренный ранее вариант с преобразованием панорамы к HSL на этапе препроцессинга (один раз в самом начале работы программы) был отвергнут из-за того, что после применения фильтрации к текстуре, содержащей на самом деле значения HSL, а не RGB, на панораме появлялись артефакты, связанные с интерполяцией от пикселя к пикселю значения hue. Такая интерполяция не является корректной.
После преобразования к HSL в шейдере происходит построение спектра. Схематически значение параметров HSL в результирующем спектре отражено на рисунке 3.

Рис. 3. Влияние параметров HSL на формируемый спектр
Параметр hue фактически задает длину волны, на которой достигается максимум функции спектра. Параметр lightness задает среднее значение между максимальным и минимальным значениями спектра, а параметр saturation задает расстояние от среднего до максимального или минимального значения. При этом максимум спектра представляется в виде гауссиана, и гауссиан тем шире, чем ближе пик находится к красному цвету (так как в спектре диапазон красных цветов шире, чем диапазон зеленых, а диапазон зеленых шире, чем диапазон синих).
В шейдере для построения спектра создается массив из элементов типа float, и в этот массив заносятся значения интенсивностей, рассчитанных для соответствующих длин волн. В этот массив заносятся значения гауссиана с высотой, заданной параметрами saturation и lightness, либо минимальное значение функции спектра, если значение гауссиана меньше его.
Когда спектр построен, по тому же алгоритму, что и в первом подходе, происходит отбрасывание ненужных длин волн, и остается только та часть спектра, для которой было рассчитано преломление. После того, как спектр был изменен, необходимо преобразовать его к RGB. Это так же делается через HSL. Сперва спектр преобразуется к HSL, а затем HSL преобразуется к RGB.
Для преобразования спектра в HSL необходимо проанализировать его функцию и найти максимальное и минимальное значения, а так же длину волны, на которой достигается максимум. Из этой длины волны мы можем получить параметр hue, а параметры saturation и lightness получаются из максимального и минимального значений функции спектра.
После того, как найден цвет пикселя в пространстве HSL, этот цвет приводится к пространству RGB.
В данной статье была рассмотрена задача моделирования эффекта дисперсии света, а так же вариант ее решения с использованием спектрального представления цвета источника освещения, свет которого подвергается дисперсии. Были рассмотрены основные понятия спектра, света и цвета объекта, а так же предложены два подхода к построению спектра для цвета, представленного в виде компонент красного, зеленого и синего. Оба подхода были реализованы с использованием GPU применительно к задаче моделирования эффекта дисперсии света.
[1] http://www.realcolor.ru/lib/
[2] http://www.ixbt.com/digimage/spectr3.shtml
Комментарии
Статья не
Статья не понравилась. Вообще не очень понял идею, которую вкладывали авторы. Получился какойто обзорный тур. Никаких тебе практически полезных формул. Типа "кому надо - тот разберётся"? Но тогда зачем было нужно делать попытки углубиться в тему?? Понять авторов местами очень сложно (ну хотя, возможно, это только мои проблемы). Например я так и не понял как можно "рассчитывать преломления лучей только в вершинах объекта"... Откравенно говоря, создаётся ощущение, что либо авторам класть на читателя, либо они недостаточно компетентны, чтобы изложить материал понятным логичным языком с приведением математических выкладок и алгоритмов. В общем получилась какая то статься для развлечения. Грустно, товарищи...
Нууу......
А в Excel тоже самое можно сделать???
Будьте так любезны в табличке Excel выше изложенное отобразить в рабочем режиме.
Буду очень признателен.!!!
Заранее благодарен Александр.
Отправить комментарий