Эффективный рендеринг со многими источниками света

10

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

Это может быть легко расширено для приспособления к нескольким источникам света путем суммирования результатов применения каждого отдельного источника света к фрагменту как такового:

final_color = (0, 0, 0, 1)
for each light:
    final_color += apply_light(material, light)
final_color = clamp(final_color, (0,0,0,1), (1,1,1,1))

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

Есть ли лучший подход для рендеринга сцен с очень большим количеством источников света (сотни, тысячи и т. Д.)?

es1024
источник

Ответы:

15

Да, но вам нужно сменить парадигму.

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

Но многое изменилось. Входит: отложенный рендеринг

Теперь, когда есть так много вариантов, которые описывают их все в деталях, ответ здесь будет более чем приемлемым. Итак, здесь я просто собираюсь описать суть отложенного затенения, есть много других ресурсов, которые вы можете легко найти с помощью Google, надеюсь, после прочтения этого у вас будут правильные ключевые слова, чтобы найти то, что вам нужно.

Основная идея состоит в том, чтобы отложить затенение до окончания конвейера. У вас есть два основных шага:

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

Это изображение из Википедии показывает три буфера (цвет, глубина и нормали)

введите описание изображения здесь

Опять же, количество, тип и содержание используемых буферов довольно сильно различаются в разных проектах. Вы найдете набор буферов с именем GBuffers.

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

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

Он также имеет различные недостатки, в частности, обработку прозрачных объектов и более высокое потребление полосы пропускания и видеопамяти. Но также сложнее обращаться с различными моделями материалов.

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

Более новыми методами являются, например, Tiled Rendering . Основная идея заключается в том, чтобы разделить сцену на экранные «плитки» и назначить каждой плитке свет, воздействующий на нее. Это существует как в отложенном, так и в прямом направлении. Эти методы приводят к некоторым проблемам, когда у вас есть различные разрывы глубины в плитке, но, как правило, быстрее, чем у классической отсроченной, и это решает различные ее проблемы. Например, среди преимуществ, с использованием мозаичного отсрочки, вы считываете GBuffers один раз на освещенный фрагмент, а пиксели в одной и той же плитке последовательно обрабатывают одни и те же источники света.

Дальнейшее развитие на этой стороне - кластерное затенение, которое концептуально похоже на плиточные подходы, с использованием вместо плиток пространства экрана кластеров с трехмерным экстентом. Этот метод лучше справляется с проблемой разрывов глубины и обычно работает лучше, чем мозаичные методы.

ВАЖНОЕ ПРИМЕЧАНИЕ: я описал основы отложенного затенения. Существует множество вариаций, оптимизаций и улучшений, поэтому я призываю вас поэкспериментировать с простой версией, а затем провести некоторые исследования других методов, таких, которые я упоминал выше.

cifz
источник
1
Вот два ресурса исходного кода для Tiled и Clustered
RichieSams