Практическое руководство по оптимизации для мобильных
Это руководство предназначено для новичков в мобильном геймдеве. Для тех, кто испытывает трудности при планировании и прототипировании новой мобильной игры (или портировании уже существующего проекта). Также этот раздел будет полезен в качестве справки для каждого, кто делает мобильные или браузерные игры (с целевой платформой — старые ПК или нетбуки).
Оптимизация вообще широкая тема, и то как вы ее сделаете, целиком зависит от вашей игры, поэтому данное руководство следует рассматривать как некое введение или ссылку, а не пошаговое руководство.
Мобильные устройства не созданы одинаковыми
Информация здесь предполагает аппаратное обеспечение на уровне чипсета Apple A4, который используется в оригинальных iPad, iPhone 3GS и третьем поколении iPod Touch. Из Android предполагается устройство подобное Nexus One, или большинства устройств, работающих на Android 2.3 Gingerbread. В основном, эти устройства были выпущены в начале 2010 года. Эти устройства старее, медленнее современных, но так как они составляют большую часть рынка, их также следует поддерживать.
Есть очень быстрые и очень медленные телефоны. Вычислительные мощности мобильных устройств растут с потрясающей скоростью. Для нового поколения мобильной GPU, быть в 5 раз быстрее своего предшественника — обычное дело. Скорость мобильных устройств уже сравнима со скоростью ПК.
Для обзора технических характеристик мобильных устройств от Apple, см. Hardware.
Если вы хотите разрабатывать под мобильные устройсва, которые станут известными в будущем, или эксклюзивные high end устройства прямо сейчас, вы можете это сделать. См. Мобильные устройства будущего.
Очень низкая производительность (например, iPhone 3G или первое и второе поколение iPod touches) требует особого внимания к оптимизации. В противном случае могут возникнуть проблемы когда покупатели, не обновившие устройства, будут покупать ваши приложения. Если же вы делаете бесплатное приложение, можно не беспокоится о поддержке старых устройств.
Оптимизацию не следует считать последней стадией разработки проекта
Британский ученый Майкл А. Джексон часто цитируется своими Правилами оптимизации программ:
_Первое правило оптимизации программы: не делаете ее. Второе правило оптимизации программы (только для экспертов!): не делайте ее пока что.
Он обосновал это тем, что учитывая рост скорости компьютеров, ваша программа будет достаточно быстрой. Кроме того, если вы попытаетесь слишком много оптимизировать, то сильно усложните код, ограничите себя и создадите много ошибок.
Однако, если вы разрабатываете мобильные игры, есть еще одно мнение: аппаратное обеспечение, представленное сейчас на рынке, сильно ограничено по сравнению с компьютерами, которые мы используем для работы. Поэтому высок риск того, что ваша ваша игра не будет работать на большинстве устройств и оптимизацию рекомендуют делать с самого начала разработки.
В данном руководстве мы постараемся указать ситуации, когда оптимизация сыграет большую роль в производительности, по сравнению с обратными ситуациями, когда оптимизация большого значения не имеет.
Оптимизация: Не только для программистов
Художникам тоже полезно знать ограничения платформы и методы, которые используются для того, чтобы их обойти. Зная это, они могут принимать креативные решения, которые в итоге сэкономят их труд.
- На художника ложится большая ответственность. Если дизайн игры предполагает атмосферность и освещение, их можно нарисовать в текстурах вместо запекания.
- Каждый раз, когда что-либо может быть запечено, художники могут готовить контент для выпекания, вместо рендеринга в реальном времени. Это позволяет им игнорировать технические ограничения и работать свободно.
Планируйте игру так, чтобы во время исполнения она работала “плавно”.
Эти две страницы детально описывают основные тенденции в игровой производительности и объясняют, как лучше спланировать оптимизацию своей игры или как интуитивно выявить места, нуждающиеся в оптимизации (в случае, если игра уже вышла в продакшн).
- Практические методы для оптимизации рендеринга
- Практические методы для оптимизации скриптинга и геймплея
Профилируйте на ранней стадии и почаще
Профилирование важно, потому что оно поможет выяснить, какие оптимизации действительно приведут к большому приросту производительности, а какие являются пустой тратой вашего времени. Благодаря тому, что рендеринг обрабатывается на отдельном чипе (GPU), отрисовка одного кадра занимает в два раза меньше времени (только GPU, а не CPU + GPU). Это означает, что если CPU замедляет работу, оптимизация ваших шейдеров вообще не повысит частоту кадров, и если GPU замедляет работу, не помогут оптимизация физики и скриптов.
Часто бывает так, что разные части игры и разные ситуации работают по разному, так что одна часть игры может привести к 100 миллисекундным кадрам полностью из скрипта, а другая может привести в замедлению игры, потому что в данный момент что нибудь рендерится. Поэтому, если вы собираетесь оптимизировать свою игру, нужно по крайней мере выявить узкие места.
Внутренний Профайлер
Профайлер в Unity в основном используется при ориентации на iOS и Android. См. Руководство по профайлеру для основных инструкций по его использованию.
Внутренний Профайлер
Внутренний профайлер выкидывает текст каждые 30 кадров. Это поможет вам выяснить, какие аспекты вашей игры замедляют ее, будь то физика, скрипты, визуализация, но без множества деталей (например, только название скрипта или визуализации).
См. Встроенный Профайлер для подробной информации о том, как это работает и включается.
Профайлер с рендерингом
Профайлер без рендеринга
Как оптимизировать игру в unity под андроид
Оптимизация производительности графики
Хорошая производительность критична для многих игр. Ниже даны простые советы по увлечению скорости рендеринга в вашей игре.
Какова стоимость графики
Графическая часть вашей игры нагружает в первую очередь две системы компьютера: GPU (графический процессор) и CPU (центральный процессор). Первое правило любой оптимизации: найти, где возникает проблема, так как стратегия оптимизации для GPU и CPU имеет существенные различия (иногда даже возникает ситуация, когда при оптимизации для GPU больше нагрузки ложится на CPU и наоборот).
Типичные узкие места и их проверка:
- GPU часто ограничен филлрейтом (fillrate) или пропускной способностью памяти.
- Lower the display resolution and run the game. If a lower display resolution makes the game run faster, you may be limited by fillrate on the GPU.
- Check “batches” in the Rendering Statistics window. The more batches are being rendered, the higher the cost to the CPU.
- GPU обрабатывает слишком много вершин. Какое количество вершин является нормальным, определяется GPU и набором вертексных шейдеров. Можно посоветовать использовать не более 100 тысяч для мобильных устройств и не более нескольких миллионов для PC.
- The CPU has too many vertices to process. This could be in skinned meshes, cloth simulation, particles, or other game objects and meshes. As above, it is generally good practice to keep this number as low as possible without compromising game quality. See the section on CPU optimization below for guidance on how to do this.
- Рендеринг не создаёт проблем ни для GPU, ни для CPU. Проблема может быть, к примеру, в скриптах или физике. Используйте профайлер для поиска источника проблемы.
Оптимизация для CPU — количество draw call (в дальнейшем, DC)
CPU optimization
To render objects on the screen, the CPU has a lot of processing work to do: working out which lights affect that object, setting up the shader and shader parameters, and sending drawing commands to the graphics driver, which then prepares the commands to be sent off to the graphics card.
All this “per object” CPU usage is resource-intensive, so if you have lots of visible objects, it can add up. For example, if you have a thousand triangles, it is much easier on the CPU if they are all in one mesh, rather than in one mesh per triangle (adding up to 1000 meshes). The cost of both scenarios on the GPU is very similar, but the work done by the CPU to render a thousand objects (instead of one) is significantly higher.
Reduce the visible object count. To reduce the amount of work the CPU needs to do:
- Объединяйте близко расположенные объекты: вручную или используя инструмент draw call batching в Unity.
- Используйте меньше материалов, объединяйте текстуры в большие текстурные атласы.
- Используйте меньше объектов, которые должны визуализироваться несколько раз (отражения, тени, попиксельные источники света и т. п., смотрите ниже).
Объединяйте объекты так, чтобы каждый меш содержал хотя бы несколько сотен треугольников и использоват только один Материал. Важно понимать, что объединение двух объектов, использующих разные материалы, не даст увеличения производительности. Основная причина, по которой два меша используют разные материалы, состоит в том, что они использують разные текстуры. Для оптимизации производительности CPU нужно убедиться, что объекты, которые вы объединяете, используют одну текстуру.
Однако, когда вы используете много пиксельных источников света при Forward rendering path, бывают ситуации, в которых не имеет смысла объединять объекты, это более подробно описано ниже.
CPU optimization using OnDemandRendering
Use OnDemandRendering to improve CPU performance by controlling your application’s rendering speed.
You might want to lower the frame rate in the following scenarios:
- Menus, such as the application entry point or a pause menu. Menus tend to be relatively simple scenes that don’t need to render at full speed. You can render menus at a lower frame rate to reduce power consumption and to prevent device temperature from rising to a point where the CPU frequency may be throttled.
- Turn based games, such as chess. Players spend time waiting for other users to make their move or thinking about their own move. During periods of low activity, you can lower the frame rate to prevent unnecessary power usage and prolong battery life.
- Applications where the content is mostly static, such as Automotive UI.
Adjusting the rendering speed helps you manage power usage and device thermals to maximize battery life and prevent CPU throttling. It works particularly well with the Adaptive Performance package. Even though frames don’t render as often, the application still sends events to scripts at a normal pace (for example, it might receive input during a frame that isn’t rendered). To prevent input lag, you can call OnDemandRendering.renderFrameInterval = 1 for the duration of the input so that movements, buttons, etc. still appear to be responsive.
Situations that are very heavy in areas such as scripting, physics, animation, but not rendering, don’t benefit from using this API. Your application’s visuals might stutter with minimal impact on power usage.
Note: VR applications don’t support On Demand Rendering. Not rendering every frame causes the visuals to be out of sync with head movement and might increase the risk of motion sickness.
GPU: Optimizing Model geometry
There are two basic rules for optimizing the geometry of a Model:
- Don’t use any more triangles than necessary.
- Try to keep the number of UV mapping seams and hard edges (doubled-up vertices) as low as possible.
Следует отметить, что количество вершин, которое обрабатывает видеокарта, обычно не совпадает с количеством, показываемым 3D-приложением. Приложения для моделирования обычно показывают геометрическое количество вершин, то есть, количество угловых точек, составляющих модель. Для видеокарты некоторые геометрические вершины необходимо разбить на несколько логических вершин для корректной визуализации. Вершина может быть разбита на несколько, если она имеет несколько нормалей, UV-координат или вертексных цветов. Следовательно, количество вершин в Unity неизменно выше, чем количество вершин в 3D-приложении.
While the amount of geometry in the Models is mostly relevant for the GPU, some features in Unity also process Models on the CPU (for example, Mesh skinning).
For more tips on improving performance while creating Assets in 3D applications outside of Unity, see Modeling characters for optimal performance.
Lighting performance
Самое быстрое освещение — это то, которое не рассчитывается. Используйте карты освещения для запекания статичного освещения вместо расчёта освещения в каждом кадре. Процесс создания карт освещения требует много времени, чем простое размещения источников света в сцене, но:
- Это намного быстрее работает (в 2–3 раза по сравнению с 2 пиксельными источниками света)
- Это выглядит лучше, так как вы можете запечь глобальное освещение и с более высоким качеством
Во многих случаях можно заменить размещение источников света правильной настройков шейдеров и контента. Для примера, вместо размещения источника света прямо перед камерой для получения эффекта “подсветка краёв модели” (rim lighting), проще добавить расчёт этого эффекта прямо в шейдере.
Освещение в forward rendering
Освещение в forward rendering
Пиксельное динамическое освещение добавит затраты на визуализацию каждого пикселя и может привести к появлению объектов, визуализируемых в несколько проходов. На маломощных устройствах, таких как мобильные устройства или дешёвые PC, следует избегать использования более чем одного пиксельного источника света, освещающего каждый отдельный объект, и стараться использовать карты освещения. Вершинное динамическое освещение может добавить затраты для случаев вершинных трансформаций. Старайтесь избегать ситуаций, когда несколько источников света освещают один объект.
Если вы используете пиксельное освещение, то каждлый меш будет визуализирован столько раз, сколько пиксельных источников света его освещает. Если вы объедините два меша, находящихся далеко друг от друга, то это увеличит габариты меша. Все пиксельные источники света, освещавшие каждую часть объединённого меша, будут освещать теперь этот меш, поэтому количество проходов визуализации, необходимое для этого меша, увеличится. Как правило, число проходов для объединённого меша равно сумме проходов для составивших его частей, в результате чего нет выигрыша от объединения. По этой причине не стоит объединять меши, которые достаточно далеко друг от друга, чтобы быть освещёнными разными пиксельными источниками света.
During rendering, Unity finds all lights surrounding a mesh and calculates which of those lights affect it most. The settings on the Quality window are used to modify how many of the lights end up as pixel lights, and how many as vertex lights. Each light calculates its importance based on how far away it is from the mesh and how intense its illumination is — and some lights are more important than others purely from the game context. For this reason, every light has a Render Mode setting which can be set to Important or Not Important; lights marked as Not Important have a lower rendering overhead.
Для примера рассмотрим игру, где игрок управляет автомобилем, движущимся в темноте со включёнными фарами. Скорее всего, передние фары будут наиболее важным источником света в игре и параметр Render Mode будет установлен для них в значение Important. Задние огни будут менее важны, не оказывая значительного влияния на конечное изображения, так что для них Render Mode можно установить в Not Important, сэкономив тем самым аппаратные ресурсы.
Оптимизация пиксельного освещения сохраняет ресурсы и CPU и GPU: CPU делает меньше draw calls, а GPU обрабатывает меньше вершин и растеризует меньше пикселей для каждого дополнительного объекта.
GPU: сжатие текстур и мипмапы
Use Compressed textures to decrease the size of your textures. This can result in faster load times, a smaller memory footprint, and dramatically increased rendering performance. Compressed textures only use a fraction of the memory bandwidth needed for uncompressed 32-bit RGBA textures.
Использование мипмап для текстур
Как правило, параметр импорта Generate Mip Maps включён для текстур, используемых в 3D-сцене. В этом случае сжатие текстур поможет ограничить количество текстурных данных, транспортируемых в GPU при визуализации. Мимпапы позволяют GPU использовать для маленьких треугольников текстуры пониженного разрешения.
Есть исключение из этого правила: когда один тексель (пиксель текстуры) соответствует одному пикселю экрана, что встречается в элементах пользовательского интерфейса и в 2D-играх.
LOD и послойное задание дистанции для сulling
Culling objects involves making objects invisible. This is an effective way to reduce both the CPU and GPU load.
В некоторых играх целесообразно обрезать мелкие объекты более агрессивно, чем крупные, чтобы снизить разницу между нагрузкой на CPU и GPU. Для примера, маленькие камни и трава могут обрезаться на меньшей дистанции, чем большие здания.
There are a number of ways you can achieve this:
- Use the Level Of Detail system
- Manually set per-layer culling distances on the camera
Это может быть достигнуто использованием системы Level Of Detail или ручной настройкой дистанции обрезки для камеры по слоям. Вы можете поместить мелкие объекты в отдельный слой и задать ему дистанцию обрезки, используя свойство Camera.layerCullDistances.
Тени в реальном времени
Тени в реальном времени хорошо выглядят, но они могут сильно снижать производительность, одновременно добавляя дополнительные draw calls для CPU и дополнительную обработку для GPU. Подробности даны на странице Shadows.
GPU: советы для написания высокопроизводительных шейдеров
Different platforms have vastly different performance capabilities; a high-end PC GPU can handle much more in terms of graphics and shaders than a low-end mobile GPU. The same is true even on a single platform; a fast GPU is dozens of times faster than a slow integrated GPU.
Имейте в виду, что производительность GPU на мобильных устройствах и PC начального уровня скорее всего будет намного ниже, чем на PC, который вы используете для разработки. Как правило, шейдеры нужно вручную оптимизировать, чтобы уменьшить количество расчётов и чтений текстуры для получения высокой производительности. Для примера, некоторые встроенные в Unity шейдеры имеют “мобильные” эквиваленты, которые работают намного быстрее за счёт некоторых ограничений и упрощений.
Ниже приведены рекомендации, которые важны для GPU в мобильных устройствах и PC низкого уровня:
Сложные математические операции
Transcendental mathematical functions (such as pow , exp , log , cos , sin , tan ) are quite resource-intensive, so avoid using them where possible. Consider using lookup textures as an alternative to complex math calculations if applicable.
Avoid writing your own operations (such as normalize , dot , inversesqrt ). Unity’s built-in options ensure that the driver can generate much better code. Remember that the Alpha Test ( discard ) operation often makes your fragment shader slower.
Операции с плавающей точкой
While the precision ( float vs half vs fixed ) of floating point variables is largely ignored on desktop GPUs, it is quite important to get a good performance on mobile GPUs. See the Shader Data Types and Precision page for details.
Подробности о производительности шейдеров можно прочитать на странице Shader Performance.
Список шагов для увеличения производительности вашей игры
- Сохраняйте количество вершин между 200 000 и 3 000 000 в каждом кадре, если целевая платформа — PC
- Если вы используете встроенные шейдеры, проверьте категории шейдеров Mobile и Unlit. Они прекрасно работают и на немобильных платформ, но являются упрощёнными версиями более сложных шейдеров.
- Уменьшите количество различных материалов в сцене — используйте один материал для нескольких объектов, где это возможно.
- Установите свойство Static для неподвижных объектов, чтобы использовать внутреннию оптимизацию static batching.
- Only have a single (preferably directional) pixel light affecting your geometry, rather than multiples.
- Bake lighting rather than using dynamic lighting.
- Используйте сжатие текстур, когда это возможно, а также отдавайте предпочтение 16-битным текстурами перед 32-битными.
- Avoid using fog where possible.
- Узнайте преимущества технологии Occlusion Culling и используйте её для снижения количества видимой геометрии и количества draw calls в случаях со сложными статичными сценами с большим количеством перекрывающих друг друга объектов. Планируйте свои игровые уровни с учётом этой технологии.
- Используйте скайбоксы для имитации далеко расположенной геометрии.
- Используйте пиксельные шейдеры или инструменты для совмещения текстур, чтобы смешивать текстуры вместо многопроходной визуализации.
- Use half precision variables where possible.
- Сводите к минимуму количество сложных математических операций в пиксельных шейдерах: pow, sin, cos и т. п.
- Используйте меньше текстур.
- Unity Profiler Window. Производительность освещения
Гайд по оптимизации мобильных игр в Unity
Всем привет! Меня зовут Илья, я работаю разработчиком мобильных игр на Unity вот уже несколько лет и сегодня хотел бы поделиться небольшим чек-листом (или гайдом) по оптимизации мобильных игр для начинающих. В этой статье мы коснемся как графических, так и других аспектов оптимизации «на скорую руку» когда вам нужно быстро поднять FPS ваших мобильных игр.
По большей мере речь пойдет про оптимизацию 2D игр, чтобы их можно было запустить даже на кипятильнике.
Итак, с предисловием закончили. Поехали!
Продолжаем оптимизировать мобильные игры на Unity. Используем профайлер, а также смотрим, куда лезть не стоит
Постоянно просматриваю сотни новых проектов и вижу новые пробелы в производительности даже в гиперказуальных играх, причем практически во всех. В прошлой статье я описал четыре простых шага и несколько рекомендаций, как оптимизировать практически любую простую игру на Unity под слабые устройства, затратив на это минимум ресурсов.
Сегодня рассмотрим еще несколько нюансов, которые могут облегчить разработку или ревью вашего проекта, чтобы приблизить дату релиза и избежать разочарования игроков от плохой производительности.
Также поговорим, на что не стоит обращать внимания в небольших проектах, чтобы не тратить лишнее время ради пары процентов производительности.
Начнем с основного инструмента, который сильно может облегчить жизнь при поиске слабых мест.
1. Профайлер
Встроенный в Unity профайлер я всегда использую как стартовую точку. Здесь все интуитивно, даже если пользуешься им первый раз, поэтому игнорировать его точно не стоит. Он наглядно показывает части кода, которые тормозят.
Проблемы обычно возникают, когда код писал кто-то другой — тут придется разобраться, что он делает и как это исправить.
Если профайлер Unity не дал однозначных ответов, переходим к нативным профайлерам — Android Studio или Xcode, в зависимости от платформы.
В более сложных, непонятных ситуациях переходим на специализированные, например, Snapdragon Profiler, Arm Mobile Studio и так далее, в зависимости от девайсов под рукой. Функционал у таких профайлеров плюс-минус одинаковый, просто они под разное «железо».
2. Баннерная реклама
Не так давно был случай, когда я использовал профайлер не совсем корректно. По запросу от команды проводился анализ игры. Вводная была такая: стабильно низкий FPS. И так как речь шла о нем, я проводил замеры не со старта игры, а через некоторое время, и внимательно изучал проект на «плато». Я заметил несколько проблем и почти два дня составлял рекомендации по оптимизации. Выписал огромное количестве рецептов, но по итогу производительность выросла на 10%, что очень мало.
Дальнейший анализ показал, что проблема на самом деле существовала первые 15-20 секунд после старта игры из-за загрузки баннерной рекламы. Как только баннер прогружался — лаги прекращались.
Баннер — это, по сути, браузер, запущенный внутри игры. А браузер довольно тяжелое приложение, которое используется просто, чтобы показать маленькую картинку или анимацию. Пока он загружается, игра может лагать. Такой подход используют абсолютное большинство рекламных сетей. Поэтому, если бы кто-то захотел избавиться от проблемы, то ему бы пришлось написать свой плагин и создать свою компанию, которая продает рекламу.
Поэтому выходов из такой ситуации всего два:
- Выключить баннерную рекламу на слабых устройствах и потерять часть монетизации.
- Смириться с некоторыми лагами первые 30 секунд (в идеале попытаться как-то это замаскировать), пока баннер загружается.
В целом, все рекламные плагины вызывают лаги, и общая рекомендация — подгружать плейсменты рекламы по очереди, немного размазывая лаг во времени.
3. Отсечение того, что за кадром
Случается, что камера смотрит вниз, где два игровых персонажа, а вокруг гуляет еще десяток невидимых «лишних», которые отнимают ресурсы. Обычно это не критично, потому что на небольших проектах мало объектов, все они попадают в камеру и нет больших уровней.
Если же уровень большой и объектов действительно много, не забывайте отключать все, что не видно. Например, у анимированных объектов (CullingMode) есть три опции:
- анимировать всегда (AlwaysAnimate);
- анимировать, только когда игрок их видит (CullCompletely);
- анимировать только физику, если ты их не видишь (AnimatePhysics).
По дефолту в Unity стоит «анимировать всегда», поэтому в большинстве случаев эту галочку нужно отключать.
4. 3D-модели и текстуры
Для небольших проектов этот пункт не особо актуален. Ситуации встречаются двух типов:
- Колоссальные ошибки. Например, разработчик сделал партикл-систему из сфер, в которых по полторы тысячи полигонов в каждой. Не надо так.
- Всё в пределах нормы, и оптимизация не стоит потраченного времени.
5. Организация проекта
Беспорядок в организации файлов, дублирование ассетов и текстур, нечитабельные имена и вот это все банально замедляют разработку. Хотя в казуальных проектах от сторонних студий это последнее, на что стоит обращать внимание.
Осложняет ситуацию еще и то, что каждый случай индивидуальный. У разных команд свои сильные и слабые стороны. Если кто-то привык к определенному порядку и иерархии проекта, то пытаться себя перестроить — это потратить уйму времени, сил и не факт, что станет лучше.
Я не даю рецептов в этом плане и не лезу в чужие процессы без крайней необходимости. Хорошо, когда проект с самого начала грамотно организован, но в статье мы все-таки говорим про технические ошибки.
Пример оптимизации мидкор-проекта
Теперь рассмотрим конкретный кейс из прошлого с примерами советов по оптимизации одного проекта.
Это была мидкорная игра с кораблями на 10 игроков. Но ее проблема заключалась в том, что на средних по производительности устройствах FPS падал до 5 кадров в секунду. И причин тому нашлось несколько.
Скиннинг моделей
Непомерно много на проекте отнимал скиннинг 3D-моделей — парусов и моряков на палубе было очень много. Unity умеет делать скиннинг на GPU для ускорения, но даже это не всегда помогает, особенно на слабых устройствах где и так GPU очень слаб.
В данном кейсе скиннинг занимал 60 миллисекунд, и уже это приводило к ограничению в 12 FPS, без учёта рендера кадра и прочего.
- Для начала стоит на всех аниматорах, которые не влияют на симуляцию, а только визуальны, поставить CullingMode на CullCompletely (см. раздел №3 выше). И хорошо бы ещё и на определённом расстоянии от камеры их тоже выключать, даже если видно.
- Уменьшить количество скин мешей в принципе.
- Уменьшить количество костей на вершину, иногда сделать на каждый треугольник по одной-две кости, если это не очень критично влияет на визуальную красоту.
- Уменьшить количество вершин на моделях.
- Можно переделать анимации и так далее (например, уменьшить количество костей).
Очистка буфера кадра
При рендрере первой камеры (или на старте рендера через SRP) нужно чистить весь буфер кадра, а не только Z и стенсил. Если что-то забыть — ломается маркер начала кадра, что на мобильных GPU критично и некоторые вещи, которые сделаны на аппаратном уровне, могут отрабатывать не так, как ожидается.
Форматы текстур
Хорошие и модные форматы текстур могут не поддерживаться конкретными устройствами. В таких случаях Unity показывает, что они должны весить, например, 0.7 Мб, а на девайсе по факту выходит 2.7 Мб.
Дело в том, что если какой-то оригинальный формат текстур не поддерживается на конкретном девайсе, то Unity распаковывает его в другой формат и использует в несжатом виде. Получается, что текстуры должны весить мало (как показывает Unity), а на самом девайсе они весят в несколько раз больше. Всё потому, что встроенный профайлер показывает только расчетный размер текстуры, если на телефоне будет поддерживаться такой формат.
Чтобы узнать истинный размер текстуры — нужны нативные профайлеры, о которых я упоминал выше.
Аллокации
Большое количество аллокаций (выделений памяти).
Обычно считается, сколько делается аллокаций на один кадр. И если их там больше, условно, чем 5-10 Кб на один кадр, то стоит задуматься над поиском и ликвидацией этих мест.
В итоге
Добились 20-30 FPS на слабых устройствах, вместо изначальных 5.