No Image

Эффект bloom в играх

СОДЕРЖАНИЕ
2 просмотров
11 марта 2020

Bloom (с англ. — «свечение»; произн. «блюм», «блум») — постэффект в трёхмерной графике, который используется в компьютерных играх и других 3D-приложениях. Эффект используется разработчиками игр для создания эффекта размытости света на ярких гранях сцены, передержку камерой при съёмке, а также для добавления большей кинематографичности изображению.

Одной из наиболее известных игр, где был использован этот эффект, является аркадный автосимулятор Need for Speed: Most Wanted. В этой игре с помощью эффекта блюм реализовано свечение от солнечных лучей на асфальте, а также размытость на ярких гранях сцены, таких, как дневное небо.

Действие эффекта во многом схоже по действию с другим эффектом, «glow», однако эти эффекты имеют различные способы реализации, и как следствие, отличия в изображении. Bloom используется в играх вместе с High Dynamic Range, однако иногда простое включение bloom-фильтра в настройках игры обозначается как «включение HDR».

Bloom

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

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

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

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

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

Чтобы было яснее разберем процесс по шагам. Рендерим сцену, содержащую 4 ярких источника света, отображенных как цветные кубики. Все они имеют величину яркости в интервале от 1.5 до 15.0. Если осуществить вывод в HDR буфер цвета, то результат выглядит следующим образом:

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

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

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

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

Итак, вышеописанные действия дают нам пошаговый алгоритм эффекта пост-обработки для блум-эффекта. Изображение ниже кратко подытоживает необходимые действия:

Первым делом нам потребуется информация о ярких участках сцены на основе заданного порогового значения. Этим и займемся.

Извлечение ярких участков

Итак, для начала нам потребуется получить два изображения на основе нашей сцены. Можно было бы наивно выполнить рендер дважды, но используем более продвинутый метод множественных целей рендера (Multiple Render Targets, MRT): мы задаем в завершающем фрагментном шейдере более одного выхода и благодаря этому извлечение двух изображений можно выполнить в один проход! Чтобы указать в какой буфер цвета будет осуществлен вывод шейдера используется спецификатор layout:

Читайте также:  1С дополнительные реквизиты в табличной части

Безусловно, метод будет работать только если мы подготовили несколько буферов для записи. Иными словами, для осуществления множественного вывода из фрагментного шейдера использующийся в этот момент кадровый буфер должен содержать достаточное количество подключенных буферов цвета. Если обратиться к уроку о кадровом буфере, то вспоминается, что при привязке текстуры как буфера цвета мы могли указать номер прикрепления цвета (color attachment). До сего момента нам не было нужды использовать прикрепление отличное от GL_COLOR_ATTACHMENT0, но в этот раз пригодится и GL_COLOR_ATTACHMENT1 – ведь нам нужны сразу две цели для записи:

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

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

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

Разобравшись с алгоритмом мы можем понять, почему данная техника так хорошо сочетается с HDR рендерингом. Рендеринг в HDR формате позволяет компонентам цвета выходить за верхнюю границу величиной в 1.0, что позволяет более гибко настраивать порог яркости за пределами стандартного интервала [0., 1.], обеспечивая возможностью тонко настроить какие участки сцены считать яркими. Без использования HDR придется довольствоваться порогом яркости в интервале [0., 1.], что вполне допустимо, но приводит к более «резкой» отсечке по яркости, что зачастую делает блум слишком навязчивым и кричащим (представьте себя на снежном поле высоко в горах).

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

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

Размытие по Гауссу

Урок постпроцессинга дал нам представление о размытии с использованием простого усреднения цвета соседствующих фрагментов изображения. Такой метод размытия прост, но результирующее изображение может выглядеть и привлекательней. Размытие по Гауссу основывается на одноименной кривой распределения, имеющей форму колокола: высокие значения функции располагаются ближе к центру кривой и спадают в обе стороны от него. Математически кривая Гаусса может быть выражена с разными параметрами, но общий вид кривой остается следующим:

Размытие с весовыми коэффициентами, основанными на значениях кривой Гаусса, выглядит гораздо лучше прямоугольного фильтра: за счет того, что кривая имеет бОльшую площадь в окрестности своего центра, что соответствует бОльшим весовым коэффициентам для фрагментов вблизи центра ядра фильтра. Взяв, для примера, ядро 32х32 мы будем использовать весовые коэффициенты тем меньше, чем дальше фрагмент отстоит от центрального. Именно эта характеристика фильтра и дает визуально более удовлетворяющий результат размытия по Гауссу.

Реализация фильтра потребует двумерного массива весовых коэффициентов, который можно было бы заполнить на основе двумерного же выражения, описывающего кривую Гаусса. Однако, мы тут же столкнемся с проблемой производительности: даже относительно небольшое ядро размытия в 32х32 фрагмента потребует 1024 выборок из текстуры для каждого фрагмента обрабатываемого изображения!

Читайте также:  Программа устранение цифрового неравенства список населенных пунктов

На наше счастье выражение Гауссовой кривой обладает весьма удобной математической характеристикой – сепарабельностью, которая позволит сделать из одного двумерного выражения два одномерных, описывающих горизонтальную и вертикальную составляющие. Это позволить выполнить размытие по очереди в два подхода: по горизонтали, а затем по вертикали с наборами весовых коэффициентов, соответствующими каждому из направлений. Результирующее изображение будет таким же, что и при обработке двумерным алгоритмом, но при этом потребует куда меньше вычислительной мощности видеопроцессора: вместо 1024 выборок из текстуры нам понадобятся всего лишь 32 + 32 = 64! В этом и заключается суть двупроходной фильтрации по Гауссу.

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

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

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

Создадим два буфера кадра, содержащие по одному буферу цвета на основе текстуры:

После того, как мы получим HDR текстуру сцены и извлечем текстуру ярких областей, мы заполняем буфер цвета одного из пары подготовленных фреймбуферов текстурой яркости и запускаем процесс пинг-понга десять раз (пять раз по вертикали, пять по горизонтали):

На каждой итерации мы выбираем и привязываем один из буферов кадра на основе того, будет ли эта итерация совершать размытие по горизонтали или вертикали, а буфер цвета другого фреймбуфера тогда используется как входная текстура для шейдера размытия. На первый итерации нам приходится явно использовать образ, содержащий яркие области (brightnessTexture)– иначе оба пинг-понг фреймбуфера так и останутся пустыми. После десяти проходов исходное изображение приобретает вид пятикратно размытого полным фильтром Гаусса. Использованный подход позволяет нам легко менять степень размытия: чем больше пинг-понг итераций – тем сильнее размытие.

В нашем случае итог размытия выглядит как-то так:

Для завершения эффекта остается только скомбинировать размытое изображение с исходным HDR образом сцены.

Смешение текстур

Имея под рукой HDR текстуру отрендереной сцены и размытую текстуру пересвеченных участков все что нужно для реализации знаменитого блум- эффекта или свечения – объединить эти два изображения. Итоговый фрагментный шейдер (весьма похож на присутствовавший в уроке о формате HDR) именно это и делает – аддитивно смешивает две текстуры:

На что обратить внимание: смешение осуществляется до применения тональной компрессии (tone mapping). Это позволит корректно перевести дополнительную яркость от эффекта в LDR (Low Dynamic Range) диапазон, сохранив относительное распределение яркости в сцене.

Итог обработки – все яркие участки получили заметный эффект свечения:

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

Исходный код примера – здесь.

Читайте также:  Как настроить приватность в вконтакте

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

Информация взята с сайта http://gamegpu.com/

Потребление ОЗУ игрой с различными настройками графики:

Потребление RAM всей системой во время игры с максимальными настройками графики (зависит также от количества запущенных фоновых программ):

Можно заметить, что для игры на минимальных настройках требуется ПК с 3-мя ГБ оперативной памяти, для средних настроек — с 3.5-4 ГБ, для высоких — 6 ГБ, для максимальных же настроек потребуется 8 ГБ ОЗУ и более. Конечно, перед запуском игры закройте браузеры и другие работающие программы, чтобы освободить ОЗУ. Количество памяти указано при включённом файле подкачки.

Q: у меня gtx 780ti или gtx970980 и игра тормозит на максимуме! Что за отвратительная оптимизация, раз игра тормозит на топовых видеокартах?!
A: без паники! Во-первых, текстуры максимального разрешения рассчитаны на видеокарты с памятью более 6-ти ГБ. Поэтому выберите "высокое" качество текстур. Во-вторых, обратите внимание на сглаживание, поставьте SMAA или FXAA. Скорее всего после этого лаги пропадут.

Q: у меня 2 ГБ видеопамяти и игра очень сильно тормозит. Что делать?
A: если у вас видеокарта оснащена только 2-мя ГБ памяти (например, некоторые версии gtx960), то поставьте качество текстур на "средние" и попробуйте перезапустить игру.

Q: у меня игра сильно тормозит на максимуме! Какие опции в первую очередь необходимо снизить?
A: 1) Поставьте сглаживание SMAA или FXAA. 2) Динамическую листву поставьте на средние. 3) Детализацию на "высоко" или ниже. 4) PureHair просто "ВКЛ". 5) Качество теней на "средние". 5) Если у вас видеокарта серии GTX7XX или ниже, выключите тессиляцию. 6) Качество отражений поставьте на минимум.

Q: какие опции могут испортить графику?
A: 1) "Глубина резкости" размывает изображение, некоторым может не понравится. 2) "Зернистость плёнки" добавляет шумы и артефакты на изображение. 3) "Размытие по краям" также не всем игрокам придётся по вкусу. 4) "Мягкие тени от солнца" слишком сильно размывают тени, особенно когда опция "качество теней" выбрана ниже чем "очень высоко".

Q: у меня очень слабый компьютер. Я играю на полном минимуме, но у меня есть запас мощности. Какие опции включить в первую очередь, чтобы существенно улучшить графику?
A: 1) Обязательно включите "Преграждение окружающего" 2) "Динамическую листву" поставьте на "средние". 3) "Детализацию" на "средние". 4) Включите "Отражения пространства экрана", но в последнюю очередь 5) "Качество теней" очень сильно влияют на качество графики, поэтому постарайтесь поставить тени хотя бы на "минимум", это очень важно. 6) На "качество текстур" влияет только объём видеопамяти, поэтому поставьте на "средние" или "высокие".

Q: у меня в игре fps нормальный, но в кат-сценых игра тормозит! Что делать?
A: "Pure Hair" и "глубина резкости" в длинных роликах автоматически переключаются на максимум вне зависимости от выбранных настроек, поэтому выключите соответствующие опции.

Q: у меня всего лишь 2 ГБ ОЗУ. Я не смогу поиграть в эту игру?
A: сможете! Увеличьте файл подкачки. Загрузки в игре и быстрые переходы на другие зоны у вас будут занимать 8-15 минут. Также во время перехода из одной зоны в другую игра будет подвисать на 30-40 секунд в течение нескольких минут.

Q: у меня очень старый ПК. Ну там gt440+Core 2 Duo E4400. Мне остаётся только смотреть прохождение игры на youtube?
A: нет! В это сложно поверить, но я прошёл игру именно на gt440+ Core 2 Duo E4400 (2.65 GHZ). В игре было 17-25 fps на 1280х720.

Комментировать
2 просмотров
Комментариев нет, будьте первым кто его оставит

Это интересно
Adblock detector