Сравнение методов наложения теней с помощью Shadow Explorer

Скачать статью и посетить домашнюю страницу Shadow Explorer

Скачать статью Comparing Shadow Mapping Techniques with Shadow Explorer [Eng., PDF 990KB]
Домашняя страница Shadow Explorer (исходный код, видео)
 

Введение

Тени в том или ином виде реализованы в абсолютном большинстве современных игр. При этом, в каждом случае разработчики должны решить, какие применять алгоритмы и какие сложности стоит ожидать при использовании той или иной методики, какое соотношение качества и производительности оптимально подходит для данного приложения. Рассматриваемый нами приме𠬬– Shadow Explorer – позволяет пользователю сравнить четыре разных метода, настраивая параметры работы каждого из них и наблюдая возникающие эффекты в реальном времени. В нем представлены следующие алгоритмы наложения теней: простой каскадный метод, PCF (percentage closer filtered), VSM (variance), and EVSM (exponential variance).
 

Использование примера

На самом высоком уровне данный пример позволяет пользователю сравнить качество и характеристики производительности разных теневых алгоритмов. Здесь присутствуют две сцены, на которых можно применять алгоритмы: панорама города и чайник. Первая (сцена города) является типичной для игрового мира и состоит из объектов разного размера и обладающих разными характеристиками. Чайник представляет собой «самый плохой» вариант, поскольку состоит в основном из тонких примитивов, которые отбрасывают тени не только на себя, но и на искривлённые поверхности и плоское основание.
 

Архитектура примера

Shadow Explorer реализован в виде приложения Microsoft DirectX* на основе DXUT. Все четыре алгоритма наложения теней работают на общей основе, но используют разные шейдеры, также VSM и EVSM перед рендерингом сцены применяют фильтр к карте теней. В листинге 1 приведёна часть исходного кода, отвечающая за создание и использование карты теней. Каждый фрейм функция RenderShadowMap() создаёт стандартную каскадную карту теней с помощью шейдера SceneZ. Как уже было сказано, алгоритмы VSM и EVSM после этого фильтруют карту теней с помощью шейдеров FilterV и FilterH. Затем производится рендеринг сцены шейдером SceneMain, который, в зависимости от выбранного алгоритма, вызывает разные версии IsNotInShadow()(). Соответствующие версии при выборе алгоритма создаются с помощью перекомпиляции шейдеров с использованием разных файлов .fxh. Например, если выбран алгоритм PCF, то вызывается версия IsNotInShadow(), находящаяся в файле filter_PCF.fxh.

 

static void RenderShadowMap(...)
{
   // For each cascade
   for( int i = 0; i < iLayers; ++i )
   {
      // Set the Z only pass
      SetRenderTargets( 0, NULL, g_d3d.pShadowMapDSV[i] );
      g_d3d.pTechSceneZ->GetPassByIndex( 0 )->Apply( 0,
         pd3dImmediateContext );
      // Render the appropriate scene
      g_pSelectedMesh->Render( pd3dImmediateContext );
   }
   
   // VSM and EVSM techniques require additional filters
   if(Filter_Type_VSM || Filter_Type_EVSM)
   {
      // Use the shadow map just generated in the filters
      g_d3d.pVarShadowTex->SetResource( g_d3d.pShadowMapSRV );

      // Run the vertical filter
      SetRenderTargets( 1, &pShadowMapRTV_vsm[0].p, NULL );
      g_d3d.pTechFilter_V->GetPassByIndex( 0 )->Apply(...);
      pd3dImmediateContext->Draw(...);

      // Use the result of the vertical filter
      g_d3d.pVarShadowTex->SetResource( g_d3d.pShadowMapSRV_vsm[0] );

      // Run the horizontal filter
      SetRenderTargets( 1, &pShadowMapRTV_vsm[1].p, NULL );
      g_d3d.pTechFilter_H->GetPassByIndex( 0 )->Apply(...);
      pd3dImmediateContext->Draw(...);
   }
}

static void RenderScene(...)
{
   RenderShadowMap(...)

   if(Filter_Type_VSM || Filter_Type_EVSM)
      // Use the filtered shadow map
      g_d3d.pVarShadowTex->SetResource( g_d3d.pShadowMapSRV_vsm[1] );
   else
      g_d3d.pVarShadowTex->SetResource( g_d3d.pShadowMapSRV );
   g_pSelectedMesh->Render(...);
}

Листинг 1 - Основной код приложения Shadow Explorer


Самым простым вариантом алгоритма является базовая каскадная карта теней. Очевидно, что это самый быстрый метод, поскольку он требует минимального объёма работы, но с точки зрения качества он оставляет желать много лучшего. Следом идёт алгоритм PCF, который работает с такой же картой теней, но обращается к текстуре по несколько раз, чтобы уменьшить уровень алиасинга и сгладить границы теней. Лучшее качество достигается при увеличении количества сэмплов, но при этом вполне предсказуемо страдает производительность. Если использовать неравномерное распределение сэмплов, то хороших результатов можно достичь с помощью меньшего количества сэмплов. В Shadow Explorer вместо позиций на основе грида используется предварительно рассчитанная последовательность Гальтона для расчёта «случайных» позиций. Метод PCF требует большого количества сэмплов, даже при неравномерного распределения, что дает значительные нагрузки на GPU.

Следующий метод, VSM, сохраняет значения глубины и квадрата глубины в карте теней. В Shadow Explorer рендеринг карты теней происходит нормально, а квадрат глубины добавляется во время дополнительного прохода сразу после z-прохода. Кроме того, во втором проходе запускается блочный фильтр, который смягчает края теней. Основным недостатком алгоритма VSM является наличие эффекта потёков света в случаях, когда несколько отбрасывающих тень объектов накладываются друг на друга и отношение их расстояний от создаваемой тени достаточно велико. Это хорошо видно на рис. 1: тень от высокого здания, расположенного на заднем плане, очерчена светлыми полосами в тех местах, где она накладывается на тени от двух более низких зданий на переднем плане.

 

 

 

 

 

Рис. 1 - Алгоритм VSM приводит к возникновению эффектов потёков света


В зависимости от сцены, потёки света могут быть незаметны и не создавать проблемы. Если они начинают мешать, то для устранения проблемы можно использовать алгоритм EVSM, как показано на рис. 2. Основным отличием от VSM здесь является то, что EVSM «искажает» значения глубины при считывании их из карты теней. В результате относительные расстояния от объектов до их теней сокращаются, что минимизирует или исключает эффект потёков света. В Shadow Explorer это делается функцией WarpDepth().

 

 

Рис. 2 - EVSM устраняет эффект потёков света

 

Заключение

В Shadow Explorer реализованы четыре метода наложения теней с возможностью изменения во время работы различных параметров таким образом, чтобы пользователь мог сравнить производительность и качество получаемой картинки при использовании разных технологий. Во всех алгоритмах была настроена оптимальная производительность. При оптимизации в некоторых местах были использованы значения типа float половинной точности, в PCF были развёрнуты циклы, вертикальный фильтр стал запускаться до горизонтального, выбирался интервал каскада Z вместо нахождения наилучшего каскада, тени рассчитывались только для треугольников, ориентированных по направлению к свету. Дополнительные материалы, включая исполняемые файлы и исходные коды, можно найти на домашней странице ресурса http://software.intel.com/en-us/articles/shadowexplorer.

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

 

Управление

Shadow Explorer позволяет пользователю изменять разные параметры, меняющие поведение теневых алгоритмов. Ниже приведён список контрольных параметров и их краткое описание:

 

 

 

  1. Toggle full screen - Включение/выключение полноэкранного режима
  2. Change device - Смена d3d устройства
  3. Scene drop down list - Смена отображаемой сцены
  4. Align light to camera - Поворот источника света для оптимального использования пространства теневой карты
  5. Algorithm drop down list - Смена метода фильтрации
  6. Shadow Map BPP - Определение количества бит, используемых для каждого пикселя теневой карты
  7. SM resolution - Изменение разрешения теневой карты
  8. Filter size - Размер фильтра, используемого в PCF, VSM, и EVSM
  9. Cascade layers - Сколько каскадных уровней используется
  10. Cascade Factor - Указывает, как пространство разбивается плоскостями
  11. Aperture - Апертура пространственного фильтра для PCF
  12. Visualize Cascades - Визуализация разных уровней каскадов
  13. Visualize Light Space - Отображение сцены из точки источника света
  14. Use Texture Array - Использование в каскадах массива текстур. Каждый уровень получает одну текстуру. В противном случае используется атлас текстур.
  15. Z interval selection - Метод определения, к какому каскаду относится конкретный пиксель. Если параметр установлен, то используется только расстояние по z только в области видимости. В противном случае для определения позиции пикселя проверяются все каскады.
  16. Deduce Z range - Вычисляет z-диапазон из текущего вида. В противном случае в качестве верхней границы используется окружающий объём сцены.
  17. Deduce Res - Разрешение рендер-таргета, используемого для расчёта z-диапазона
  18. Downscale Factor - Каждый последующий проход GPU использует текстуру рендер-таргета меньшего размера. Данная опция определяет отношение между размерами текстур последующих проходов.
  19. Downscale Limit - Максимальный размер текстуры, когда расчёт Z-диапазона выполняется на GPU. В некоторый момент становится более эффективным перенести все данные на CPU и завершить расчёты там, что экономит несколько вызовов отрисовки.

 

 

 

Об авторах

Алексей Рухлинский (Alexey Rukhlinskiy) является специалистом по графическим программам в отделе Intel Advanced Visual Computing Division. Он занимается разработкой профессиональных графических программ уже более 10 лет. Получил степень магистра компьютерных наук в Новосибирском Государственном Университете в 2002 году.

Квентин Фромке (Quentin Froemke) не отходит от клавиатуры уже более 10 лет, в настоящее время работает в отделе Intel Visual Computing Software Division, где помогает в оптимизации и улучшении компьютерных игр.

 

Ссылки

 

 

 

  1. Williams, L. 1978. Casting curved shadows on curved surfaces. In Proc. SIGGRAPH, vol. 12, 270-274. http://portal.acm.org/citation.cfm?id=807402
  2. Donnelly, W. and Lauritzen, A. Variance shadow maps. In SI3D '06: Proceedings of the 2006 symposium on Interactive 3D graphics and games. 2006. pp. 161-165. New York, NY, USA: ACM Press. /sites/default/files/m/1/f/d/vsm_paper.pdf
  3. Lauritzen, Andrew and McCool, Michael. Layered variance shadow maps. Proceedings of graphics interface 2008, May 28-30, 2008, Windsor, Ontario, Canada. http://portal.acm.org/citation.cfm?id=1375714.1375739&coll=GUIDE&dl=GUIDE
  4. Isidoro, J. R. Shadow Mapping: GPU-based Tips and Techniques. Conference Session. GDC 2006. March 2006, San Jose, CA. /sites/default/files/m/7/6/1/Isidoro-ShadowMapping.pdf
  5. The Halton Sequence. http://orion.math.iastate.edu/reu/2001/voronoi/halton_sequence.html
  6. Engel, Wolfgang F. Section 4. Cascaded Shadow Maps. ShaderX5, Advanced Rendering Techniques, Wolfgang F. Engel, Ed. Charles River Media, Boston, Massachusetts. 2006. pp. 197-206.
Для получения подробной информации о возможностях оптимизации компилятора обратитесь к нашему Уведомлению об оптимизации.