Что вы получите с этой страницы: Вторая часть нашей подборки полезных советов по оптимизации художественных активов для мобильной игры. Часть I находится здесь.
Многие другие советы по оптимизации мобильных устройств вы найдете в этой всеобъемлющей электронной книге и в этом курсе Unity Learn по Оптимизация 3D-арта для мобильных приложений.
Те же физически обоснованные освещение и материалы с консолей и ПК можно масштабировать на телефон или планшет с помощью Universal Render Pipeline (URP).
Пакетные вызовы рисования
В каждом кадре Unity определяет объекты, которые должны быть отрисованы, а затем создает вызовы рисования. Вызов рисования - это вызов графического API для рисования объектов (например, треугольника), а пакет - это группа вызовов рисования, которые должны быть выполнены вместе. Пакетирование объектов для совместного рисования минимизирует изменения состояния, необходимые для рисования каждого объекта в пакете. Это приводит к повышению производительности за счет снижения затрат процессора на рендеринг объектов.
- Динамическое дозирование: Для небольших сеток Unity может группировать и трансформировать вершины на процессоре, а затем отрисовывать их за один раз. Примечание: Используйте эту функцию только в том случае, если у вас есть достаточно низкополигональные сетки (менее 900 вершинных атрибутов и не более 300 вершин). Dynamic Batcher не будет обрабатывать сетки большего размера, чем это значение, поэтому его включение будет тратить процессорное время на поиск небольших сеток для обработки в каждом кадре.
- Статическое дозирование: Для недвижущейся геометрии Unity может сократить количество вызовов рисования для сеток, имеющих один и тот же материал. Хотя этот способ более эффективен, чем динамическое пакетирование, он использует больше памяти.
- Инстансирование GPU: Если у вас есть большое количество одинаковых объектов, эта техника объединяет их в группы более эффективно за счет использования графического оборудования.
Дозирование SRP: Включите SRP Batcher в активе URP в разделе "Дополнительно". Это может значительно ускорить рендеринг на процессоре, в зависимости от сцены.
Очень важно не добавлять в мобильное приложение слишком много динамических индикаторов. Рассмотрите такие альтернативы, как пользовательские шейдерные эффекты и световые зонды для динамических сеток, а также запеченное освещение для статических сеток.
Ознакомьтесь с этой таблицей сравнения характеристик, чтобы узнать о специфических ограничениях URP и Built-In Render Pipeline в режиме реального времени.
Отбрасывание теней может быть отключено для каждого MeshRenderer и света. Отключите тени, когда это возможно, чтобы уменьшить количество вызовов рисования.
Вы также можете создать фальшивые тени с помощью размытой текстуры, наложенной на простую сетку или квадрат под персонажами. В противном случае вы можете создавать тени от блобов с помощью пользовательских шейдеров.
Добавьте эффектное освещение к статичной геометрии с помощью глобального освещения (Global Illumination, GI). Разметьте объекты с помощью Contribute GI, чтобы сохранить высококачественное освещение в виде лайтмапов.
Запеченные тени и освещение могут рендериться без снижения производительности во время выполнения. Прогрессивный CPU и GPU Lightmapper позволяет ускорить процесс запекания Global Illumination.
Чтобы начать работу с лайтмэппингом в Unity, следуйте руководству и этой статье об оптимизации света.
Для сложных сцен с несколькими источниками света разделите объекты с помощью слоев, а затем ограничьте влияние каждого света определенной маской обтравки.
Световые зонды хранят информацию о пустом пространстве сцены, обеспечивая высококачественное освещение (как прямое, так и косвенное). Они используют сферическую гармонику, которая быстро вычисляется по сравнению с динамическим освещением.
Пробник отражения позволяет создавать реалистичные отражения, но может быть очень дорогостоящим в плане партий. Используйте кубические карты низкого разрешения, маски обтравки и сжатие текстур для повышения производительности во время выполнения.
Рендеринг объекта с прозрачностью всегда использует больше ресурсов GPU, чем рендеринг непрозрачного объекта, особенно когда прозрачные объекты рендерятся друг на друга несколько раз - процесс, известный как overdraw. Хорошей практикой является использование непрозрачного материала, когда это возможно, особенно для мобильных платформ. Вы можете проверить перерисовку с помощью графического отладчика RenderDoc.
Используйте максимально простой шейдер (например, шейдер без подсветки) и избегайте использования ненужных функций. Используйте готовые шейдеры Unity, разработанные специально для таких систем, как частицы. URP включает в себя несколько облегченных шейдеров Lit и Unlit, которые уже оптимизированы для мобильных платформ. Чтобы минимизировать перерисовку, уменьшите количество и/или размер частиц в вашей игре.
Для повышения производительности используйте материалы Unlit Opaque с половинной точностью, когда это возможно, и помните о сложных операциях в узлах. Дополнительные советы вы найдете в этой сессии по Shader Graph.
При создании шейдера вы можете решить, как материал будет реагировать на свет. Большинство шейдеров классифицируются как освещенные или неосвещенные. Неосвещенный шейдер - самая быстрая и дешевая в вычислительном отношении модель затенения. Используйте его, если вы нацелены на устройства низшего ценового диапазона.
Ключевые моменты, которые необходимо учитывать, включают:
- Освещение не влияет на неосвещенную модель затенения. Это означает, что многие расчеты, например, расчеты спекулярности, не нужны. В результате рендеринг становится либо дешевле, либо быстрее.
- Использование стилизованного художественного направления, напоминающего мультфильм, хорошо сочетается с неосвещенными тенями. Этот стиль стоит учитывать, если вы разрабатываете игры для мобильных платформ.
Вершинные шейдеры работают с каждой вершиной, а пиксельные (или фрагментные) шейдеры - с каждым пикселем. Обычно пикселей, которые выводятся на экран, больше, чем вершин на экране. Это означает, что пиксельный шейдер запускается чаще, чем вершинный. В связи с этим мы рекомендуем по возможности переносить вычисления из пиксельного шейдера в вершинный шейдер. Как обычно, после работы над оптимизацией необходимо провести дальнейшее профилирование, чтобы определить лучшее решение для конкретной ситуации.
Основные операции, такие как сложение и умножение, обрабатываются быстрее. Лучше всего, чтобы количество медленных математических операций было как можно меньше. На старых устройствах, например, использующих GLES 2.0, количество сложных математических вычислений должно быть меньше.
При включении SRP Batcher следите за окном статистики и графиком вершин секции рендеринга в представлении Profiler. Помимо повышения FPS, значительно уменьшается количество обрабатываемых треугольников и вершин. Поскольку наши объекты используют шейдер, совместимый с URP, конвейер рендеринга автоматически группирует все соответствующие геометрические данные, чтобы уменьшить объем обрабатываемых данных.
По умолчанию Unity импортирует анимированные модели с Generic Rig, но разработчики часто переходят на Humanoid Rig при анимации персонажа. Гуманоидная рига потребляет на 30-50 % больше процессорного времени, чем аналогичная общая рига, поскольку она рассчитывает инверсную кинематику и ретаргетинг анимации для каждого кадра.
Рендеринг сетки с кожей требует больших затрат. Убедитесь, что каждый объект, использующий SkinnedMeshRenderer, требует его наличия. Если игровой объект нуждается в анимации лишь иногда, используйте функцию BakeMesh, чтобы заморозить обтянутую сетку в статичной позе, а затем переключитесь на более простой MeshRenderer во время выполнения.
Система Mecanim в Unity, предназначенная в первую очередь для гуманоидных персонажей, довольно сложна, но часто используется для анимации отдельных значений (например, альфа-канала элемента пользовательского интерфейса). Избегайте чрезмерного использования аниматоров. Особенно при работе с элементами пользовательского интерфейса, рассмотрите возможность создания функций переключения или использования сторонних библиотек для простой анимации (например, DOTween или LeanTween).
Работайте в рамках определенного бюджета времени на кадр
Каждый кадр будет иметь временной бюджет, основанный на целевой частоте кадров в секунду (fps). В идеале приложение, работающее со скоростью 30 кадров в секунду, должно обеспечивать примерно 33,33 мс на кадр (1000 мс / 30 кадров в секунду). Аналогично, цель 60 кадров в секунду оставляет 16,66 мс на кадр.
Устройства могут превышать этот бюджет в течение коротких периодов времени (например, во время cutscenes или загрузочных последовательностей), но не в течение длительного времени.
Пресеты
Не полагайтесь на настройки по умолчанию. Используйте вкладку переопределения для конкретной платформы, чтобы оптимизировать такие активы, как текстуры и геометрию сетки. Неправильные настройки могут привести к увеличению размера сборки, увеличению времени сборки и неэффективному использованию памяти. Используйте функцию Presets, чтобы настроить базовые параметры, которые улучшат конкретный проект.
Ограничьте использование камер
Каждая камера несет определенные накладные расходы, независимо от того, выполняет она значимую работу или нет. Используйте только компоненты камеры, необходимые для рендеринга. На мобильных платформах низшего класса каждая камера может использовать до 1 мс процессорного времени.
Избегайте полноэкранных эффектов
Полноэкранный режим Эффекты постобработки, такие как свечение, могут значительно снизить производительность. С осторожностью используйте их в художественном оформлении названия.
Будьте осторожны с Renderer.material
Обращение к Renderer.material в скриптах дублирует материал и возвращает ссылку на новую копию. Это разрушает все существующие партии, в которые уже включен материал. Если вы хотите получить доступ к материалу пакетного объекта, используйте Renderer.sharedMaterial.