Как происходит рендеринг кадра A Plague Tale: Innocence

в 8:25, , рубрики: nsight graphics, Дизайн игр, игровые движки, конвейер рендеринга, Работа с 3D-графикой, разработка игр, рендеринг графики, трёхмерная графика
Как происходит рендеринг кадра A Plague Tale: Innocence - 1

Предисловие

Как и в других моих исследованиях, давайте начнём с введения. Сегодня мы рассмотрим последнюю игру французского разработчика Asobo Studio. Впервые я увидел видео этой игры в прошлом году, когда коллега поделился со мной 16-минутным геймплейным трейлером. Моё внимание привлекла механика «крысы против света», но мне не особо захотелось играть в эту игру. Однако после её выхода многие стали говорить, что она выглядит так, как будто сделана на движке Unreal, но это не так. Мне стало любопытно увидеть, как работает рендеринг и насколько вообще разработчики вдохновлялись Unreal. Ещё меня заинтересовал процесс рендеринга стаи крыс, потому то в игре она выглядела очень убедительно и к тому же является одним из ключевых элементов геймплея.

Когда я начал попытки выполнить захват игры, то подумал, что придётся сдаться, потому что ничего не срабатывало. Хотя игра использует DX11, который сейчас поддерживают практически все инструменты анализа, мне не удалось заставить работать ни один из них. Когда я пытался использовать RenderDoc, игра вылетала при запуске, и то же самое происходило с PIX. Я по-прежнему не знаю, почему так происходит, но к счастью, мне удалось выполнить несколько захватов с помощью NSight Graphics. Как обычно, я поднял все параметры до максимальных и начал искать подходящие для анализа кадры.

Разбивка кадра

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

Как обычно, давайте начнём с окончательного кадра:

Как происходит рендеринг кадра A Plague Tale: Innocence - 2

Первым, что я заметил, был совершенно иной баланс в этой игре событий рендеринга по сравнению с тем, что я видел в других играх ранее. Здесь множество вызовов отрисовки, что нормально, но на удивление лишь немногие из них используются для постобработки. В других играх после рендеринга цветов для получения окончательного результата кадр проходит ещё много этапов, но в A Plague Tale: Innocence стек постобработки очень мал и оптимизирован всего до нескольких событий отрисовки/вычислений.

Игра начинает построение кадра с рендеринга GBuffer с шестью render targets. Интересно, что это все render targets имеют 32-битный беззнаковый целочисленный формат (за исключением одного) вместо цветов RGBA8 или других специфичных для таких данных форматов. Это представляло сложность, потому что мне приходилось декодировать каждый канал вручную с помощью функции Custom Shader из NSight. Я потратил много времени на выяснение того, какие значения закодированы в 32-битные targets, но не исключено, что всё равно что-то упустил.

Как происходит рендеринг кадра A Plague Tale: Innocence - 3

GBuffer 0

Первый target содержит в 24 битах некие значения шейдинга, а в 8 битах — какие-то другие значения для волос.

Как происходит рендеринг кадра A Plague Tale: Innocence - 4

GBuffer 1

Второй target выглядит как традиционный RGBA8-target с разными значениями управления материалом в каждом канале. Насколько я понимаю, красный канал — это metalness (не совсем понятно, почему ею помечены некоторые листья), зелёный канал выглядит как значение roughness, а синий канал — это маска главного персонажа. Ни в одном из сделанных мной захватов альфа-канал не использовался.

Как происходит рендеринг кадра A Plague Tale: Innocence - 5

GBuffer 2

Третий target тоже выглядит как RGBA8 с albedo в каналах RGB, а альфа-канал в каждом сделанном мной захвате был полностью белым, так что я не совсем понимаю, что эти данные должны делать.

Как происходит рендеринг кадра A Plague Tale: Innocence - 6

GBuffer3

Четвёртый target любопытен, потому что на всех моих захватах почти полностью чёрный. Значения выглядят как маска части растительности и всех волос/меха. Возможно, это как-то связано с просвечиванием (translucency).

Как происходит рендеринг кадра A Plague Tale: Innocence - 7

GBuffer 4

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

Как происходит рендеринг кадра A Plague Tale: Innocence - 8

Глубина из GBuffer 5

Как происходит рендеринг кадра A Plague Tale: Innocence - 9

Маска из GBuffer 5

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

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

Как происходит рендеринг кадра A Plague Tale: Innocence - 10

Сумеречные лучи

После завершения карт теней можно вычислить освещение, но прежде в отдельный target рендерятся сумеречные лучи (god rays).

Как происходит рендеринг кадра A Plague Tale: Innocence - 11

SSAO

На этапе вычисления освещения выполняется вычислительный шейдер для расчёта SSAO.

Как происходит рендеринг кадра A Plague Tale: Innocence - 12

Освещённая непрозрачная геометрия

Освещение добавляется из кубических карт и локальных источников освещения. Все эти разные источники освещения в сочетании с отрендеренными выше targets в результате формируют освещённое HDR-изображение.

Как происходит рендеринг кадра A Plague Tale: Innocence - 13

Элементы, отрисовываемые упреждающим рендерингом

Отрисовываемые упреждающим рендерингом элементы добавляются поверх освещённой непрозрачной геометрии, но в этой сцене они не особо заметны.

После накопления всего цвета мы почти закончили, осталось только несколько операций постобработки и UI.

Как происходит рендеринг кадра A Plague Tale: Innocence - 14

Разрешение цвета снижается в вычислительном шейдере, а затем увеличивается для создания очень красивого и мягкого эффекта bloom.

Как происходит рендеринг кадра A Plague Tale: Innocence - 15

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

Стоит упомянуть пару интересных вещей, касающихся рендеринга:

  • Instancing (дублирование геометрии) используется только для отдельных мешей (похоже, что только для растительности). Все другие объекты рендерятся в отдельных вызовах отрисовки.
  • Похоже, объекты приблизительно сортируются спереди назад, за некоторыми исключениями.
  • Кажется, разработчики не прикладывали никаких усилий для группирования вызовов отрисовки с точки зрения параметров материалов.

Крысы

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

Как происходит рендеринг кадра A Plague Tale: Innocence - 16

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

Как происходит рендеринг кадра A Plague Tale: Innocence - 17

LOD0

Как происходит рендеринг кадра A Plague Tale: Innocence - 18

LOD1

Как происходит рендеринг кадра A Plague Tale: Innocence - 19

LOD2

Как происходит рендеринг кадра A Plague Tale: Innocence - 20

LOD3

У крыс есть 4 уровня LOD. Интересно, что на третьем уровне хвост загнут к телу, а у четвёртого хвоста вовсе нет. Вероятно это означает, что анимации активны только для первых двух уровней. К сожалению, у NSight Graphics, похоже, не хватает инструментов, чтобы это проверить.

Как происходит рендеринг кадра A Plague Tale: Innocence - 21

Без дублирования (instancing) крыс.

Как происходит рендеринг кадра A Plague Tale: Innocence - 22

С дублированием.

Как происходит рендеринг кадра A Plague Tale: Innocence - 23

В сцене, захват которой показан выше, отрендерено следующее количество крыс:

  • LOD0 – 200
  • LOD1 – 200
  • LOD2 – 1258
  • LOD3 – 3500 (с дублированием геометрии)

Это даёт нам понять, что существует жёсткое ограничение на количество крыс, которых можно отрендерить на первых двух LOD.

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

В заключение

Plague Tale: Innocence очень интересна с точки зрения рендеринга. Его результаты без сомнений меня впечатлили, они очень хорошо служат геймплею. Как и в случае с любым проприетарным движком, было бы здорово услышать более подробный анализ из уст самих разработчиков, особенно потому, что мне не удалось подтвердить некоторые из моих теорий. Надеюсь, моя статья когда-нибудь доберётся до кого-нибудь из Asobo Studio и они увидят, что у людей есть к этому интерес.

Автор: PatientZero

Источник


* - обязательные к заполнению поля