Моды - Euro Truck Simulator 2 :: Новости

Под капотом: объяснение SSAO


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

Jaroslav a.k.a.Cim
(один из наших храбрых и опытных программистов работает над улучшением графики)

Краткое содержание TLDR приведённого ниже текста заключается в том, что Screen Space Ambient Occlusion (SSAO) - это классная новая, но довольно тяжёлая для производительности техника для насыщения рендеринга нашего игрового мира. Вам не нужно использовать её, если вы чувствуете, что она слишком сильно снижает производительность, или же вам это наоборот может понравиться, и вы можете позволить себе пожертвовать несколько кадров в секунду для улучшенного восприятия тени и её глубины. Эффект может быть тонким, он по большому счёту работает на уровне подсознания, однако как только вы привыкнете к нему, то вам уже будет трудно вернуться к прежним настройкам. Это ещё один этап в нашем плане улучшения освещения/затенения, который мы сейчас выполняем, за которым последует новая обработка света HDR и внедрение дополнительного рельефного текстурирования поверхностей (normal mapping) в предстоящих обновлениях.

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

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

Работа наших программистов над технологиями SSAO/HBAO также потребовала изменений в нашем конвейере художественного творчества. Все 3d-модели в наших играх повторно должны были быть пересмотрены художественным отделом, и в случае, если какие-либо тени и затемнения уже были применены к модели художником, то они должны были быть изменены. Для некоторых более сложных игровых моделей это было упрощением, которое фактически уменьшило количество полигонов в них достаточно для того, чтобы повысить производительность рендеринга. В какой-то степени мы обменяли часть предварительных будущих ручных усилий, которые потребуются для построения отдельных красивых 3D-моделей, на алгоритмический проход рендеринга, который объединяет затеняющий взгляд на всю сцену, помогая "укоренить" такие объекты, как здания, фонарные столбы и растительность на местности.

Что же такое SSAO и как оно работает?

Прежде чем мы начнём разговор - обратите внимание, что SSAO - это аббревиатура от "screen space ambient occlusion". Это название охватывает все различные методы внешней окклюзии (АО) и их варианты, которые работают в пространстве экрана (это означает, что они получают всю информацию во время выполнения из данных, отображаемых на экране компьютера и в соответствующие буферы памяти). Существует SSAO (Crytech 2007 tech, которая в основном дала общее название всем методам), MSSAO, HBAO, HDAO, GTAO и многие другие методы, каждый из которых использует по-разному настроенные подходы, каждый из которых имеет свои преимущества и недостатки. Мы основали наш подход на основе метода горизонта под названием GTAO, который был представлен Activision в 2016 году.

Часть названия Ambient Occlusion (AO) означает, что мы оцениваем, какое количество входящего света (преимущественно небесного света, но иногда вычисленная окклюзия применяется и к другим источникам света) блокируется в определённом месте игрового мира. Представьте, что вы стоите на ровной поверхности - вы бы видели всё небо над головой, поэтому есть 0% окклюзии, земля полностью освещается небом. Теперь представьте, что вы находитесь на дне колодца - вы видите только небольшой участок неба, это означает, что небо закрывается почти на 100% и вносит лишь небольшой вклад в окружающее освещение в этом колодце, и естественно на дне колодца довольно темно. Определенный уровень внешней окклюзии в определённом месте влияет на вычисления освещения и создаёт затененные области в складках, отверстиях и других "сложных" местах. Он может находиться где-то между 0% и 100% в зависимости от их окружения.

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

Поэтому вместо того, чтобы запекать статическую информацию (что также заняло бы много времени и места для хранения, учитывая масштаб нашей карты), мы хотим вычислить её на лету, во время выполнения. Таким образом, мы можем вычислить его также для взаимодействия с транспортными средствами, открытия мостов, анимированных объектов и так далее. Но есть одна загвоздка. Для такого вычислительного подхода у нас есть только те данные, которые видны на экране (вспомним "screen space"), поэтому, как только какая-то часть игрового мира выходит из видимого кадра, она не может быть использована для оценки окклюзии. Это ограничение создаёт различные артефакты, такие как исчезающая окклюзия на стене, первоначально вызванная объектом, который просто попал за край экрана и таким образом стал невидимым не только для вас, но и для алгоритма, поэтому он перестал вносить вклад в вычисление окклюзии.

Отлично, теперь мы знаем, что оценивать (Ambient Occlusion), и мы знаем, какие данные у нас есть (то, что мы видим на экране). Что же нам со всем этим делать? Для каждого пикселя на экране (то есть 2 миллиона пикселей в разрешении HD, умноженное на четыре(!) в 400% масштабировании!) наш шейдерный код должен запрашивать значение z-буфера окружающих его пикселей, пытаясь получить представление о геометрической форме окружающей его области. Мы можем сделать только ограниченное количество этих "кранов", так как существует резко возрастающая стоимость производительности с увеличением количества кранов, это операция, которая действительно заставляет платить за 3D-ускоритель. Ограничение в свою очередь, влияет на качество окружения (и в определённых ситуациях может создавать неточности и прочее). Представьте себе, что вы хотите оценить своё окружение по 2-метровой прямой линии и готовы потратить 8 нажатий, чтобы приблизить его. Вы запрашиваете линию каждые 25 сантиметров, и любая деталь меньше этого может оказаться совершенно незамеченной, если вам не повезёт и вы не попадёте в неё (или не повезёт, потому что вы можете пропустить её в следующем кадре, так что окружение внезапно изменится между кадрами и вызовет мерцание). Чем дальше исследуется ваш алгоритм, тем он менее точен. Поэтому вам нужно ограничить размер области, которую вы анализируете вокруг каждого пикселя игры, что в свою очередь, ограничивает то, как далеко "видит" АО - вот почему он не подходит для вычисления окклюзии в больших пространствах, таких как например под арками моста.

Мы уже упоминали, что техника нашего выбора основана на горизонте. Это означает, что мы не исследуем окружающую среду, снимая лучи в 3D-мире, вместо этого мы анализируем полусферу над/вокруг каждого пикселя, чтобы увидеть, как далеко она открывается, пока не будет заблокирована и сколько света пропускается окружающей геометрией, используя z-буфер в качестве нашего прокси-сервера. Полусфера фактически аппроксимируется несколькими прогонами вдоль линии, вращающейся вокруг данного пикселя. Если мы можем следовать вдоль этого полушария в полном объёме, то и нет никакой окклюзии. Если алгоритм выбирает значение в z-буфере, которое блокирует входящий свет, то он определяет уровень окклюзии. Алгоритм оптимизирован для производительности, но его ограничение заключается в том, что, как только он попадает на что-либо, пусть даже на небольшой объект, то он прекращает дальнейшее исследование. Это может вызвать проблему "чрезмерной окклюзии" , которая может быть замечена как визуальный артефакт, когда какой-то относительно тонкий объект, такой как например столб дорожного знака, вызывает сильную окклюзию на соседней стене. Вы можете попытаться обнаружить такие маленькие объекты и пропустить их, что в свою очередь, может привести к «недостаточной окклюзии» на тонких выступах. Мы выбрали первое.

Существует ещё одно интересное и полезное свойство методов, основанных на горизонте. В зависимости от того, какая часть полусферы над данным пикселем закрыта, можно вычислить направление, которое меньше всего закрыто. Величину окклюзии можно представить в виде конуса мороженого с изменяющимся углом вершины, ориентированным в этом направлении. Это направление называется "изогнутой нормалью", и мы используем его для различных вычислений света, например для перекрытия отражения на блестящих поверхностях. Идея заключается в том, что если вы смотрите на поверхность и зеркально отраженное направление выходит из этого конуса, мы считаем его (по крайней мере частично) закрытым, настраивая интенсивность отражения. Лучший способ увидеть этот эффект - посмотреть на большие и круглые хромированные детали, такие как бензобаки, со включённым и выключенным SSAO.

Так что, как видите, идея не так уж сложна, во всяком случае для опытного графического программиста;), однако тут задействовано много вычислений, что создаёт нагрузку на 3D-ускоритель. Таким образом, мы создали несколько профилей производительности, каждый из которых использует сочетание методов оптимизации:

1) Использование меньшего количества нажатий в каждом направлении - это быстрее, но позволяет АО пропустить более крупные объекты, чем при более тонкой выборке.

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

3) Рендеринг в половинном разрешении - уменьшает количество вычислений до 1/4, но создаёт менее мелкий АО, результатом чего может стать слегка размытое затенение.

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