stringtranslate.com

Объем тени

Пример трафаретного затенения Кармака в Doom 3

Объем тени — это метод, используемый в 3D-компьютерной графике для добавления теней к визуализированной сцене. Впервые он был предложен Фрэнком Кроу в 1977 году [1] как геометрия, описывающая трехмерную форму области, скрытой от источника света. Объем тени делит виртуальный мир на две части: области, которые находятся в тени, и области, которые не находятся в тени.

Реализация теневых объёмов с помощью трафаретного буфера обычно считается одной из наиболее практичных универсальных техник затенения в реальном времени для использования на современном оборудовании для 3D-графики [ требуется ссылка ] . Она была популяризирована видеоигрой Doom 3 , а конкретная вариация техники, используемая в этой игре, стала известна как «Обратная Кармака».

Объемы теней стали популярным инструментом для затенения в реальном времени, наряду с более почтенным картированием теней . Главное преимущество объемов теней заключается в том, что они точны до пикселя (хотя во многих реализациях есть небольшая проблема самозатенения вдоль края силуэта, см. конструкцию ниже), тогда как точность карты теней зависит от выделенной ей текстурной памяти, а также от угла, под которым отбрасываются тени (при некоторых углах точность карты теней неизбежно страдает). Однако этот метод требует создания геометрии теней, что может быть интенсивным для ЦП (в зависимости от реализации). Преимущество карт теней заключается в том, что он часто быстрее, поскольку полигоны объема теней часто очень велики с точки зрения экранного пространства и требуют много времени заполнения (особенно для выпуклых объектов), тогда как карты теней не имеют этого ограничения.

Строительство

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

Для полигональной модели объем обычно формируется путем классификации каждой грани в модели как обращенной к источнику света или обращенной от источника света. Набор всех ребер, которые соединяют обращенную к источнику света грань с отдалённой гранью, образуют силуэт относительно источника света. Ребра, образующие силуэт, выдавливаются от света для построения граней теневого объема. Этот объем должен простираться на весь диапазон видимой сцены; часто размеры теневого объема увеличиваются до бесконечности, чтобы достичь этого (см. оптимизацию ниже). Чтобы сформировать замкнутый объем, передний и задний конец этого выдавливания должны быть покрыты. Эти покрытия называются «крышками». В зависимости от метода, используемого для теневого объема, передний конец может быть покрыт самим объектом, а задний конец иногда может быть опущен (см. проход глубины ниже).

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

Основные этапы формирования теневого объема:

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

Реализации буфера трафарета

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

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

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

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

Глубина прохода

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

  1. Отключить запись в буферы глубины и цвета.
  2. Используйте отбраковку по задней грани .
  3. Установите операцию трафарета на увеличение при проходе глубины (учитывать только тени перед объектом).
  4. Визуализируйте теневые объемы (из-за отбраковки визуализируются только их передние грани).
  5. Используйте отбраковку по фронтальной поверхности.
  6. Установите операцию трафарета на уменьшение при проходе глубины.
  7. Визуализируйте теневые объемы (визуализируются только их задние поверхности).

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

Этот подход имеет проблемы, когда сам глаз находится внутри теневого объема (например, когда источник света движется позади объекта). С этой точки зрения глаз видит заднюю поверхность этого теневого объема прежде всего, и это добавляет смещение −1 ко всему буферу трафарета, эффективно инвертируя тени. Это можно исправить, добавив поверхность «cap» к передней части теневого объема, обращенной к глазу, например, на передней плоскости отсечения . Есть еще одна ситуация, когда глаз может находиться в тени объема, отбрасываемого объектом позади камеры, который также должен быть каким-то образом ограничен, чтобы предотвратить подобную проблему. В большинстве распространенных реализаций, поскольку правильное ограничение для прохода глубины может быть сложно осуществить, метод провала глубины (см. ниже) может быть лицензирован для этих особых ситуаций. В качестве альтернативы можно задать буферу трафарета смещение +1 для каждого теневого объема, внутри которого находится камера, хотя выполнение обнаружения может быть медленным.

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

Тестирование глубинного прохода также известно как тестирование z-прохода , поскольку буфер глубины часто называют z-буфером.

Глубина провалена

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

  1. Отключить запись в буферы глубины и цвета.
  2. Используйте отбраковку по фронтальной поверхности.
  3. Установите операцию трафарета на увеличение при неудачной попытке определения глубины (учитывать только тени позади объекта).
  4. Визуализируйте теневые объемы.
  5. Используйте отбраковку по задней грани.
  6. Установите операцию трафарета на уменьшение при сбое глубины.
  7. Визуализируйте теневые объемы.

Метод провала глубины имеет те же соображения относительно точности буфера трафарета, что и метод прохода глубины. Также, подобно проходу глубины, его иногда называют методом z-провала .

Уильям Билодо и Майкл Сонжи открыли эту технику в октябре 1998 года и представили её на конференции разработчиков Creativity, Creative Labs, в 1999 году. [2] Сим Дитрих представил эту технику на GDC в марте 1999 года и на Creativity в конце 1999 года. [3] [4] Несколько месяцев спустя Уильям Билодо и Майкл Сонжи в том же году подали заявку на патент США на эту технику под названием «Метод рендеринга теней с использованием теневого объёма и трафаретного буфера». [5] Джон Кармак из id Software независимо открыл этот алгоритм в 2000 году во время разработки Doom 3. [ 6]

Исключающее-или

Любой из вышеперечисленных типов может быть аппроксимирован с помощью вариации «исключающее или» , которая не обрабатывает должным образом пересекающиеся объемы теней, но экономит один проход рендеринга (если не время заполнения) и требует только 1-битный буфер трафарета. Следующие шаги предназначены для версии с проходом глубины:

  1. Отключить запись в буферы глубины и цвета.
  2. Установите операцию трафарета на XOR на проходе глубины (переворот на любой теневой поверхности).
  3. Визуализируйте теневые объемы.

Оптимизация

Смотрите также

Ссылки

  1. ^ Кроу, Франклин С.: «Теневые алгоритмы для компьютерной графики», Компьютерная графика (Труды SIGGRAPH '77) , т. 11, № 2, 242–248.
  2. ^ Йен, Хун (2002-12-03). "Теория трафаретных теневых объёмов". GameDev.net . Получено 2010-09-12 .
  3. ^ "Трафаретные тени запатентованы!? WTF! - GameDev.net". 2004-07-29 . Получено 2012-03-28 .
  4. ^ "Creative патентует обратную сторону Кармака". The Tech Report. 2004-07-29. Архивировано из оригинала 2010-01-31 . Получено 2010-09-12 .
  5. US 6384822, Билодо, Уильям и Сонжи, Майкл, «Метод рендеринга теней с использованием теневого объема и трафаретного буфера», опубликовано 07.05.2002, передано Creative Technology Ltd. 
  6. ^ Килгард, Марк; Джон Кармак. "Джон Кармак о теневых объемах..." Страница Practical and Robust Shadow Volumes на NVIDIA Developer Zone . archive.org: NVIDIA. Архивировано из оригинала 27 января 2009 г. Получено 18 октября 2012 г.
  7. ^ Лендьел, Эрик. "Advanced Stencil Shadow and Penumbral Wedge Rendering" (PDF) . Game Developers Conference 2005 . 2005 . Получено 18 октября 2012 .
  8. ^ "GPU Gems 3: Глава 11. Эффективные и надежные теневые объемы с использованием иерархического отсечения и геометрических шейдеров | NVIDIA Developer Zone". developer.nvidia.com . Архивировано из оригинала 16 мая 2011 г. . Получено 12 января 2022 г. .
  9. ^ Стич, Мартин; Карстен Вехтер; Александр Келлер (2007). "Глава 11 "Эффективные и надежные теневые объемы с использованием иерархического отсечения преград и геометрических шейдеров"". GPU Gems 3 . archive.org: nVidia / Addison-Wesley. Архивировано из оригинала 16 мая 2011 г. . Получено 18 октября 2012 г. .
  10. ^ Бреннан, Крис. "Выдавливание объёма тени с использованием вершинного шейдера" (PDF) . AMD . Получено 14.02.2018 .