Статья подготовлена при содействии РФФИ по проекту 12-01-31027
Кэш излучения (irradiance cache) – это не способ вычисления интеграла освещенности. Это лишь способ ускорения вычисления этого интеграла на множестве точек. Основная идея заключается в том, что вторичное освещение разделяется на две компоненты – низкочастотную (диффузную) и высокочастотную (отражающую). Низкочастотная компонента на изображении меняется плавно, поэтому ее можно вычислить каким-либо из методов лишь в очень небольшом числе точек, а в остальных интерполировать [1]. Рисунки 1 и 2 демонстрируют пример использования кэша освещенности. Высокочастотная компонента обычно обусловлена резкими максимумами BRDF, поэтому она может быть вычислена сэмплированием с помощью относительно небольшого числа (что конечно не всегда так) лучей только в максимумах BRDF (importance sampling).
Рисунок 1. Изображение со вторичным освещением. На скриншоте заметны характерные для иррадианс-кэша артефакты интерполяции.
Рисунок 2. То же самое изображение со вторичным освещением. Cиним цветом обозначены точки, в которых вторичное освещение было рассчитано.
Различают кэш излучения в трехмерном пространстве сцены (world space) и кэш в экранной плоскости (screen space). Реализация кэша в экранной плоскости проще и эффективнее т.к. втоиричное освещение вычисляется целиком для пиксела. Интерполяция также производится в пространстве экрана. Однако, кэш излучения в пространстве экрана может быть использован по понятным причинам только для первично видимых поверхностей.
Как правило, кэш излучения вычисляется на лету. Каждый раз при вычислении вторичного диффузного освещения делается попытка выборки из кэша. Если значение может быть выбрано так, что ошибка меньше допустимой величины, оно получается как результат интерполяции ближайших точек кэша. Если ошибка больше допустимой величины, значение честно вычисляется с помощью трассировки лучей по всем направлениям (или финального сбора из фотонной карты) и полученная точка сохраняется в КЭШе [3].
Алгоритм кэширования освещенности выглядит следующи образом (ленивая схема вычислений):
function IrradianceCaching(p, n) is
begin
if (одна или более точек могут быть использованы для интерполяции в точке p) then
return интерполированное значение освещения;
else
Вычислить освещенностьв точке p честно, считая интеграл по полусфере вокруг нормали n;
Cохранить вычисленное освещение в кэше;
return значение освещенности в точке p;
end if;
end IrradianceCaching;
Алгоритм кэширования вторичного освещения содержит 2 узких места - расчет собственно вторичного освещения в точках кэша и финальный алгоритм интерполяции освещения во всех остальных точках. Оба узких места могут быть существенно ускорены на графических процессорах.
Вычисление вторичного освещения
Стандартным способом вычисления вторичного освещения в точках кэша является монте-карло трассировка лучей или финальный сбор в сочетании с фотонными картами. Однако в [3] предлагается вычислять вторичную освещенность в точках с помощью растеризации в кубическую текстурную карту. Данная операция может производиться очень быстро т.к. имеет аппаратную поддержку даже в довольно старых видеокартах (обычно используется для симуляции отражений на объектах).
Рисунок 3. Пример кубической текстурной карты.
Несмотря на преимущество по скорости, недостаток этого алгоритма в том, что он не может учитывать зеркальных отскоков света и может быть в ряде случаев медленнее трассировки лучей на больших сценах. Причина заключается в том, что при растеризации вся геометрия обрабатывается графическим процессором. Она проходить весь графический конвейер: преобразование вершин, возможно тесселяцию и геометрические преобразования над примитивами, интерполяция атрибутов вершин и вычисление значений освещенности в пикселах.
Допустим, геометрия – это некоторое здание, разделенное на комнаты. Всё здание содержит 2 миллиона вершин. Пусть виртуальный наблюдатель находится в одной из комнат. Несмотря на то, что комната может составлять 10-20% всей геометрии, при вычислении освещения в точке каждый раз потребуется пропускать через графический конвейер все 2 миллиона вершин. Тот факт что 90% сцены может быть закрыто стеной или каким-то близкорасположенным объектом никак не используется. В то же время, трассировка лучей учитывает такие вещи. Так как трассировка лучей использует бинарный поиск, скорость вычисления освещенности будет зависеть сублинейно (обычно логарифмически) от размера входных данных, а не линейно, как в случае растеризации.
Радиус валидности точки
Одним весьма неочевидным моментом при реализации кэша освещенности является вычисление радиуса валидности точки кэша. Подразумевается, что каждая точка иррадианс кэша может быть использована для интерполяции только в некоторой определенной области. Есть по крайней мере 2 причины, по которым радиус валидности точки нужно ограничивать. Первая причина - стремление избежать артефактов. Вторая - скорость выборки из кэша. Если слишком много точек будут затрагиваться при каждой выборке, интерполяция станет медленной.
Обычно область валидности ограничивают сферой с центром в точке иррадианс кэша и некоторым радиусом, называемым радиусом валидности (хотя есть работы где для этой цели используются эллипсоиды). В [3] для вычислениия радиуса валидности было использовано 5 различных эвристик. Каждая из них имеет недостатки, но все вместе они дают удовлетворительный результат.
Из самых простых - используется так называемая эвристика "Sphere Split Approximation". Эта эвристика вычисляется исключительно из геометрических соображений. При оценке освещенности, для всех трассируемых лучей запоминается расстояние, на котором они ударились о поверхность и из этих расстояний берется наименьшее. Однако при использовании этого подхода, в процессе нахождения минимума важно не принимать в расчет лучи, имеющие маленький угол с тангент-плоскостью (рис. 5).
Рисунок 5. Точки расположенные на поверхностях.
В противном случае на вогнутых криволинейных поверхностях радиус валидности точки всегда будет равным нулю. Альтернативный метод реализации эвристики "Sphere Split Approximation" заключается в том, чтобы не искать минимальное расстояние а вычислить так называемое "среднее грамоническое расстояние" (рис. 6).
Рисунок 6. Среднее гармоническое расстояние.
MN - количество лучей используемых при сэмплировалнии полусферы. r[j,k] - расстояние от точки кэша до поверхности в которую ударился соответствующий луч. Индексы j и k используются для того чтобы подчеркнуть двумерных характер сэмплирования по полусфере. Формула для среднего гармонического расстояния (рис. 6) характерна тем, что чем меньше расстояние r[i,j] тем больше оно влияет на финальный результат.
Также размер радиуса валидности рекомендуется ограничивать снизу размером 2-4 пикселей (спроецированных на сцену в world space) и сверху размером 20-64 пикселей. Конкретные числа могут варьироваться.
Структуры данных и интерполяция
Для хранения точек иррадианс кэша обычно используется специальное октодерево со множественными ссылками (multiple reference octree) [3]. Точки кэша излучения в таком октодереве хранятся только в листьях, но каждый лист хранит список всех сфер, которые он пересекает. Основной плюс такого октодерева в том, что возможно осуществить простой нерекурсивный поиск от корня к листу с последующим перебором всего лишь нескольких точек ирраианс кэша.
Рисунок 7. Multiple reference octree.
Очевидно, что для поиска ближайших точек можно использовать любую другую ускоряющую структуру, например kd-дерево.
Формула
В заданной точке трехмерного пространства, при помощи поиска в октодереве мы должны найти все сферы (с центрами в точках иррадианс кэша и радиусами равными радиусам валидности записей кэша), которые пересекают данную точку.
Затем, пройдя в цикле по всем точкам, нужно собрать с них освещение. Одна из практичных формул была предложена Tabellion-ом и Lamorlette в [2] и представлена ниже в виде алгоритма. Переменные lookPos и lookNorm - это позиция и нормаль в той точке, в которой мы хотим сделать выборку из иррадианс кэша. pointPos и pointNorm соответственно - позиция и нормаль для i-ой записи иррадианс кэша, validityRadius - радиус валидности этой записи.
// Tabellion and Lamorlette [2] use a modified version of the weigh function
//
float perr = length(lookPos-pointPos)/validityRadius; // perr = ||p1-p2||/(Ri)
float nerr = 9.0124*sqrtf(1.f - dot(lookNorm, pointNorm)); // nerr = (1-sqrt(n1*n2))/(sqrt(1-cos(10))
float err = fmaxf(perr, nerr);
if (err < 1.0f)
{
float wt = (1.0f - err);
summWt += wt;
E += wt*color;
}
После чего полученную освещенность E нужно поделить на сумму весов summWt, чтобы получить правильное значение, учтя вклады от каждой точки, соответственно их весам.
Irradiance Cache на GPU
В [3] предлагается также реализовать интерполяцию при помощи растеризации сплатов – дисков или сфер некоторой небольшой величины.
Рисунок 8. Интерполяция освещения при помощи растеризации сплатов.
Недостаток этого метода в том, что он может быть применен только при вычислении освещения на первично-видимых поверхностях. Преимущество – высокая скорость за счет аппаратной поддержки растеризации и альфа-блендинга.
Резюме
Кэширование вторичного освещения - крайне эффективная техника ускорения вычисления глобально освещения, позволяющая снизитиь количество необходимых вычислений практически на 3 порядка (для больших разрешений). Допустим имеется изображение размером 1024x1024 пиксела. Если вычислять вторичное освещение в каждой точке, то потребуется суммарно протрассировать порядка 109 лучей только для вычисления вторичной освещенности. Используя кэш излучения количество точек, в которых необходимо вычислить вторичную освещенность сокращается с миллиона до нескольких тысяч. Соответственно, число лучей падает с 109 до 106 - 107.
Ссылки
[1] Pharr, M. and Humphreys, G. 2004 Physically Based Rendering: from Theory to Implementation. Morgan Kaufmann Publishers Inc.
[2] Eric Tabellion and Arnauld Lamorlette. An approximate global illumination system for computer-generated films. In Proceedings of SIGGRAPH, 2004.
[3] Křivánek J., Gautron P. Practical Global Illumination With Irradiance Caching. Synthesis lectures on computer graphics and animation. Morgan & Claypool Publishers, 2009.
|