Games

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

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

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

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

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

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

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

Уменьшить или отключить частоту акселерометра

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

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

Отключите ненужные настройки проигрывателя или качества

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

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

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

Если ваша игра не использует физику, снимите флажки Auto Simulation и Auto Sync Transforms. Они просто замедлят работу вашего приложения без какой-либо ощутимой пользы.

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

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

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

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

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

О лучших практиках работы с трансформациями читайте в разделе "Оптимизация иерархии" и в этом выступлении Unite.

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

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

Если вам нужно инстанцировать GameObjects во время выполнения, простой оптимизацией будет родительское и повторное размещение во время инстанцирования:

GameObject.Instantiate(prefab, parent);

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

Более подробную информацию о Object.Instantiate можно найти в разделе Scripting API.

Предположим, что функция Vsync включена

Мобильные платформы не отображают полукадры. Даже если вы отключите Vsync в редакторе(Настройки проекта > Качество), Vsync будет включен на аппаратном уровне. Если графический процессор не может обновляться достаточно быстро, текущий кадр будет удерживаться, эффективно снижая ваш FPS.

Активы

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

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

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

Корректный импорт текстур

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

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

Сжатие текстур

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

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

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

Исключение составляют:

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

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

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

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

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

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

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

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

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

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

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

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

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

Если вы разделите свои некодовые активы (модели, текстуры, префабы, аудио и даже целые сцены) в AssetBundle, вы сможете выделить их в качестве загружаемого контента (DLC).

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

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

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

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

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

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

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

Пакетные вызовы рисования

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

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

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

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

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

Новичок в отладчике фреймов? Ознакомьтесь с этим вводным руководством здесь.

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

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

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

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

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

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

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

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

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

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

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

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

Используйте легкие слои

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

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

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

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

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

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

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

Скриншот редактора
Пример сетки с использованием LOD Group.
Скриншот
Исходные сетки, смоделированные с разным разрешением.

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

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

В то время как обрезка фрагментов за пределами обзора камеры происходит автоматически, обрезка окклюзии - это запекаемый процесс. Просто пометьте объекты как Static Occluders или Occludees, а затем запеките их через диалог Window > Rendering > 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, требует его наличия. Если GameObjects нуждается в анимации лишь иногда, используйте функцию BakeMesh, чтобы заморозить сетку со скинами в статичной позе, а затем переключитесь на более простой MeshRenderer во время выполнения.

Минимизация отражения зондов

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

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

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

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

DOWNLOAD E-BOOK

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

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

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