Оптимизируем мидкор: повышаем FPS с помощью SRP Batcher

В мидкоре особенно важно найти оптимальный баланс между красочной картинкой и высокой производительностью. Уже не раз об этом говорили, а сегодня вспомним про SRP Batcher. С его помощью можно не только рендерить объекты в 2-4 раза быстрее, но и добиться снижения общей нагрузки на мобильное устройство.

Далее кратко поделюсь опытом использования SRP Batcher при создании карт для мидкорных проектов. 

Отличия SRP от Legacy Render Pipeline

Legacy Render Pipeline — это стандартный пайплайн движка Unity, который используется для отрисовки графики. Он дает ограниченные возможности настройки и оптимизации рендера, а это напрямую влияет на производительность. Пока еще Unity его поддерживает, но уже настоятельно рекомендует переходить на SRP. Для мобильных устройств есть свой шаблон URP, а для ПК — HDRP, но можно и написать свой рендер-пайплайн с нуля. 

Scriptable Render Pipeline, он же SRP, предлагает новый более гибкий подход к  рендерингу и его кастомизации. С ним можно создавать собственные кастомизированные пайплайны, исходя из потребностей проектов, снизить количество вызовов отрисовки (draw call) и получить другие преимущества для более скоростного рендеринга. 

Как это работает

Вкратце: SRP помогает улучшить производительность игры. Он батчит (т.е. объединяет) множество мелких объектов использующих один и тот же шейдер, в один большой объект перед их отрисовкой на экране — это помогает снизить время взаимодействия между CPU и GPU.

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

Как это работает технически: 

1) Анализ сцены. SRP Batcher пробегается по сцене в поисках объектов, которые используют одинаковый шейдер и плюс-минус одинаковые характеристики материалов. 

2) Группирование объектов. Найденные объекты группируются исходя из схожести их характеристик. В первую очередь объединяются те, что используют один и тот же шейдер. 

3) Создание SRP-батча. Сгруппированные объекты объединяются в один большой объект — SRP-батч. 

4) Отрисовка батчей. После создания батчей, SRP передает их на рендеринг, где происходит отображение объектов на экране. Объекты внутри батча рисуются за один вызов рендера (draw call), что существенно сокращает количество операций рендеринга и улучшает производительность. 

5) Обновление батчей. В процессе игры, сцена естественно может меняться — SRP батчер следит за этими изменениями и по необходимости обновляет батчи. Т.е. если какой-то камешек был изменен или перенесён, то происходит пересчитывание батчей.

Источник

Важный поинт.

Чтобы SRP Batcher сработал, ваш шейдер должен быть совместим с SRP.  Т.е. кликнув на шейдер в окне инспектора у вас должно быть так:

Эта совместимость нивелируется использованием Shader Graph, либо руками, используя макросы CBUFFER_START(UnityPerMaterial) и CBUFFER_END. 

Tags {"RenderPipeline" = "UniversalPipeline"
   "RenderType" = "Opaque"
   "Queue" = "Geometry"}
HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

CBUFFER_START(UnityPerMaterial)
float4 _BaseMap_ST;
float4 _BaseColor;
CBUFFER_END
ENDHLSL

В Railroad Empire SRP Batcher берет на себя все деревья вместе с камушками. Вот наглядный пример профайлинга его работы:

Почти все деревья на заднем плане сшиты в один объект и вызываются на отрисовке один раз, а не 125. 

Безусловно, есть нюансы. Несколько источников света или, если использовать не один текстурный атлас на деревья в купе с затайленой по world_UV маской для цветов на ВЕСЬ лес, а 30 уникальных материалов, то картина кратно поменяется в худшую сторону. В таком случае SRP Batcher не спасет и ждать какого-то сильного прироста FPS не стоит. Как всегда, каждый проект уникален и требует свой стэк инструментов оптимизации. 

SRP Batcher — интересный и полезный инструмент для оптимизации, снижающий время коммуникаций между CPU и GPU. Его однозначно стоит использовать в пайплайне разработки. Но, как это обычно и бывает, нельзя надеяться, что один инструмент решит все ваши проблемы. По-прежнему придется уделять большое внимание архитектуре сборки контента на движке. 

Вернуться в блог