Відкладене затінення - як поєднувати кілька світильників?


9

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

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

Тепер я малюю сферу для точкового світла і вихід виходить у буфер освітлення.

Проблема полягає в тому, як я поєдную результати буфера освітлення при малюванні декількох вогнів?

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

Відповіді:


12

Аддитивне змішування, тобто glBlendFunc (GL_ONE, GL_ONE) та glEnable (GL_BLEND).


чи потрібно вимкнути глибинне тестування для цього?
woojoo666

1
@ woojoo666 Ні. Насправді це повинно бути включено з випробуванням на глибину, встановленим на менш рівне, так що поверхні, які точно відповідають попередньому проходу, будуть проходити. Якщо випробування на глибину вимкнено, то поверхні будуть неправильно накопичувати світло від того, що знаходиться позаду них. :)
Натан Рід

Хм, здається, що саме те, що відбувається, хоча. Повернення змішування на передніх гранях поєднується із задніми гранями, хоча я перевіряв глибину тестування. чи потрібно щось робити і з маскою глибини?
woojoo666

трохи тестування, схоже, має значення порядку замовлення (малювання спереду та назад робить глибоке тестування правильним і суміш відбувається лише в тому випадку, якщо грані є рівноплановими, а спина - наперед - все поєднується разом). Чи є спосіб це зробити, не сортуючи все?
woojoo666

2
@ woojoo666 Ага, здається, ви вирішили це самостійно. Так, вам доведеться закласти глибину в непрозорий прохід, перш ніж ви зможете використовувати будь-яку суміш. Це може бути z-попередній запис із відключенням кольорового запису, або іншим поширеним способом є навколишнє / спрямоване світло при першому проході без змішування, а потім додавати точкові / точкові світильники в пізніші проходи зі змішуванням.
Натан Рід

2

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

Таким чином, я проводжу всю свою геометрію гри через пропуск геометрії для створення g-буферів. Звідти я подаю g-буфери в мій шейдер пропускання світла. Кожне світло пропускається через прохід, використовуючи повноекранний квадроцикл. Таким чином мій піксельний шейдер може обчислити інтенсивність світла для всіх видимих ​​поверхонь з g-буфера, а потім додати їх до цілі світлого відтворення. Ви просто додаєте інтенсивність світла для кожного світла до буфера світла, але обов'язково затискаєте інтенсивність від 0 до 1.

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


Так, і питання полягає в тому, - як ви додаєте до цілі легкої візуалізації? Використовувати альфа-змішування, як запропонував Натан Рід? Тому що, наскільки я знаю, ви не можете читати і записувати в той самий вихідний буфер (який у цьому випадку є легким буфером).
JBeurer

Ой, так. Я дозволяю вихідному злиттю впоратися з тим, що додає добавки. Під час відбору проб для остаточного зображення, коли ви хочете зафіксувати значення, яке працює для мене, як максимально можливу інтенсивність світла, яку може отримати поверхня. Звідти ви можете просто масштабувати свої світильники за потребою.
KlashnikovKid

Як ви поводитесь із випадками, коли світло знаходиться за стіною і не повинен запалювати речі з іншого боку стіни?
jjxtra

@PsychoDad Це сфера тіней, що є ... більш складною темою. :)
Натан Рід

0

Ймовірно, краща відповідь, ніж ця, але я знаю, якщо у вашому шейдері ви повторите код, необхідний для другого світла, ви зможете обробити два індикатори на одному об'єкті замість одного. Це вимагає усунення багато коду для другого світла і шви трохи зайві, але я знаю, що це працює. Однак я вірю, як хтось, як ми сподіваємось, зауважимо для вас, може бути і більш елегантне рішення.


Ні, це не працює так. Я малюю сферу для кожного точкового світла. Якщо друга точка не лежить у сфері впливу першого світла, друге світло просто не буде намальовано. Ваш метод спрацював би, якщо я намалюю повноекранний квадроцикл для всіх точкових світильників, однак, це не правильний підхід, оскільки повноекранні квадроцикли використовуються для глобальної ілюмінації. Скажімо, у мене 16 маленьких точкових вогнів, що змусить мене пройти їх для кожного пікселя, навіть якщо піксель не засвічується ним. І зазвичай я б сказав, що кожен піксель горить одним або двома лампами. А що, якщо у мене 100 вогнів? НЕТ
JBeurer

Основна причина, про яку я заявив, це те, що якщо ви використовуєте лише два або кілька світильників, це може допомогти. Особливо, якщо ви обробляєте багато об'єктів, використовуючи суміш, вам потрібно перемалювати сцену для кожного світла, тому якщо у вас є багато форм, скажімо, один мільйон або десять мільйонів або мільярд, кожен малюнок коштує набагато більше . Якщо це зробити в шейдері, це спричинить проблеми, якщо ви хочете багато світла, але суміш викликає проблеми, якщо ви хочете багато форм. Якщо у вас багато обох, вам потрібно знайти середину, але зазвичай у вас є кілька вогнів і багато предметів в іграх.
CodeNeko

Ні, відкладене затінення не працює таким чином. Я маю намалювати сцену лише один раз і зберігати відповідну інформацію в G-Buffer. Потім сфера впливу на кожне світло і змішайте його з буфером світла. І, нарешті, поєднуючи світловий буфер з кольоровим буфером, я отримую остаточний відтінок буферного кольору. Кількість обчислень освітлення не залежить від складності сцени. Це головна перевага відкладеного затінення, в першу чергу.
JBeurer

Ах, це має набагато більше сенсу і значно краще.
CodeNeko
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.