Хабрахабр

[Перевод] Reflective Shadow Maps: Часть 1

image

Представляю вашему вниманию перевод статьи «Reflective Shadow Maps» автора Eric Polman. Привет, Хабр!

Алгоритм учитывает свет, рассеянный после первого попадания на поверхность (diffuse). Reflective Shadow Maps (RSM) (отражающие карты теней) ― это алгоритм, расширяющий “простые” shadow map. В данной статье я разберу алгоритм из официальной статьи, чтобы объяснить его по-человечески. Это означает, что кроме прямого освещения, вы получаете непрямое освещение. Я также кратко расскажу о shadow mapping.

Shadow mapping

Shadow Mapping (SM) ― это алгоритм генерации теней. Согласно алгоритму, мы храним расстояние от источника освещения до объекта в карте глубины. На рисунке 1 показан пример карты глубины. В ней хранится расстояние (глубина) для каждого пикселя.

Чем ближе пиксель, тем он ярче. image
Рисунок 1: Данное изображение демонстрирует карту глубины.

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

image
Рисунок 2: Расстояние от источника освещения до пикселя в тени больше, чем расстояние, хранимое в карте теней.

Reflective Shadow Mapping

Теперь, когда вы поняли основную концепцию Shadow Mapping, мы продолжим с Reflective Shadow Mapping (RSM). Данный алгоритм расширяет функциональность “простых” shadow maps. Помимо данных о глубине, вы также храните world-space (в мировой системе координат) позицию, world-space нормали и flux (световой поток). Я объясню, зачем вам нужны эти данные.

Данные

World-space позиция

В RSM world-space позицию нужно хранить для того, чтобы определить расстояние между пикселями. Это полезно для расчета затухания света. Свет затухает (становится менее концентрированным), когда проходит определенное расстояние. Расстояние между двумя точками в пространстве используется для расчета интенсивности освещения.

Нормали

Нормали (world-space) используются для расчета отражения света от поверхности. В случае RSM они также используются для определения, является ли данный пиксель источником освещения для другого пикселя. Если две нормали практически совпадают, они не будут давать друг другу много отраженного света.

Luminous Flux (световой поток)

Flux ― это световая интенсивность источника освещения. Ее единицей измерения является люмен, термин, который в настоящее время вы можете увидеть на упаковках лампочек. Алгоритм сохраняет flux для каждого пикселя, пока рисуется карта теней. Flux рассчитывается умножением интенсивности света на коэффициент отражения. Для directional light (направленный источник освещения) вы получите равномерно освещенное изображение. Для spot light вы также учитываете угол падения. Затухание и принимающий косинус (между нормалью и light вектором) не берутся в расчет, так как это учитывается, когда вы считаете непрямое освещение. В данной статье не будут рассматриваться подробности. На рисунке 3 изображены текстуры для spot light из официальной статьи.

Слева направо: карта глубины, world-space позиции, world-space нормали, flux. image
Рисунок 3: Изображены четыре карты, содержащиеся в RSM.

Применение данных

Теперь, когда данные сгенерированы (теоретически), пришло время применить их к финальному изображению. Когда вы отрисовываете финальное изображение, вы рассчитываете влияние каждого источника освещения на каждый пиксель. Помимо простого освещения пикселей, используя источники освещения, теперь вы также используете Reflective Shadow Map.

Вы проверяете, не попадает ли свет из текселя в RSM на пиксель, который вы рассчитываете. Наивным подходом к расчету вклада освещения является проход по всем текселям в RSM. Вы рассчитываете направление от world-space позиции в текселе RSM до пикселя. Это делается, используя world-space позиции и world-space нормали. Любое положительное значение означает, что пиксель должен быть освещен с помощью flux, который храниться в RSM. Затем вы сравниваете его с нормалью, используя скалярное произведение векторов. Рисунок 4 демонстрирует данный алгоритм.

image
Рисунок 4: Демонстрация вклада непрямого освещения, основываясь на world-space позициях и нормалях.

Вместо этого лучше всего сделать определенное количество сэмплов из карты. Shadow mapsRSMs) по своей природе большие (512x512=262144 пикселя), так что проверка каждого текселя далека от оптимальности. Недостаточное количество сэмплов может дать такие артефакты, как полосы или мерцания. Количество сэмплов зависит от того, насколько мощное у вас железо.

Метод сэмплинга, который собирает большинство сэмплов рядом с координатами пикселя, даст лучшие результаты. Тексели, которые в наибольшей степени будут влиять на результат освещения, находятся ближе всего к рассчитываемому пикселю. В официальной статье описывается, что плотность сэмплинга уменьшается с квадратом расстояния от пикселя, который мы рассчитываем. Данный метод называется “importance sampling” (сэмплинг по важности).

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

Больше сэмплов берется из центра и сэмплы масштабируются коэффициентом, основанным на их расстоянии от центральной точки. image
Рисунок 5: Importance sampling. Заимствовано из статьи о RSM.

Дополнительно

А координаты сэнмплинга относительно (s,t) рассчитываются заранее и передаются массивом в шейдер.
В качестве точки (s,t) берется проекция текущего пикселя на shadow map.

К сэмплу вы должны относиться как к точечному источнику освещения. Вы используйте значение flux в качестве light color и только те источники освещения, которые находятся напротив пикселя.

Заключение

В официальной статье более подробно рассказывается о других оптимизациях этого алгоритма, но я остановлюсь на этом. В разделе Screen-Space Interpolation описывается, как вы можете увеличить производительность, но я думаю для начала importance sampling будет достаточно.

Во второй части представлена реализация RSM.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть