Ambient Occlusion¶. Ambient occlusion что это.

Затем создайте текстуру 4×4 и заполните таблицу векторов вращения. Обязательно используйте функцию повтора GL_REPEAT для привязки текстуры:

Ambient Occlusion Volumes для прожженных самоваров

В процессе поиска подходящего алгоритма освещения я наткнулся в интернете на новый алгоритм от NVIDIA под названием AOV (Ambient Occlusion Volumes). Темными осенними вечерами и с несколькими чашками горячего кофе в руке я решил изучить этот алгоритм, и эта статья — результат. Прежде чем начать, я хотел бы выразить свое удивление тем, что этот алгоритм, в отличие от известного всем нам SSAO, слишком непопулярен среди разработчиков игр. Содержание этой статьи будет состоять в основном из теории.

В июне 2010 года Морган МакГуайр, исследователь и разработчик в NVIDIA, разработал алгоритм освещения под названием Ambient Occlusion Volumes. При разработке этого алгоритма целью М. Макгуайра было достижение лучшей производительности и качества освещения. По словам разработчика, производительность алгоритма в значительной степени не зависит от сложности моделей, а качество освещения ни в чем не уступает трассировке лучей.

Немного об Ambient Occlusion

AO (Ambient Occlusion) — это алгоритм, аналогичный GI (Global Illumination). Он был разработан для затенения пространств, в которые лучи света фактически не попадают, поскольку эти пространства заслонены другими объектами, так что лучи света не могут попасть в это пространство. Сам алгоритм работает путем вычисления лучей, исходящих из точки, затенение которой контролируется, а затем проверки пересечения объекта с лучом. Если луч проходит беспрепятственно, точка освещается, в противном случае она затеняется.

Однако при расчете по этому алгоритму возникают некоторые трудности. Через некоторое время на смену старому алгоритму пришел SSAO (Screen Space Ambient Occlusion) от разработчиков из компании Crytek. Сам алгоритм работает по следующему принципу: определяется некая сфера и выбираются случайные точки в области этой сферы. Затем алгоритм сравнивает глубины этих точек (ранее записанные в буфер глубины) с точкой, для которой мы рассчитываем затенение. Если глубина последней больше глубины случайной точки, то она затеняется, в противном случае — освещается. Проводится несколько таких тестов, результаты которых затем суммируются, и рассчитывается коэффициент затенения. Это выглядит примерно так:

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

Прежде чем описать метод AOV, я хочу затронуть еще одну важную тему.

Radiosity

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

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

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

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

Коэффициент формы рассчитывается следующим образом:

Где θi,j — угол между нормалью плоскости и Ri,j, dA1,2 — дифференциальная площадь плоскости, Ri,j — вектор расстояния между dA1,2. В этом уравнении HID равен единице, когда dA1,2 видны друг другу, и нулю, когда наоборот.

В рамках этого метода были использованы два подхода: Полноматричная радиальность и прогрессивная уточняющая радиальность .

Full Matrix Radiosity

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

Таким образом, мы вычисляем интенсивность света, излучаемого плоскостью:

Где pi — коэффициент отражения плоскости i; Fij — коэффициент формы от плоскости i к плоскости j; Ii — радиоактивность плоскости i; Iei — интенсивность излучения плоскости i; N — количество плоскостей в среде.

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

Форм-фактор от патча к патчу рассчитывается следующим образом:

Где Ei — количество элементов в патче, Fej — коэффициент формы от элемента e к патчу j, Ai,e — площади патча и элемента.

Progressive Refinement Radiosity

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

Где Ii — уже рассчитанное значение коэффициента выбросов.

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

Corona Ambient Occlusion (AO) — параметры

Для Corona AO есть три входа, первые два управляют окклюзивным цветом и не окклюзивным цветом, который также может управляться текстурой. Третий вход управляет параметром расстояния Corona AO с помощью текстуры или растрового изображения, которое можно дополнительно контролировать параметром Max Distance. Низкие значения обеспечивают контактное затенение и улучшение возможных разрывов в сетке, а также более высокую производительность, в то время как более высокие значения охватывают большие поверхности/области, но также дают более медленную производительность.

Максимальные расстояния определяются как 1 см, 10 см, 100 см.

Режим расчета и распределение цвета

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

  • Режим «Снаружи» активирован по умолчанию и создает окклюзию при взгляде на объект со стороны (поверхность, на которую смотрит человек). Это сравнимо с освещением объекта окружающим светом.
  • Outside + Inside учитывает окклюзию, когда объект рассматривается изнутри (поверхность обращена назад).
  • Режим Outside + Inside учитывает оба режима одновременно и объединяет их.

Функции: Снаружи, оба (снаружи + внутри), внутри.

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

Распределение цвета: значение суммы равно 0,0, значение суммы равно 1,0.

Максимальные образцы

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

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

Направление луча: Значение суммы равно 1.0, Значение суммы равно 0.5, Значение суммы равно 0.0

Изменение направления также может использоваться отдельно для осей X, Y и Z. Это полезно при моделировании износа вследствие утечки веществ или жидкостей и других направленных эффектов.

Смещение осей в направлении: ось X — 10.0, ось Y — 10.0, ось Z — 10.0

Этот алгоритм был разработан для видеокарт AMD, которые гораздо менее популярны, чем видеокарты NVIDIA, согласно данным Steam Hardware & Software Survey.

$ambientocclusion

Ambient Occlusion — это метод затенения, который помогает добавить реалистичности моделям локальных отражений путем учета ослабления света, вызванного Clarify Occlusion. В отличие от локальных методов, таких как Phong Shading, Ambient Occlusion — это глобальный метод, то есть освещение в любой точке является функцией остальной геометрии в сцене. Однако это очень грубое приближение к полному глобальному освещению. Мягкий вид, достигаемый только за счет окклюзии, похож на то, как выглядит объект в пасмурный день. Она глобально поддерживается затенением EyeRefract. Когда модуль IFM загружен, параметр $ambientocclusion функционирует в других шейдерах, таких как VertexLitGeneric, как средство управления интенсивностью SSAO.

Сделать: Чем использование специальной текстуры окружения окклюзии отличается от простого встраивания ее в базовую текстуру (и, возможно, в маску голоса/глобуса)?

Ошибка: Когда $ambientocclusion применяется к прозрачным материалам (либо $translucent или $alphatest, либо ко всем материалам в модели, где был использован прозрачный материал без компиляции с $Opaque или $MostlyOpaque в QC-файле), $ambientocclusion также вызывает эффект, отображаемый материалом для всех объектов за материалом. (Проверено в Source Filmmaker)

Contents

Example VMT Syntax

Следующий пример взят из Left 4 Dead из материала модели, расположенного в L4D root/materials/models/survivors/teenangst/teenangst_eyeball_l.vmt.

VMT Parameters

$AmbientOcclusion Управляет количеством окклюзии окружающего пространства. (1 = полностью включен, 0 = полностью выключен).

Примечание: Используется для управления мощностью SSAO для моделей в Source Filmmaker.

$AmbientOcclColor «.n .n .n .n .n» Замените n на число для цвета (формат RGB) $AmbientOcclTexture «path/to/vtf» Имя файла текстуры окклюзии, которая будет использоваться.

Сделать: Как $ambientocclusiontexture вписывается во все это?

Наш последний шаг — создание функции разложения (g) путем наложения на многоугольник P ( AOp(n) ). После всех операций нам также необходимо применить так называемое смешивание.

Случайный поворот ядра выборки

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

Мы создаем матрицу 4×4 и заполняем ее случайными векторами вращения, ориентированными по нормали в касательном пространстве:

Поскольку ядро ориентировано вдоль положительной полуоси Z в касательном пространстве, мы оставляем z-компоненту равной нулю — это обеспечивает вращение только вокруг оси Z.

Затем создайте текстуру 4×4 и заполните таблицу векторов вращения. Обязательно используйте функцию повтора GL_REPEAT для привязки текстуры:

Что ж, теперь у нас есть все необходимые данные для прямой реализации алгоритма SSAO!

Шейдер SSAO

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

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

В целом, процесс рендеринга на этапе SSAO выглядит примерно так:

ShaderSSAO принимает на вход необходимые ему текстуры G-буфера, а также текстуру шума и ядро выборки:

Обратите внимание на переменную NoiseScale: наша маленькая текстура шума должна быть затенена на экране, но поскольку координаты текстуры TexCoords находятся в пределах 0. и 1. это не произойдет без нашего вмешательства. Для этого мы вычисляем множитель для текстурных координат, который представляет собой отношение между размером экрана и размером текстурного шума:

Поскольку при создании текстуры texNoise мы установили режим повтора GL_REPEAT, она будет многократно повторяться на поверхности экрана. Имея в руках randomVec, fragPos и normal, мы можем создать таблицу трансформации TBN от касательной к области просмотра:

Используя метод Грамма-Шмидта, мы создаем прямоугольный след, который случайным образом наклонен в каждом фрагменте на основе значения randomVec. Важный момент: поскольку в данном случае таблица TBN не должна быть выровнена точно по поверхности треугольника (как в параллаксном представлении), нам не нужны предварительно вычисленные данные для касательной и биссектрисы.

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

Это звучит запутанно, но давайте разберем все пошагово:

Здесь kernelSize и radius — переменные, которые управляют свойствами явления. В данном случае они равны 64 и 0,5 соответственно. На каждой итерации вектор выборки ядра переводится в пространство проекций. Затем мы добавляем значение положения фрагмента в окне проекции к полученному значению смещения образца в окне проекции. В то же время значение смещения умножается на переменную radius, которая управляет радиусом ядра выборки эффекта SSAO.

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

После преобразования в пространство клипа мы вручную выполняем перспективное деление, просто разделив компонент xyz на компонент w. Полученный вектор в нормализованных координатах устройства (NDC) переводится в диапазон значений от 0., 1., чтобы его можно было использовать в качестве координат текстуры:

Размытие фонового затенения

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

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

Шейдер просто переключается на тексели текстуры SSAO со смещением о т-2 до +2, что соответствует реальному размеру текстуры шума. Смещение соответствует точному размеру текселя: textureSize() используется для вычисления и возвращает vec2 с размером указанной текстуры. Поэтому шейдер просто усредняет результаты, хранящиеся в текстуре, в результате чего получается быстрое и довольно эффективное размытие:

Learn OpenGL. Урок 5.10 – Screen Space Ambient Occlusion - 13

Таким образом, у нас есть текстура с данными о фоновом затенении для каждого фрагмента на экране — все готово для финальной фазы смешивания изображений!

Оцените статью
club-cs.ru