Оптимизируйте производительность вашей мобильной игры: Советы экспертов по графике и активам

THOMAS KROGH-JACOBSEN / UNITY TECHNOLOGIESSenior Technical Content Marketing Manager
Aug 3, 2021|12 Мин
Оптимизируйте производительность вашей мобильной игры: Советы экспертов по графике и активам
Эта веб-страница была переведена с помощью машинного перевода для вашего удобства. Мы не можем гарантировать точность или надежность переведенного контента. Если у вас есть вопросы о точности переведенного контента, обращайтесь к официальной английской версии веб-страницы.

Наша команда Integrated Success поддерживает клиентов Unity в решении их сложных технических проблем. Мы встретились с этой командой старших инженеров-программистов и попросили их поделиться своим опытом в оптимизации мобильных игр.

Наша команда Unity Studio Production знает исходный код наизусть и работает с множеством клиентов Unity, чтобы помочь им максимально использовать возможности движка. В своей работе они глубоко погружаются в проекты создателей, чтобы помочь выявить точки, где производительность может быть оптимизирована для большей скорости, стабильности и эффективности. Когда наши инженеры начали делиться своими знаниями об оптимизации мобильных игр, мы довольно быстро поняли, что информации слишком много для одного запланированного блога. Вместо этого мы решили превратить их гору знаний в полноценную электронную книгу (которую вы можете скачать здесь), а также в серию блогов, которые освещают некоторые из этих более чем 75 практических советов.

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

Конфигурация проекта

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

Снизьте или отключите частоту акселерометра

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

Editor
Убедитесь, что частота акселерометра отключена, если вы не используете ее в своей мобильной игре.

Отключите ненужные настройки Player или Quality

В настройках Player отключите Auto Graphics API для неподдерживаемых платформ, чтобы предотвратить создание избыточных вариантов шейдеров. Отключите Target Architectures для старых ЦП, если ваше приложение их не поддерживает.

В настройках Quality отключите ненужные уровни качества.

Отключите ненужную физику

Если ваша игра не использует физику, снимите отметки с Авто Симуляция и Авто Синхронизация Трансформов. Это просто замедлит ваше приложение без заметной пользы.

Выберите правильную частоту кадров

Мобильные проекты должны балансировать частоту кадров с временем работы от батареи и тепловым троттлингом. Вместо того, чтобы нагружать устройство на 60 fps, рассмотрите возможность работы на 30 fps в качестве компромисса. Unity по умолчанию устанавливает 30 fps для мобильных устройств.

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

Избегайте больших иерархий

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

Смотрите Оптимизация Иерархии и этот доклад Unite для лучших практик с Трансформами.

Трансформируйте один раз, а не дважды

Кроме того, при перемещении Трансформов используйте Transform.SetPositionAndRotation, чтобы обновить как позицию, так и вращение сразу. Это избегает накладных расходов на изменение трансформа дважды.

Если вам нужно Создать экземпляр GameObject во время выполнения, простая оптимизация - это установить родителя и изменить позицию во время создания:

GameObject.Instantiate(prefab, parent);

GameObject.Instantiate(prefab, parent, position, rotation);

Для получения дополнительной информации об Object.Instantiate, пожалуйста, смотрите Scripting API.

Предположим, что Vsync включен

Мобильные платформы не будут рендерить половинные кадры. Даже если вы отключите Vsync в редакторе (Project Settings > Quality), Vsync включен на аппаратном уровне. Если GPU не может обновляться достаточно быстро, текущий кадр будет удерживаться, что фактически уменьшает ваш fps.

Активы

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

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

Смотрите это руководство по лучшим практикам для художественных активов или ознакомьтесь с этим курсом по Оптимизации 3D-арта для мобильных приложений через Unity Learn для получения дополнительной информации.

Правильно импортируйте текстуры

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

  • Уменьшите максимальный размер: Используйте минимальные настройки, которые дают визуально приемлемые результаты. Это неразрушающе и может быстро уменьшить вашу память текстур.
  • Используйте степени двойки (POT): Unity требует размеры текстур в степени двойки для мобильных форматов сжатия текстур (PVRCT или ETC).
  • Атласируйте ваши текстуры: Размещение нескольких текстур в одной текстуре может уменьшить количество вызовов отрисовки и ускорить рендеринг. Используйте Unity Sprite Atlas или сторонний TexturePacker для атласирования ваших текстур.
  • Отключите опцию Read/Write Enabled: При включении эта опция создает копию как в памяти, доступной для CPU, так и для GPU, удваивая объем памяти текстуры. В большинстве случаев оставляйте это отключенным. Если вы генерируете текстуры во время выполнения, примените это через Texture2D.Apply, передав makeNoLongerReadable установленным в true.
  • Отключите ненужные Mip Maps: Mip Maps не нужны для текстур, которые остаются постоянного размера на экране, таких как 2D спрайты и графика UI (оставьте Mip Maps включенными для 3D моделей, которые изменяют расстояние до камеры).
Скриншот редактора
Правильные настройки импорта текстур помогут оптимизировать размер вашей сборки.

Сжать текстуры

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

Скриншот
Несжатые текстуры требуют больше памяти.

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

Единственные исключения:

  • игры для iOS, нацеленные на устройства A7 или ниже (например, iPhone 5, 5S и т. д.) – используйте PVRTC
  • игры для Android, нацеленные на устройства до 2016 года – используйте ETC2 (сжатие текстур Ericsson)

Если сжатые форматы, такие как PVRTC и ETC, недостаточно качественные, и если ASTC не полностью поддерживается на вашей целевой платформе, попробуйте использовать текстуры с 16 битами вместо 32 бит.

Смотрите руководство для получения дополнительной информации о рекомендуемом формате сжатия текстур по платформам.

Настройте параметры импорта сетки

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

  • Сжать сетку: Агрессивное сжатие может уменьшить занимаемое дисковое пространство (память во время выполнения, однако, не затрагивается). Обратите внимание, что квантование сетки может привести к неточностям, поэтому экспериментируйте с уровнями сжатия, чтобы увидеть, что работает для ваших моделей.
  • Отключить чтение/запись: Включение этой опции дублирует сетку в памяти, что сохраняет одну копию сетки в системной памяти и другую в памяти GPU. В большинстве случаев вы должны отключить эту опцию (в Unity 2019.2 и ранее эта опция включена по умолчанию).
  • Отключить риги и BlendShapes: Если вашей сетке не нужна скелетная анимация или анимация BlendShape, отключите эти опции, где это возможно.
  • Отключить нормали и тангенты: Если вы абсолютно уверены, что материал сетки не будет нуждаться в нормалях или тангентах, снимите отметку с этих опций для дополнительной экономии.
Скриншот редактора
Проверьте параметры импорта вашей сетки.

Проверьте количество полигонов

Модели с более высоким разрешением требуют больше памяти и потенциально более длительного времени работы GPU. Нужна ли вашей фоновой геометрии полмиллиона полигонов? Рассмотрите возможность уменьшения моделей в вашем DCC-пакете по выбору. Удалите невидимые полигоны с точки зрения камеры и используйте текстуры и нормальные карты для мелких деталей вместо высокоплотных сеток.

Автоматизируйте свои настройки импорта с помощью AssetPostprocessor

AssetPostprocessor позволяет вам запускать скрипты при импорте активов. Это побуждает вас настраивать параметры до и/или после импорта моделей, текстур, аудио и т. д.

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

Система адресуемых активов предоставляет упрощенный способ управления вашим контентом. Эта унифицированная система загружает AssetBundles по "адресу" или псевдониму, асинхронно из локального пути или удаленной сети доставки контента (CDN).

Скриншот редактора

Если вы разделите свои не кодовые активы (Модели, Текстуры, Префабы, Аудио и даже целые Сцены) на AssetBundle, вы сможете отделить их как загружаемый контент (DLC).

Затем используйте адресуемые активы, чтобы создать меньшую начальную сборку для вашего мобильного приложения. Cloud Content Delivery позволяет вам размещать и доставлять контент вашей игры игрокам по мере их продвижения в игре.

Скриншот
Загружайте активы по "адресу" с помощью системы адресуемых активов.

Нажмите здесь, чтобы увидеть, как система адресуемых активов может упростить управление активами.

Оптимизация графики и GPU

С каждым кадром Unity определяет объекты, которые необходимо отрисовать, а затем создает вызовы отрисовки. Вызов отрисовки — это вызов к графическому API для отрисовки объектов (например, треугольника), в то время как пакет — это группа вызовов отрисовки, которые будут выполнены вместе.

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

Следующие рекомендации могут помочь вам ускорить вашу графику.

Группируйте ваши вызовы отрисовки

Группировка объектов для совместной отрисовки минимизирует изменения состояния, необходимые для отрисовки каждого объекта в группе. Это приводит к улучшению производительности за счет снижения затрат ЦП на рендеринг объектов. Unity может объединять несколько объектов в меньшее количество групп, используя несколько техник:

  • Динамическая группировка: Для небольших мешей Unity может группировать и преобразовывать вершины на ЦП, а затем отрисовывать их все за один раз. Примечание. Используйте это только если у вас достаточно низкополигональных мешей (менее 900 атрибутов вершин и не более 300 вершин). Динамический группировщик не будет группировать меши больше этого, поэтому его включение будет тратить время ЦП на поиск небольших мешей для группировки на каждом кадре.
  • Статическая группировка: Для неподвижной геометрии Unity может уменьшить количество вызовов отрисовки для мешей, которые используют один и тот же материал. Хотя это более эффективно, чем динамическая группировка, оно использует больше памяти.
  • GPU инстансирование: Если у вас есть большое количество идентичных объектов, эта техника группирует их более эффективно с помощью графического оборудования.
  • SRP группировка: Включите SRP группировщик в вашем Активе универсального рендеринга в разделе Дополнительно. Это может значительно ускорить время рендеринга вашего ЦП, в зависимости от сцены.
Скриншот редактора
Организуйте ваши GameObjects, чтобы воспользоваться этими техниками группировки.

Используйте отладчик кадров

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

Editor
Дебаггер кадров разбивает каждый кадр на отдельные шаги.

Вы новичок в Дебаггере кадров? Посмотрите этот вводный учебник здесь.

Избегайте слишком большого количества динамических источников света

Крайне важно избегать добавления слишком большого количества динамических источников света в ваше мобильное приложение. Рассмотрите альтернативы, такие как пользовательские эффекты шейдеров и световые пробы для динамических мешей, а также запеченное освещение для статических мешей.

Смотрите эту таблицу сравнения функций для конкретных ограничений URP и встроенных реальных источников света.

Отключить тени

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

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

Скриншот редактора
Отключите отбрасывание теней, чтобы уменьшить количество вызовов отрисовки.

Запекайте ваше освещение в Lightmaps

Добавьте драматическое освещение к вашей статической геометрии с помощью глобального освещения (GI). Отметьте объекты с Contribute GI, чтобы вы могли хранить качественное освещение в виде Lightmaps.

Запеченные тени и освещение могут затем отображаться без потери производительности во время выполнения. Прогрессивный CPU и GPU Lightmapper могут ускорить запекание глобального освещения.

Скриншот редактора
Настройте параметры Lightmapping (Windows > Rendering > Lighting Settings) и размер Lightmap, чтобы ограничить использование памяти.

Следуйте manual guide и этой статье о оптимизации освещения, чтобы начать работу с Lightmapping в Unity.

Используйте Light Layers

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

Скриншот редактора
Слои могут ограничить влияние вашего света на конкретную маску отсечения.

Используйте Light Probes для движущихся объектов

Light Probes хранят информацию о запеченном освещении в пустом пространстве вашей сцены, обеспечивая высококачественное освещение (как прямое, так и косвенное). Они используют сферические гармоники, которые рассчитываются очень быстро по сравнению с динамическими источниками света.

Скриншот редактора
Light Probes освещают динамические объекты на заднем плане.

Используйте уровень детализации (LOD)

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

Скриншот редактора
Пример меша, использующего группу LOD.
Скриншот
Исходные меши, смоделированные с различными разрешениями.

Используйте Occlusion Culling для удаления скрытых объектов

Объекты, скрытые за другими объектами, могут по-прежнему рендериться и потреблять ресурсы. Используйте Occlusion Culling, чтобы исключить их.

Хотя отсечение фрустума вне поля зрения камеры происходит автоматически, отсечение окклюзии — это запеченный процесс. Просто отметьте ваши объекты как Статические окклюдеры или Окклюдируемые, затем запеките через диалог Window > Rendering > Occlusion Culling . Хотя это не обязательно для каждой сцены, отсечение может улучшить производительность во многих случаях.

Посмотрите Работа с Occlusion Culling учебник для получения дополнительной информации.

Избегайте мобильного родного разрешения

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

Используйте Screen.SetResolution(width, height, false), чтобы понизить разрешение вывода и вернуть некоторую производительность. Профилируйте несколько разрешений, чтобы найти лучший баланс между качеством и скоростью.

Ограничьте использование камер

Каждая камера требует некоторой вычислительной мощности, независимо от того, выполняет ли она значимую работу или нет. Используйте только компоненты камеры, необходимые для рендеринга. На мобильных платформах низкого уровня каждая камера может использовать до 1 мс времени ЦП.

Держите шейдеры простыми

Универсальный рендеринг включает несколько легковесных Lit и Unlit шейдеров, которые уже оптимизированы для мобильных платформ. Старайтесь держать количество вариаций шейдеров как можно ниже, так как они могут значительно повлиять на использование памяти во время выполнения. Если стандартные шейдеры URP не подходят для ваших нужд, вы можете настроить внешний вид ваших материалов с помощью Shader Graph. Узнайте, как визуально создавать ваши шейдеры с помощью Shader Graph здесь.

Скриншот
Создавайте пользовательские шейдеры с помощью Shader Graph.

Минимизируйте избыточную отрисовку и альфа-смешивание

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

Ограничьте эффекты постобработки

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

Скриншот редактора
Держите эффекты постобработки простыми в мобильных приложениях.

Будьте осторожны с Renderer.material

Доступ к Renderer.material в скриптах дублирует материал и возвращает ссылку на новую копию. Это нарушает любую существующую партию, которая уже включает материал. Если вы хотите получить доступ к материалу сгруппированного объекта, используйте Renderer.sharedMaterial вместо этого.

Оптимизируйте SkinnedMeshRenderers

Отрисовка скинованных мешей затратна. Убедитесь, что каждый объект, использующий SkinnedMeshRenderer, действительно требует этого. Если GameObject нуждается в анимации только время от времени, используйте функцию BakeMesh, чтобы заморозить скинованный меш в статической позе, а затем переключитесь на более простой MeshRenderer во время выполнения.

Минимизируйте отражающие пробы

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

Скачайте полный гид по оптимизации производительности мобильных устройств

Это был последний пост в блоге в серии по оптимизации производительности мобильных устройств. Тем не менее, если вы хотите получить доступ к полному списку советов и приемов от команды, мы также опубликовали 52-страничную электронную книгу, доступную здесь.

Электронная книга

СКАЧАТЬ ЭЛЕКТРОННУЮ КНИГУ

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

Не нашли то, что искали?

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