Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Каскадные карты тени (CSM) — лучший способ борьбы с одной из наиболее распространенных ошибок с тенью: псевдоним перспективы. Эта техническая статья, предполагающая, что читатель знаком с теневым сопоставлением, решает тему CSM. В частности, это:
- объясняет сложность CSM;
- содержит подробные сведения о возможных вариантах алгоритмов CSM;
- описывает два наиболее распространенных метода фильтрации— процент ближе к фильтрации (PCF) и фильтрацию с теневыми картами дисперсии (VSMs);
- определяет и устраняет некоторые распространенные ошибки, связанные с добавлением фильтрации в CSMs; и
- показывает, как сопоставить csms с Direct3D 10 с оборудованием Direct3D 11.
Код, используемый в этой статье, можно найти в пакете SDK для DirectX в примерах CascadedShadowMaps11 и VarianceShadows11. Эта статья будет наиболее полезной после реализации методов, описанных в технической статье, Распространенные методы для улучшения карт глубины тениреализованы.
Каскадные теневые карты и псевдоним перспективы
Псевдоним перспективы в теневой карте является одной из самых сложных проблем для преодоления. В технической статье описаны распространенные методы улучшения теневых карт глубины, а также описаны некоторые подходы к устранению проблемы. На практике csms, как правило, является лучшим решением и часто используется в современных играх.
Основная концепция CSM легко понять. Для различных областей камеры frustum требуются теневые карты с различными разрешениями. Объекты, ближайшие к глазу, требуют более высокого разрешения, чем более удаленные объекты. На самом деле, когда глаз движется очень близко к геометрии, пиксели, ближайшие к глазу, могут требовать так много разрешения, что даже 4096 × 4096 теневой карты недостаточно.
Основная идея CSMs заключается в секционирование frustum на несколько frusta. Отрисовка теневой карты для каждой подфрустумы; шейдер пикселей затем примеры из карты, которая наиболее тесно соответствует требуемому разрешению (рис. 2).
Рис. 1. Покрытие теневой карты
На рисунке 1 показано качество (слева направо) от самого высокого до нижнего. Ряд сетки, представляющих теневые карты с представлением frustum (инвертированного конуса в красном) показывает, как покрытие пикселей влияет на различные карты теневого разрешения. Тени имеют наибольшее качество (белые пиксели), если в теневой карте есть пиксели сопоставления 1:1 в светлом пространстве с текселями. Псевдоним перспективы происходит в виде больших блочных карт текстур (левое изображение), когда слишком много пикселей сопоставляется с тем же теневым тексельом. Если теневая карта слишком велика, она находится под выборкой. В этом случае тексели пропускаются, отображаются мерцающие артефакты, а также влияет производительность.
Рис. 2. Качество тени CSM
На рисунке 2 показаны вырезки из раздела высокого качества на каждой теневой карте на рис. 1. Теневая карта с наиболее близко расположенными пикселями (в вершине) ближайшим глазом. Технически это карты с одинаковым размером, с белым и серым, используемым для примера успеха каскадной теневой карты. Белый является идеальным, потому что он показывает хорошее покрытие — соотношение 1:1 для пикселей пространства глаз и теневой карты тексели.
ДЛЯ CSM требуются следующие шаги для каждого кадра.
Секционирование frustum в subfrusta.
Вычислите орографическую проекцию для каждой субфрустумы.
Отрисовка теневой карты для каждой подфрустной.
Отрисовка сцены.
Привязка теневых карт и отрисовка.
Шейдер вершин выполняет следующие действия:
- Вычисляет координаты текстуры для каждой светлой подфрумы (если нужная координата текстуры не вычисляется в шейдере пикселей).
- Преобразует и зажигает вершину и т. д.
Шейдер пикселей выполняет следующие действия:
- Определяет правильную схему тени.
- При необходимости преобразует координаты текстуры.
- Примеры каскада.
- Зажигает пиксель.
Секционирование Frustum
Секционирование frustum — это действие создания субфрусты. Один из способов разделения frustum заключается в вычислении интервалов от нуля до ста процентов в направлении Z. Каждый интервал затем представляет близнюю плоскость и дальнюю плоскость в процентах от оси Z.
Рис. 3. Просмотр frustums секционированных произвольно
На практике перерасчет разбиения фреймов на кадр вызывает теневые края. Общепринятая практика заключается в использовании статического набора каскадных интервалов для каждого сценария. В этом сценарии интервал по оси Z используется для описания подфрустум, который возникает при секционации frustum. Определение правильных интервалов размера для данной сцены зависит от нескольких факторов.
Ориентация геометрии сцены
В отношении геометрии сцены ориентация камеры влияет на выбор каскадного интервала. Например, камера очень близка к земле, например земляная камера в футбольной игре, имеет другой статический набор каскадных интервалов, чем камера в небе.
На рисунке 4 показаны различные камеры и соответствующие секции. Когда Z-диапазон сцены очень большой, требуются более разделенные плоскости. Например, если глаз находится недалеко от плоскости земли, но удаленные объекты по-прежнему видны, может потребоваться несколько каскадов. Деление frustum таким образом, чтобы больше разбиений находятся рядом с глазом (где псевдоним перспективы меняется самым быстрым) также ценен. Если большая часть геометрии сжимается в небольшой раздел (например, накладное представление или симулятор полета) представления frustum, требуется меньше каскадов.
Рис. 4. Для разных конфигураций требуется разбиение frustum
(Слева) Если геометрия имеет высокий динамический диапазон в Z, требуется множество каскадов. (Центр) Если геометрия имеет низкий динамический диапазон в Z, мало преимуществ от нескольких frustums. (Справа) Требуется только три раздела, если динамический диапазон является средним.
Ориентация света и камеры
Матрица проекции каждого каскада тесно вписывается в соответствующую подфрустум. В конфигурациях, где камера просмотра и световые направления являются ортогональными, каскады могут быть тесно связаны с небольшим перекрытием. Перекрытие становится больше, так как свет и камера просмотра перемещается в параллельное выравнивание (рис. 5). Когда свет и камера просмотра почти параллельны, он называется "дуэтлинг frusta", и является очень трудным сценарием для большинства теневых алгоритмов. Это не редкость, чтобы ограничить свет и камеру, чтобы этот сценарий не происходил. Однако CSMS выполняют гораздо лучше, чем многие другие алгоритмы в этом сценарии.
Рис. 5. Каскадный перекрытия увеличивается, так как направление света становится параллельным с направлением камеры
Многие реализации CSM используют frusta фиксированного размера. Шейдер пикселей может использовать глубину Z для индексирования в массив каскадов, когда frustum разделен на интервалы фиксированного размера.
Вычисление привязки View-Frustum
После выбора интервалов frustum создается подфруста с помощью одного из двух: подходит для сцены и подходит для каскада.
Подходит для сцены
Все frusta можно создать с одной и той же близкой плоскости. Это заставляет каскады перекрываться. Пример CascadedShadowMaps11 вызывает этот метод, подходящий для сцены.
Подход к каскаду
Кроме того, frusta можно создать с фактическим интервалом секционирования, используемым как ближайшие и дальние плоскости. Это приводит к более жесткой посадке, но дегенерирует, чтобы поместиться на сцену в случае дуэта frusta. Примеры CascadedShadowMaps11 называют этот метод каскадным.
Эти два метода показаны на рис. 6. Подходит для каскадных отходов меньше разрешения. Проблема с каскадом заключается в том, что орографическая проекция растет и сжимается на основе ориентации представления frustum. Подходящий для сцены метод помещает орографическую проекцию на максимальный размер представления frustum, удаляя артефакты, которые появляются при перемещении камеры просмотра. распространенные методы улучшения карт глубины тени устраняет артефакты, которые отображаются при перемещении света в разделе "Перемещение света в добавочных размерах текселя".
Рис. 6. Подходит для сцены и подходит для каскада
Отрисовка теневой карты
Пример CascadedShadowMaps11 отрисовывает теневые карты в один большой буфер. Это связано с тем, что PCF в массивах текстур является функцией Direct3D 10.1. Для каждого каскада создается окно просмотра, охватывающее раздел буфера глубины, соответствующий этому каскаду. Шейдер пикселей null привязан, так как требуется только глубина. Наконец, для каждого каскада задана правильная матрица представлений, так как карты глубины отрисовываются одновременно в основной буфер тени.
Отрисовка сцены
Буфер, содержащий тени, теперь привязан к шейдеру пикселей. Существует два метода выбора каскада, реализованного в примере CascadedShadowMaps11. Эти два метода объясняются кодом шейдера.
Interval-Based каскадный выбор
Рис. 7. Каскадный выбор на основе интервала
На основе интервала выбор (рис. 7) вершинный шейдер вычисляет положение в мировом пространстве вершины.
Output.vDepth = mul( Input.vPosition, m_mWorldView ).z;
Шейдер пикселей получает интерполированную глубину.
fCurrentPixelDepth = Input.vDepth;
Каскадный выбор на основе интервала использует векторное сравнение и пунктирное произведение, чтобы определить правильный cacade. CASCADE_COUNT_FLAG указывает количество каскадов. M_fCascadeFrustumsEyeSpaceDepths_data ограничивает секции представления frustum. После сравнения fComparison содержит значение 1, где текущий пиксель больше барьера, а значение 0, если текущий каскад меньше. Точка продукта суммирует эти значения в индекс массива.
float4 vCurrentPixelDepth = Input.vDepth;
float4 fComparison = ( vCurrentPixelDepth > m_fCascadeFrustumsEyeSpaceDepths_data[0]);
float fIndex = dot(
float4( CASCADE_COUNT_FLAG > 0,
CASCADE_COUNT_FLAG > 1,
CASCADE_COUNT_FLAG > 2,
CASCADE_COUNT_FLAG > 3)
, fComparison );
fIndex = min( fIndex, CASCADE_COUNT_FLAG );
iCurrentCascadeIndex = (int)fIndex;
После выбора каскада координата текстуры должна быть преобразована в правильный каскад.
vShadowTexCoord = mul( InterpolatedPosition, m_mShadow[iCascadeIndex] );
Затем эта координата текстуры используется для выборки текстуры с координатами X и координатами Y. Координата Z используется для окончательного сравнения глубины.
Map-Based каскадный выбор
Выбор на основе карты (рис. 8) проверяется на четырех сторонах каскадов, чтобы найти самую жесткую карту, которая охватывает конкретный пиксель. Вместо вычисления позиции в мировом пространстве вершины шейдер вычисляет положение пространства представления для каждого каскада. Шейдер пикселей выполняет итерацию каскадов, чтобы масштабировать и переместить координаты текстуры, чтобы индексировать текущий каскад. Затем координата текстуры проверяется по границам текстуры. Если значения координат текстуры X и Y попадают внутри каскада, они используются для выборки текстуры. Координата Z используется для окончательного сравнения глубины.
Рис. 8. Каскадный выбор на основе карты
Interval-Based выбор и выбор Map-Based
Выбор на основе интервала немного быстрее, чем выбор на основе карты, так как каскадный выбор можно сделать напрямую. Выбор на основе карты должен пересекаться с координатами текстуры с каскадными границами.
Выбор на основе карты использует каскад более эффективно, если теневые карты не выравниваются идеально (см. рис. 8).
Сочетание между каскадами
VSMs (рассмотренные далее в этой статье) и методы фильтрации, такие как PCF, можно использовать с CSM с низким разрешением для создания мягких теней. К сожалению, это приводит к видимому шву (рис. 9) между каскадным слоями, так как разрешение не соответствует. Решение заключается в создании полосы между теневыми картами, где выполняется теневой тест для обоих каскадов. Затем шейдер линейно интерполирует между двумя значениями на основе расположения пикселя в полосе смешения. Примеры CascadedShadowMaps11 и VarianceShadows11 предоставляют ползунок ГРАФИЧЕСКОго интерфейса, который можно использовать для увеличения и уменьшения этой полосы размытия. Шейдер выполняет динамическую ветвь, чтобы подавляющее большинство пикселей только считывалось из текущего каскада.
Рис. 9. Каскадные швы
(Слева) Видимый шов можно увидеть, где каскады перекрываются. (Справа) Когда каскады смешиваются между, нет швов.
Фильтрация теневых карт
PCF
Фильтрация обычных теневых карт не создает мягкие, размытые тени. Фильтрующее оборудование размыто значения глубины, а затем сравнивает эти размытые значения с световым тексельом пространства. Жесткое крае, полученное из теста прохождения или сбоя, по-прежнему существует. Размытие теневых карт служит только для ошибочного перемещения жесткого края. PCF обеспечивает фильтрацию на теневых картах. Общая идея PCF заключается в вычислении процента пикселя в тени на основе количества подсамплесов, которые передают тест глубины по общему количеству подсемпелей.
Оборудование Direct3D 10 и Direct3D 11 может выполнять PCF. Входные данные для примера PCF состоят из координат текстуры и значения глубины сравнения. Для простоты PCF описывается с помощью фильтра с четырьмя касаниями. Пример текстуры считывает текстуру четыре раза, как и стандартный фильтр. Однако возвращаемый результат — это процент пикселей, которые прошли тест глубины. На рисунке 10 показано, как пиксель, который проходит один из четырех тестов глубины, составляет 25 процентов в тени. Фактическое возвращаемое значение представляет собой линейную интерполяцию на основе координат подтекселя текстуры для получения гладкого градиента. Без этой линейной интерполяции четыре касания PCF смогут возвращать только пять значений: { 0.0, 0.25, 0.5, 0.75, 1.0 }.
Рис. 10. Отфильтрованное изображение PCF с 25 процентами выбранного пикселя
Кроме того, можно сделать PCF без поддержки оборудования или расширить PCF до более крупных ядер. Некоторые методы даже примеры с весовым ядром. Для этого создайте ядро (например, Gaussian) для сетки N × N. Весы должны составлять до 1. Затем текстура выборка N2 раз. Каждый пример масштабируется соответствующими весами в ядре. В примере CascadedShadowMaps11 используется этот подход.
Смещение глубины
Смещение глубины становится еще более важным, когда используются большие ядра PCF. Это допустимо только для сравнения глубины светлого пространства пикселя с пикселем, с который он сопоставляется с картой глубины. Соседи карты глубины ссылаются на другую позицию. Эта глубина, вероятно, будет похожа, но может быть очень разными в зависимости от сцены. На рисунке 11 выделены артефакты, которые происходят. Одна глубина сравнивается с тремя соседними текселями в теневой карте. Один из тестов глубины ошибочно завершается ошибкой, так как его глубина не коррелирует с вычисляемой глубиной света текущей геометрии. Рекомендуемое решение этой проблемы — использовать более крупное смещение. Слишком большое смещение, однако, может привести к Питеру Паннингу. Вычисление жесткой близкой плоскости и дальней плоскости помогает уменьшить эффекты использования смещения.
Рис. 11. Ошибочное самотенение
Ошибочное самотенение приводит к сравнению пикселей в глубине светлого пространства с текселями в теневой карте, которая не коррелирует. Глубина в светлом пространстве коррелирует с теневым тексельом 2 на карте глубины. Тексель 1 больше светло-космической глубины, а 2 равны и 3 меньше. Texels 2 и 3 проходят тест глубины, а Texel 1 завершается ошибкой.
Вычисление Per-Texel смещения глубины с помощью DDX и DDY для больших ПК
Вычисление смещения глубины каждого текселя с ddx и ddy для больших PCFs — это метод, который вычисляет правильную предвзятость глубины ( если поверхность планарна) для соседней теневой карты тексель.
Этот метод соответствует глубине сравнения с плоскости с использованием производных сведений. Так как этот метод является вычислительным способом, его следует использовать только в том случае, если gpu имеет циклы вычислений для экономии. Если используются очень большие ядра, это может быть единственным способом, который работает для удаления самотенения артефактов, не вызывая Питера Паннинга.
Рис. 12 подчеркивает проблему. Глубина в светлом пространстве известна для одного текселя, который сравнивается. Глубины света, соответствующие соседствующим текселям на карте глубины, неизвестны.
Рис. 12. Карта сцены и глубины
сцены и карты глубины
Отрисованная сцена показана слева, а карта глубины с примером блока текселя отображается справа. Тексель пространства глаз сопоставляется с пикселем, помеченным D в центре блока. Это сравнение является точным. Правильная глубина в пространстве глаз, коррелируя с пикселями, которые сосед D неизвестен. Сопоставление соседних текселей обратно к пространству глаз возможно только в том случае, если предполагается, что пиксель относится к тому же треугольнику, что и D.
Глубина известна для текселя, который коррелирует с положением светлого пространства. Глубина неизвестна для соседних текселей на карте глубины.
На высоком уровне этот метод использует ddx и операции ddy HLSL для поиска производной от положения светлого пространства. Это нетривиальное, так как производные операции возвращают градиент глубины света относительно пространства экрана. Чтобы преобразовать это в градиент глубины светлого пространства относительно светлого пространства, необходимо вычислить матрицу преобразования.
Объяснение с кодом шейдера
Сведения о остальной части алгоритма предоставляются в качестве объяснения кода шейдера, выполняющего эту операцию. Этот код можно найти в примере CascadedShadowMaps11. На рисунке 13 показано, как координаты текстуры света сопоставляют карту глубины и как производные в X и Y можно использовать для создания матрицы преобразования.
Рис. 13. Матрица пространства экрана на свет
Производные от положения светлого пространства в X и Y используются для создания этой матрицы.
Первым шагом является вычисление производных позиции пространства освещения.
float3 vShadowTexDDX = ddx (vShadowMapTextureCoordViewSpace);
float3 vShadowTexDDY = ddy (vShadowMapTextureCoordViewSpace);
Графические процессоры класса Direct3D 11 вычисляют эти производные путем параллельного выполнения 2 × 2 квадрата пикселей и вычитания координат текстуры из соседа в X для ddx и от соседа в Y для ddy. Эти два производных составляют строки матрицы 2 × 2. В текущей форме эта матрица может использоваться для преобразования соседних пикселей экрана в наклоны светлого пространства. Тем не менее, требуется обратная матрица. Матрица, которая преобразует соседние пиксели света в наклоны экрана.
float2x2 matScreentoShadow = float2x2( vShadowTexDDX.xy, vShadowTexDDY.xy );
float fInvDeterminant = 1.0f / fDeterminant;
float2x2 matShadowToScreen = float2x2 (
matScreentoShadow._22 * fInvDeterminant,
matScreentoShadow._12 * -fInvDeterminant,
matScreentoShadow._21 * -fInvDeterminant,
matScreentoShadow._11 * fInvDeterminant );
Рис. 14. Светлое пространство на экран
Затем эта матрица используется для преобразования двух текселей выше и справа от текущего текселя. Эти соседи представлены как смещение от текущего текселя.
float2 vRightShadowTexelLocation = float2( m_fTexelSize, 0.0f );
float2 vUpShadowTexelLocation = float2( 0.0f, m_fTexelSize );
float2 vRightTexelDepthRatio = mul( vRightShadowTexelLocation,
matShadowToScreen );
float2 vUpTexelDepthRatio = mul( vUpShadowTexelLocation,
matShadowToScreen );
Соотношение, которое создает матрица, окончательно умножается на производные глубины для вычисления смещения глубины для соседних пикселей.
float fUpTexelDepthDelta =
vUpTexelDepthRatio.x * vShadowTexDDX.z
+ vUpTexelDepthRatio.y * vShadowTexDDY.z;
float fRightTexelDepthDelta =
vRightTexelDepthRatio.x * vShadowTexDDX.z
+ vRightTexelDepthRatio.y * vShadowTexDDY.z;
Теперь эти весы можно использовать в цикле PCF для добавления смещения в положение.
for( int x = m_iPCFBlurForLoopStart; x < m_iPCFBlurForLoopEnd; ++x )
{
for( int y = m_iPCFBlurForLoopStart; y < m_iPCFBlurForLoopEnd; ++y )
{
if ( USE_DERIVATIVES_FOR_DEPTH_OFFSET_FLAG )
{
depthcompare += fRightTexelDepthDelta * ( (float) x ) +
fUpTexelDepthDelta * ( (float) y );
}
// Compare the transformed pixel depth to the depth read
// from the map.
fPercentLit += g_txShadow.SampleCmpLevelZero( g_samShadow,
float2(
vShadowTexCoord.x + ( ( (float) x ) * m_fNativeTexelSizeInX ) ,
vShadowTexCoord.y + ( ( (float) y ) * m_fTexelSize )
),
depthcompare
);
}
}
PCF и CSM
PCF не работает над массивами текстур в Direct3D 10. Для использования PCF все каскады хранятся в одном большом атласе текстуры.
смещение Derivative-Based
При добавлении производных смещения для CSM возникают некоторые проблемы. Это связано с производным вычислением в элементе управления потоком разных элементов управления. Проблема возникает из-за фундаментального способа работы GPU. Графические процессоры Direct3D11 работают на 2 × 2 квадрата пикселей. Для выполнения производной графические процессоры обычно вычитают копию текущего пикселя переменной из копии соседнего пикселя той же переменной. Как это происходит, зависит от GPU до GPU. Координаты текстуры определяются каскадным выделением на основе карты или интервала. Некоторые пиксели в квадрате пикселей выбирают другой каскад, чем остальные пиксели. Это приводит к видимым швам между теневыми картами, так как смещение на основе производных теперь совершенно неправильно. Решение состоит в том, чтобы выполнить производные координаты текстуры пространства освещения. Эти координаты одинаковы для каждого каскада.
Заполнение ядер PCF
Индекс ядер PCF за пределами каскадной секции, если теневой буфер не помещается. Решение заключается в том, чтобы заполнить внешний обод каскада на одну половину размера ядра PCF. Это должно быть реализовано в шейдере, который выбирает каскад и в матрице проекции, которая должна отображать каскад достаточно большой, чтобы граница сохранялась.
Теневые карты дисперсии
VSMs (см. карты тени Вариативности Доннелли и Lauritzen для получения дополнительных сведений) включите фильтрацию прямой теневой карты. При использовании VSMs можно использовать все возможности оборудования фильтрации текстур. Можно использовать трилайнарную и анисотропную фильтрацию (рис. 15). Кроме того, VSM можно размыть непосредственно через свертку. VSMs имеют некоторые недостатки; должны храниться два канала данных глубины (глубина и глубина квадрата). Когда тени перекрываются, легкие кровотечения распространены. Они хорошо работают, однако, с более низким разрешением и могут быть объединены с CSM.
Рис. 15. Анисотропная фильтрация
Сведения о алгоритме
VSM работает путем отрисовки глубины и глубины, квадратной на теневой карте двух каналов. После этого двухканальное теневое сопоставление может быть размыто и отфильтровано так же, как обычная текстура. Затем алгоритм использует неравенство Чебичева в шейдере пикселей для оценки доли области пикселей, которая пройдет тест глубины.
Шейдер пикселей получает значения глубины и глубины квадрата.
float fAvgZ = mapDepth.x; // Filtered z
float fAvgZ2 = mapDepth.y; // Filtered z-squared
Выполняется сравнение глубины.
if ( fDepth <= fAvgZ )
{
fPercentLit = 1;
}
Если сравнение глубины завершается сбоем, процент пикселя, который был освещен, оценивается. Вариативность вычисляется как среднее значение квадратов минус квадратов среднего.
float variance = ( fAvgZ2 ) − ( fAvgZ * fAvgZ );
variance = min( 1.0f, max( 0.0f, variance + 0.00001f ) );
Значение fPercentLit оценивается с неравенством Чебичева.
float mean = fAvgZ;
float d = fDepth - mean;
float fPercentLit = variance / ( variance + d*d );
Светлое кровотечение
Самым большим недостатком VSMs является легкий кровотечение (рис. 16). Светлое кровотечение возникает, когда несколько теневых кастеров окклюд друг друга вдоль краев. VSM затеняют края теней на основе различий глубины. Когда тени пересекаются друг с другом, в центре региона существует неравенство глубины, которое должно быть теневым. Это проблема с использованием алгоритма VSM.
Рис. 16. Легкое кровотечение VSM
Частичное решение проблемы заключается в том, чтобы поднять fPercentLit к власти. Это влияет на размытие, что может привести к артефактам, где неравенство глубины невелико. Иногда существует волшебное значение, которое устраняет проблему.
fPercentLit = pow( p_max, MAGIC_NUMBER );
Альтернатива повышению процента, освещенного в мощности, заключается в том, чтобы избежать конфигураций, где тени перекрываются. Даже очень настроенные конфигурации тени имеют несколько ограничений на свет, камеру и геометрию. Легкое кровотечение также уменьшается с помощью текстур более высокого разрешения.
Многоуровневые теневые карты (LVSMs) решают проблему за счет разрыва frustum на слои, которые перпендикулярны свету. Количество карт, необходимых для использования, будет довольно большим при использовании CSM.
Кроме того, Эндрю Лауицен, соавтор статьи по VSMs и автор статьи на LVSMs, обсудил объединение экспоненциальных карт теней (ESMs) с VSMs для противодействия легкому смешению в Beyond3D Forum.
VSMs с CSMs
Пример VarianceShadow11 объединяет vsms и CSMs. Сочетание довольно просто. Пример выполняет те же действия, что и образец CascadedShadowMaps11. Так как PCF не используется, тени размыты в двухпроходной свертке. Не используя PCF, пример также позволяет использовать массивы текстур вместо атласа текстур. PCF в массивах текстур — это функция Direct3D 10.1.
Градиенты с csms
Использование градиентов с CSM может создать шов вдоль границы между двумя каскадами, как показано на рисунке 17. В примере инструкции используются производные между пикселями для вычисления сведений, таких как уровень mipmap, необходимый фильтру. Это приводит к проблеме, в частности для выбора mipmap или анисотропной фильтрации. Если пиксели в квадрате принимают различные ветви в шейдере, производные, вычисляемые оборудованием GPU, недопустимы. Это приводит к замеченной шве вдоль теневой карты.
Рис. 17. Швы на каскадных границах из-за анисотропной фильтрации с помощью управления потоками разверждения
Эта проблема решена путем вычисления производных на позиции в пространстве освещения; Координата пространства освещения не зависит от выбранного каскада. Вычисляемые производные можно масштабировать по масштабируемой части матрицы текстур проекции до правильного уровня MIP-карты.
float3 vShadowTexCoordDDX = ddx( vShadowMapTextureCoordViewSpace );
vShadowTexCoordDDX *= m_vCascadeScale[iCascade].xyz;
float3 vShadowTexCoordDDY = ddy( vShadowMapTextureCoordViewSpace );
vShadowTexCoordDDY *= m_vCascadeScale[iCascade].xyz;
mapDepth += g_txShadow.SampleGrad( g_samShadow, vShadowTexCoord.xyz,
vShadowTexCoordDDX, vShadowTexCoordDDY );
VSMs по сравнению со стандартными тенями с PCF
И VSMs, и PCF пытаются приблизить долю области пикселей, которая пройдет тест глубины. VSMs работают с оборудованием фильтрации и могут быть размыты с помощью отдельных ядер. Сепарабельные ядра значительно дешевле реализовать, чем полное ядро. Кроме того, VSM сравнивает одну световую глубину с одним значением в карте глубины света. Это означает, что vsms не имеют одинаковых проблем смещения, что и PCF. Технически VSM — это глубина выборки по большей области, а также выполнение статистического анализа. Это менее точно, чем PCF. На практике VSM выполняют очень хорошую работу смешивания, что приводит к меньшему смещению. Как описано выше, недостатком VSM является легкий кровотечение.
VSMs и PCF представляют компромисс между вычислительной мощностью GPU и пропускной способностью текстуры GPU. Для вычисления дисперсии vsms требуется больше математических вычислений. PCF требует больше пропускной способности памяти текстуры. Большие ядра PCF могут быстро оказаться узкими по пропускной способности текстуры. Благодаря быстрому росту вычислительной мощности GPU, чем пропускная способность GPU, vsms становится более практическим из двух алгоритмов. VSMs также лучше выглядят с теневыми картами с более низким разрешением из-за смешивания и фильтрации.
Сводка
CSMs предлагают решение проблемы с псевдонимом перспективы. Существует несколько возможных конфигураций для получения необходимой визуальной точности для заголовка. PCF и VSM широко используются и должны сочетаться с CSM для уменьшения псевдонимов.
Ссылки
Доннелли, В. и Лауицен, А. теневые карты вариативности. В SI3D '06: Материалы симпозиума 2006 года по интерактивной трехмерной графике и играм. 2006. pp. 161–165. Нью-йорк, нью-йорк, США: ACM Press.
Лауицен, Эндрю и МакКул, Майкл. многоуровневые теневые карты теневых карт. Материалы графического интерфейса 2008, 28–30 мая 2008 года, Виндзор, Онтарио, Канада.
Энгель, Woflgang F. Раздел 4. Каскадные теневые карты. ШейдерX5, расширенные методы отрисовки, Вольфганг Ф. Энгель, Эд. Чарльз Ривер Медиа, Бостон, Массачусетс. 2006. pp. 197–206.