Shadow Mapping артефакты

8

Я играл с теневым отображением в OpenGL, используя текстуры глубины. Глубина текстуры хорошая, и я могу нанести ее на сцену, но у меня есть странные артефакты на задней стороне объекта:

Сфера отбрасывает тень, с артефактами сзади

У меня вопрос, что является причиной этого и как я могу это исправить?

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

in vec4 vShadowCoord;

uniform sampler2DShadow shadowMap;

out vec4 fragColor;

void main()
{
    float bias = 0.005;
    float visibility = 1.0;
    if (texture(shadowMap, vec3(vShadowCoord.xy, vShadowCoord.z / vShadowCoord.w)) < (vShadowCoord.z - bias) / vShadowCoord.w)
        visibility = 0.25;

    fragColor = vec4(visibility);
}

Изменить: По запросу минимальный рабочий пример скриншота, который использует только приведенный выше код (без цвета).

Та же сфера, минус цвет

Blarglenarf
источник
1
Можете ли вы подтвердить, что показанный код (без синего цвета) также вызывает артефакты? Если вы сузили код, то показ изображения из суженного кода поможет исключить любые ненужные детали и выявить проблему.
трихоплакс
Да, это так, я решил сделать скриншот с цветом, иначе это выглядит еще страшнее :)
Blarglenarf
Я могу это понять, но, поскольку вы обращаетесь за помощью к уродству, у вас больше шансов увидеть проблему, если вы включите снимок экрана, соответствующий коду.
Трихоплакс
1
Справедливо. Я добавил дополнительный скриншот.
Blarglenarf
Вы пытались немного поиграть с уклоном?
CIFZ

Ответы:

11

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

Есть три источника артефактов прыщей:

  • Первым источником прыщей является точность карты теней. Убедитесь, что ближняя и дальняя плоскости света, отбрасывающего тень, как можно плотнее. Все объекты перед ближней плоскостью могут быть блины, так как их точная глубина не важна.
  • Вторым источником прыщей является разрешение карты теней. Для направленного света вы должны делать каскадные карты теней, по крайней мере, с 3 каскадами 1024x1012 для ~ 100-200 м расстояния тени. Трудно покрыть одинаковое расстояние тени одной картой теней с равномерной проекцией.
  • Третий источник прыщей - это фильтр широкой карты теней, такой как PCF, поскольку использование единого значения сравнения глубины глубины в широком ядре недостаточно. Есть много способов исправить это, но ни один из них не является надежным.

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

Кроме того, помимо постоянного смещения глубины (которое вы используете в настоящее время), вы также должны добавить смещение глубины наклона и максимальное смещение глубины наклона. Оба могут быть реализованы либо как состояние рендеринга, либо как код шейдера во время рендеринга карты теней. Смещение глубины наклона - это просто магическое значение смещения, масштабированное точкой (нормальное, lightDir).

Есть несколько дополнительных интересных методов, и большинство из них реализованы в отличной демоверсии: Matt Pettineo - «Выборка теневых техник» .

  • Отбрасывание во время рендеринга карты теней (меняет угри на панорамирование Питера).
  • Нормальное смещение теневого отображения делает чудеса для проблем смещения, но требует, чтобы во время затенения были нормали вершин.
  • Методы, основанные на дисперсии (ESM, VSM, EVSM), полностью устраняют проблемы смещения, но имеют другие недостатки (слабые утечки и / или проблемы с производительностью).
Кшиштоф Наркович
источник