Проблемы С Производительностью В Xcom 2

Привет! Меня зовут Александр, я руководитель отдела программистов компьютерной графики в Gaijin в проектах.

CRSED И Зачислен .

Иногда в свободное время я изучаю, как работает графика в других играх, и нахожу там что-то интересное.

Недавно я решил разобраться, почему на моем ноутбуке тормозит XCOM 2. Изучая рендеринг этой игры, я нашел ряд мест, которые можно было ускорить без проблем.

Результатом моего небольшого исследования стало видео: Ниже представлена расшифровка этого видео.




Добрый день Вы наверняка играли в игру XCOM 2 или хотя бы слышали о ней.

Выпущен в 2016 году.

Сделан на Unreal Engine 3.5. Если оценивать XCOM как игру в целом, то она мне понравилась.

Увлекательный геймплей, приятная картинка, интересный сюжет. Единственная проблема, с которой я столкнулся, — это низкий FPS, особенно при съемке крупным планом.

В базовой и тактической форме эта проблема менее заметна.

Средний FPS у меня был около 25-30. И мне было интересно, выжимает ли игра всю доступную мощность из моего ноутбука с GTX 1050 или можно ли это сделать лучше.

Сейчас я покажу вам 6 оптимизаций, которые могут помочь разработчикам улучшить производительность этой игры.



Захват кадра

Для анализа графики я использовал RenderDoc версии 1.12. Он без проблем сделал несколько кадров, которые я позже просмотрел.

Я взял один кадр из меню, кадр из базы, кадр из тактической карты и кадр кадра.



Проблемы с производительностью в XCOM 2

У них всех есть общие проблемы с производительностью.

Проходы, которые вы видите здесь (скриншот ниже), представляют собой последовательные вызовы отрисовки, для которых установлены одни и те же цели рендеринга, то есть текстуры, в которые рисуется результат.

«Жирный» G-буфер

Первая оптимизация предполагает уменьшение размера G-буфера.

Самый длинный проход — заполнение G-буфера (> 16 мс).

Это видно как по таймингам различных проходов, так и по общей хронологии.



Проблемы с производительностью в XCOM 2

Всего в G-буфер входит 5 текстур в формате RGBA16F, то есть текстуры имеют 4 16-битных канала и содержат вещественные числа.

Разрешение 1080 требует для всего этого около 80 МБ видеопамяти, что не так уж и много для современных видеокарт, но проблема в том, что все эти текстуры необходимо заполнить.

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

Итак, G-буфер содержит следующие текстуры:

  1. Цвета излучающих (то есть светящихся) материалов (и альфа-канал этой текстуры пуст).

  2. Альбедо или просто цвет без учета освещения (альфа-канал содержит Ambient Occlusion).

  3. Нормали (альфа-канал хранит номер одного из 4-х материалов)
  4. Параметры материала (цвет металла + шероховатость).

  5. Дополнительные нормали для анизотропных материалов (прозрачность в альфа-канале — параметр, показывающий, насколько поверхность пропускает свет через себя)


Проблемы с производительностью в XCOM 2

Четвертый канал можно было бы удалить из излучающей текстуры.

И таким образом вместо 16 МБ потребуется 12 МБ.

Текстуру альбедо можно легко сохранить в виде 4 8-битных каналов с нормализованными действительными числами (то есть числами от 0 до 1).

Это уменьшит эту текстуру в 2 раза.

До 8 МБ.

Нормали хранятся в необработанном виде.

Вы можете упаковывать их при записи, тем самым уменьшая объем данных, и распаковывать при чтении.

[Вы можете прочитать больше здесь] .

Это, конечно, требует больше времени на выполнение кода, но существенно уменьшает объем требуемых данных.

Материал принимает всего 4 разных значения, а значит отлично упаковывается в 2 бита.

Предположим, что мы поместили эти два бита в параметры материала.

Тогда для нормалей есть 2 канала по 16 бит каждый.

Всего 8 МБ для моего разрешения экрана.

Параметры материала оставим без изменений, за исключением кодирования номера материала в ту же текстуру.

Последняя текстура — это параметры полупрозрачных материалов.

Первые три компонента являются единичными векторами, что означает, что их также можно закодировать в два действительных числа.

Осталось 3 канала.

Кроме того, полупрозрачные материалы не излучают свет. По крайней мере, на отснятых кадрах я этого не увидел.

Это означает, что мы можем объединить эту текстуру с излучающей текстурой и теперь тратим на это 0 МБ.

Всего нам понадобится 12 МБ для излучательных и полупрозрачных, 8 МБ для диффузных, 8 МБ для нормалей и 16 для параметров материала.

Итого 44 Мб.

Почти половина памяти.

Думаю это сильно ускорило бы прохождение заполнения G-буфера.



Отсутствующие объекты в предварительном проходе

Другая оптимизация, которая может уменьшить объем данных, записываемых в G-буфер, — это использование более агрессивного предварительного прохода.

Prepass — это предварительный рендеринг сцены в буфер глубины.

Это выполняется для того, чтобы уменьшить количество перезаписей пикселей G-буфера за счет отбрасывания пикселей, не прошедших тест глубины.

Текущий предварительный проход оптимизирует рендеринг, но можно достичь лучших результатов.

При записи G-буфера некоторые пиксели перерисовываются до 24 раз.



Проблемы с производительностью в XCOM 2

Судя по вызовам драйвера, между препассом и проходом G-буфера нет копий текстуры глубины или чтения этой текстуры на ЦП.

Это означает, что теоретически вся геометрия, нарисованная в G-буфере, может быть нарисована на предварительном проходе.

Таким образом, это можно сделать еще быстрее.

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



Создание экземпляра не используется

Оставим пиксельную оптимизацию и обратимся к геометрии.

Как вы могли заметить (обратите внимание на вызовы DrawIndexed на предыдущем снимке экрана), объекты рисуются строго по одному.

Это связано с тем, что при рисовании используется вызов DrawIndexed вместо вызова DrawIndexedInstanced, который позволяет рисовать несколько одинаковых объектов одновременно.

И здесь много одинаковых объектов.

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

Уже одно это могло дать прирост FPS.

Уровень детализации

И последняя оптимизация, связанная с отрисовкой сцены, — это система уровня детализации.

Нет смысла рисовать детальную геометрию, если она находится далеко и занимает пару десятков пикселей.

Во-первых, субпиксельные треугольники замедляют рендеринг.

Подробнее вы можете прочитать в Эта статья .

Во-вторых, это не имеет практического смысла.

Например, из почти тысячи треугольников этого объекта мы увидим лишь пару десятков.



Проблемы с производительностью в XCOM 2

Использование менее детализированной геометрии может значительно сократить количество рисуемых треугольников.

Естественно, это ускорит рендеринг.



Полноэкранный SSAO (экранное пространство Ambient Occlusion)

Второй по продолжительности проход после заполнения G-буфера — подготовка текстуры SSAO. Это занимает от 8 до 10 мс.

И проблема этого отрывка в том, что он на весь экран.



Проблемы с производительностью в XCOM 2

Как я сказал в прямом эфире GTAO , такие эффекты лучше всего делать при половинном разрешении экрана.

От профессионалов Activision Blizzard удалось уместить AO-рендеринг в полмиллисекунды .

Измеряли на PlayStation 4, а я мерил на ноутбуке, и сравнивать времена таким образом не совсем корректно.

Однако отмечу, что у моей видеокарты в 2,5 раза меньше GFLOPS, а расчет АО в игре идет в 20 раз медленнее, чем в статье от Blizzard. В целом, думаю, можно сделать вывод, что полноэкранный проход по АО можно значительно ускорить.



Глубина резкости

И последнее очевидное узкое место — это глубина резкости.

XCOM использует очень интересный подход к этому вопросу.

Нарисовано 3 миллиона треугольников.

Каждый из них соответствует пикселю текстуры при половине разрешения экрана.



Проблемы с производительностью в XCOM 2

В зависимости от глубины, соответствующей пикселю, выбирается положение треугольника.

Треугольник рисуется слева или справа от конечной текстуры.

Таким образом, исходное изображение делится на две по глубине.

Огромное количество субпиксельных треугольников, скорее всего, является причиной того, что этот вызов отрисовки занимает много времени.

Проблема в том, что для треугольника, покрывающего только один пиксель, шейдер выполняется на 4 пикселях.

Кому интересны подробности, рекомендую прочитать еще раз.

Эта статья .

Чтобы ускорить этот алгоритм, можно использовать компьютерный шейдер.

Тогда для каждого текселя шейдер будет выполняться один раз.

Теги: #Разработка игр #оптимизации #XCOM #Компьютерная графика

Вместе с данным постом часто просматривают: