Отложенное затенение - как объединить несколько источников света?

9

Я начинаю с GLSL и реализовал простое отложенное затенение, которое выводит G-буфер с позициями, нормалями и альбедо.

Я также написал простой точечный световой шейдер.

Теперь я рисую сферу для точечного источника света, и вывод идет в буфер освещения.

Проблема в том, как объединить результаты буфера освещения при рисовании нескольких источников света?

Например, когда я рисую второй источник света в буферном освещении, используя шейдер точечного источника света, как мне добавить первый источник света ко второму источнику света в буфере освещения. Я имею в виду, вы не можете читать и писать в один и тот же буфер вывода?

JBeurer
источник

Ответы:

12

Аддитивное смешивание, т.е. glBlendFunc (GL_ONE, GL_ONE) и glEnable (GL_BLEND).

Натан Рид
источник
для этого нужно отключить глубинное тестирование?
woojoo666
1
@ woojoo666 Нет. На самом деле его нужно включить, если для теста глубины установлено менее равное значение, чтобы проходили поверхности, точно совпадающие с предыдущим проходом. Если проверка глубины отключена, то поверхности будут неправильно накапливать свет от всего, что находится позади них. :)
Натан Рид
хм, похоже, именно это и происходит. При включении смешивания передние грани смешиваются с задними гранями, хотя я включил тестирование глубины. мне нужно что-то сделать с маской глубины?
woojoo666
сделал немного больше тестирования, похоже, порядок рисования имеет значение (рисование спереди назад позволяет правильно тестировать глубину, а смешивание происходит только в том случае, если грани равны по плоскости, а спереди назад все смешивается). Есть ли способ сделать это, не сортируя все?
woojoo666
2
@ woojoo666 Ага, похоже, ты решил это сам. Да, вы должны установить глубину в непрозрачном проходе, прежде чем вы сможете использовать любой вид смешивания. Это может быть z-препасс с отключенной записью цветов, или другой распространенный способ - сделать окружающий / направленный свет в первом проходе без наложения, а затем добавить точечные / точечные источники света на более поздних проходах с наложением.
Натан Рид
2

Для моего отложенного рендеринга я объединяю все источники света в одну цель рендеринга источников света, используя информацию из g-буфера, а затем выполняю выборку, которая отображает цель для интенсивности света при создании моего окончательного изображения заднего буфера.

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

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

KlashnikovKid
источник
Да, и вопрос в том, как вы добавляете к цели визуализации света? Используя альфа-смешение, как предложил Натан Рид? Потому что, насколько я знаю, вы не можете читать и записывать в один и тот же выходной буфер (в данном случае это легкий буфер).
JBeurer
Ой, да. Я позволил выходному слиянию справиться с этим с помощью аддитивного смешивания. Когда выборка для окончательного изображения происходит, когда вы хотите ограничить значение тем, которое работает для меня как максимально возможная интенсивность света, которую может получить поверхность. Оттуда вы можете просто масштабировать свои огни по мере необходимости.
KlashnikovKid
Как вы справляетесь со случаями, когда свет находится за стеной и не должен освещать вещи на другой стороне стены?
Jjxtra
@PsychoDad Это область теней, которая ... более сложная тема. :)
Натан Рид
0

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

CodeNeko
источник
Нет, это не сработает. Я рисую сферу для каждой точки света. Если второй точечный источник света не находится в сфере влияния первого источника света, второй источник света просто не будет прорисован. Ваш метод сработает, если я нарисую полноэкранный квад для всех точечных источников света, однако это неправильный подход, потому что полноэкранные квадраты используются для глобального освещения. Скажем, у меня есть 16 маленьких точечных источников света, которые заставили бы меня проходить их для каждого пикселя, даже если он им не освещен. И обычно я бы сказал, что каждый пиксель освещается одним или двумя огнями. А что если у меня 100 лампочек? НЕТ
JBeurer
Основная причина, по которой я это сказал, заключается в том, что если вы используете только два или несколько источников света, это может помочь. Особенно, если вы разрисовываете много объектов, использование смешивания означает, что вам нужно перерисовать сцену для каждого источника света, поэтому, если у вас много фигур, скажем, один миллион, или десять миллионов, или миллиард, каждый рисунок стоит намного дороже. , Выполнение этого в шейдере вызывает проблемы, если вы хотите много источников света, но смешивание вызывает проблемы, если вы хотите много форм. Если у вас много обоих, вам нужно найти золотую середину, но обычно у вас есть несколько источников света и множество объектов в играх.
CodeNeko
Нет, отложенное затенение не работает таким образом. Я должен нарисовать сцену только один раз и сохранить соответствующую информацию в G-Buffer. Затем сфера влияния для каждого источника света и смешайте его со световым буфером. И, наконец, комбинируя световой буфер с цветным буфером, я получаю окончательный буфер закрашенных цветов. Количество вычислений освещения не зависит от сложности сцены. Это главное преимущество отложенного затенения в первую очередь.
JBeurer
Ах, это имеет больше смысла и будет значительно лучше.
CodeNeko