Shadow Map

Xtreme3D v3

Shadow Map

Shadow Map | Теневая карта
Один из методов построения теней, заключающийся в использовании Z-буфера для определения попиксельно, находится ли заданная точка в тени. В основе метода теневых карт лежит идея о том, что освещенные точки - это те точки, которые "видны" источнику света. "Видимость" в данном случае означает, что данная точка успешно проходит тест глубины при рендеринге из положения источника света - то есть, не перекрывается другими объектами. Следовательно, все точки, которые "невидимы" из положения источника света, находятся в тени.
Метод работает в два прохода: сначала осуществляется рендеринг из положения источника света - значения глубины записываются в специальный буфер. Затем делается обычный рендеринг, во время которого полученный буфер используется для проверки, попадает ли тот или иной пиксель в тень (эта проверка осуществляется во фрагментном шейдере).
Обычно теневые карты используются с направленным источником света (таким, как солнце) - соответственно, для рендеринга буфера глубины используется ортогональная проекция. Однако метод совместим и с точечными источниками света - для этого вместо одного буфера глубины осуществляется рендеринг кубической карты (6 буферов глубины по сторонам куба, окружающего источник света) с перспективной проекцией. При большом количестве источников света эта техника сильно повышает нагрузку на GPU, поэтому на практике тени обычно рендерятся только для нескольких самых важных источников света, в зависимости от характера изображаемой сцены.
Теневые карты очень эффективны - они работают намного быстрее, чем shadow volume. Но они имеют и недостаток - сильный алиасинг: иными словами, если не использовать гигантский буфер глубины, то тени получаются сильно пикселизированные. Этот артефакт обычно устраняют фильтрацией (размытием) выборки из буфера глубины ядром 3х3 или 5x5 - в результате чего получаются мягкие тени без пикселизации. Данное расширение метода теневых карт получило название PCF (Percentage Closer Filtering).
Классические теневые карты имеют ограниченную площадь покрытия. То есть, невозможно сделать так, чтобы все видимые объекты сцены отбрасывали качественную тень - при увеличении размера проекции уменьшается детализация и, соответственно, повышается алиасинг. При уменьшении, соответственно, удаленные объекты выпадают из "поля зрения" источника света и не отбрасывают тени Самая популярная техника, решающая эту проблему - каскадные теневые карты (Cascaded Shadow Maps, CSM). Она заключается в рендеринге нескольких теневых буферов вместо одного, с разными размерами проекции - они называются теневыми каскадами. Обычно используется 3-4 каскада. Затем во фрагментном шейдере нужный буфер выбирается в зависимости от координат текущего пикселя - обычно выборки интерполируют между соседними каскадами, чтобы получить плавные переходы. В результате теневая карта охватывает практически всю видимую сцену: получаются качественные тени вблизи от камеры и пикселизированные - вдалеке. Пикселизация далеких теней практически не заметна зрителю - он видит лишь, что далекие объекты тоже отбрасывают тени, и этого достаточно.
Основная сложность метода CSM заключается в эффективном расположении каскадов относительно пирамиды видимости. Самое простое решение - выровнять их по центру в точке положения камеры, но в этом случае эффективная площадь каскадов будет составлять лишь около трети их реальной площади, поскольку в каждый момент времени зритель видит не весь каскад, а только его часть, соответствующую горизонтальному углу зрения камеры. В современных реализациях CSM позиции и размеры проекций каскадов обычно подбирают так, чтобы они полностью попадали внутрь пирамиды видимости и покрывали ее как можно более плотно.
Существует также популярное расширение метода теневых карт - Variance Shadow Map (VSM). В нем буфер глубины хранит два значения для каждого пикселя - собственно глубину и ее квадрат, при этом используется буфер значений с плавающей запятой. Для получения выборки из такого буфера используется неравенство Чебышева. Преимущество метода заключается в том, что VSM-буфер можно предварительно отфильтровать один раз, и затем использовать для дальнейшего рендеринга без PCF, значительно повышая тем самым производительность. Однако VSM привносит свои артефакты, самый серьезный из которых - так называемый light-bleeding, когда в зоне затенения появляются светлые пятна. Есть несколько способов исправления данной проблемы, но они либо требуют больше памяти, либо делают тени не такими мягкими, как хотелось бы.

См. также Shadow Volume, Z-Buffer.