Pull to refresh

Comments 6

Правильно ли я понимаю, что при этом яркость всех ярких объектов увеличивается в 2 раза? Может нужно занулять FragColor в тех местах, где выставлен ненулевой BrightColor?
Не в два раза — второй буфер содержит отфильтрованное изображение. Плюс, если удалить исходные области, то в ярком пятне потеряется исходная детализация, опять же из-за фильтра.
И вряд ли в этом был бы какой-то особый физический смысл. Тональная компрессия так или иначе пройдется по яркой области.
Для ярких областей которые попали во вторую текстуру в два. Вокруг них уже с учетом размытия, а те что дальше не получат никакого дополнительного увеличения.
Занулять не получится, тогда под ореолом не будет видно ничего. А увеличение яркости в двое не проблема из-за экспоненциальной тоновой компрессии.

Искал как сделать bloom, нашёл красивую идею: https://www.gamedev.net/forums/topic/693388-bloom/?do=findComment&comment=5362111


Для картинки делается размытие, и потом она с каким-то небольшим коэффициентом (типа 0.05 — 0.15) смешивается с исходной картинкой. Идея небольшого коэффициента в том, что яркая размытая область будет заметно влиять на тёмную, но при этом тёмная на яркую — практически нет. Это делается в HDR, где яркости тёмных и светлых объектов действительно сильно различаются. Таким образом, никакого "искусственного" отсечения по яркости не будет.

Совсем недавно делал свою реализацию Bloom-а на основе оригинальной статьи и хочу поделиться несколькими соображениями.

1) Имеет смысл сразу делать реализацию, которая использует линейную фильтрацию исходной cutoff текстуры, получается почти в два раза меньшее количество сэмплов на фрагмент.

2) Я сделал реализацию, в которой задавалась «ширина» гауссовской кривой (при помощи указания среднеквадратичного отклонения), а также количество точек сэмплинга вокруг текущего фрагмента. Практика показала, что эти параметры в общем-то лишние. Степень размытия удобнее и быстрее задавать при помощи изменения (уменьшения) размера текстур pingpongBuffer[2]. Также, результат, получаемый при количестве точек сэмплинга в скажем 7, визуально не отличается от скажем 77, если размытие сделать по крайней мере два-три раза.

3) Для финального прохода, где размытие текстуры объединяются с исходной имеет смысл использовать несколько различных текстур-результатов размытия по Гауссу, но с разной степенью размытия, как и рекомендуется в статье How to do good bloom for HDR rendering. Кроме того, имеет смысл назначить различные веса для разных текстур-размытий чтобы можно было варьировать степень их влияния на конечный результат. К сожалению, каждое дополнительное размытие по Гауссу отъедает около 5-10 FPS на моей системе: манипуляции с FBO и текстурами увы не бесплатны.

Самой сложной частью, на мой взгляд, является подбор функции тональной компрессии. Ни один более или менее стандартный алгоритм (некоторые из них можно посмотреть например тут) не давал хорошего визуального результата: дело в том, что все они снижают контрастность на участках средней яркости. Поэтому, пока я остановился на алгоритме, который применяется только для ярких участков, т.е. участков, которые изначально попадают в cutoff текстуру. Краткий смысл таков, что HDR изображение преобразуется из пространства RGB в пространство xyY сжимается в нём в части Luminance (светимости) и потом преобразуется обратно в RGB. Функция сжатия используется самая простая, что-то вроде:
float mapY = pow(xyY.z, 0.5);


Нерешённой у меня осталось проблема излишнего блеска поверхностей, которые по идее «блумить» не должны, например specular участки воды, но тут уже сказывается ограничение моего движка, т.к. я реализовал Bloom как пост-процессинг эффект, а по уму его нужно делать только для emissive (излучающих) фрагментов сцены.
Sign up to leave a comment.

Articles

Change theme settings