- Практическое руководство по оптимизации для мобильных
- Мобильные устройства не созданы одинаковыми
- Оптимизацию не следует считать последней стадией разработки проекта
- Оптимизация: Не только для программистов
- Планируйте игру так, чтобы во время исполнения она работала “плавно”.
- Профилируйте на ранней стадии и почаще
- Внутренний Профайлер
- Внутренний Профайлер
- Графические приёмы
- Что можно реализовывать на текущих пользовательских устройствах:
- Что НЕ НУЖНО реализовывать на текущих пользовательских устройствах:
- Примеры — как сделаны первоклассные мобильные игры
- Shadowgun
- Sky Castle Demo
- Итог — Что это означает для вашей игры
- Не имитируйте! Запекайте!
- Оптимизации
- Фокус на GPU
- Хорошая практика
- Shader optimizations
- Фокус на CPU
- Хорошая практика
- Физика
- Android
- Что еще почитать
- Разрешение экрана
- Версия android
- Что еще почитать
- Разрешение экрана
- iOS версия
- Динамические объекты
- Asset Бандлы
- Если предел на количество одновременно загружаемых ассет бандлов на iOS? (т.е. можем ли мы безопасно загрузить более 10 ассет бандлов одновременно (или каждый кадр)?)
- Ресурсы
- Список глупых проблем
Практическое руководство по оптимизации для мобильных
Это руководство предназначено для новичков в мобильном геймдеве. Для тех, кто испытывает трудности при планировании и прототипировании новой мобильной игры (или портировании уже существующего проекта). Также этот раздел будет полезен в качестве справки для каждого, кто делает мобильные или браузерные игры (с целевой платформой — старые ПК или нетбуки).
Оптимизация вообще широкая тема, и то как вы ее сделаете, целиком зависит от вашей игры, поэтому данное руководство следует рассматривать как некое введение или ссылку, а не пошаговое руководство.
Мобильные устройства не созданы одинаковыми
Информация здесь предполагает аппаратное обеспечение на уровне чипсета 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 кадров. Это поможет вам выяснить, какие аспекты вашей игры замедляют ее, будь то физика, скрипты, визуализация, но без множества деталей (например, только название скрипта или визуализации).
См. Встроенный Профайлер для подробной информации о том, как это работает и включается.
Источник
Графические приёмы
На что способны мобильные устройства? Как нужно планировать свою игру? Если игра тормозит, и профайлер показывает что проблема в рендеринге, как узнать что именно нужно изменить? Как сделать так, чтобы ваша игра выглядела лучше и оставалась быстрой? Эта страница посвящена общему, не техническому изложению методов. Если вы ищете что-то специфическое, см. Оптимизации визуализации.
Что можно реализовывать на текущих пользовательских устройствах:
- Lightmapped static geometry. But beware of:
- Using a lot of alpha-test shaders
- Bumpmapping, especially using built-in shaders.
- High polygon count
- Animated characters, even with fancy shaders! But beware of:
- Massive crowds or high-poly characters
- 2D games with sprites. But beware of:
- Overdraw, or, lots of layers drawn on top of each other.
- Particle effects. But beware of:
- High density on large particles. (Lots of particles drawn on top of each other. This is another overdraw situation)
- Ridiculous numbers of particles, or particle colliders.
- Physics. But beware of:
- Mesh colliders.
- Lots of active bodies.
Что НЕ НУЖНО реализовывать на текущих пользовательских устройствах:
- Графические эффекты в полном экране (такие как свечение и глубина резкости).
- Dynamic per-pixel lighting (multiple lights marked Important and not baked into the lightmap)
- Every affected object is drawn an additional time for every dynamic light you use, and this gets slow quickly.
- Real time shadows on everything
- Unity has support for real time shadows on mobile platforms, but their use must be very judicious, and likely limited to higher-end devices.
Примеры — как сделаны первоклассные мобильные игры
Shadowgun
Shadowgun — замечательный пример того, что может быть сделано на текущем мобильном программном обеспечении. Более конкретно, это хороший пример того, что не следует делать и как обойти ограничения. Тем более что небольшую часть игры сделали общедоступной здесь сообщение в блоге.
Вот основные вещи, которые реализует Shadowgun для сохранения производительности:
- Dynamic lighting — barely used.
- Blob shadows and Lightmaps are used instead of any real shadows.
- Lightprobes, instead of real lights, are used on their characters.
- Muzzle flashes added into the lightprobe data via script.
- The only dynamic per-pixel lighting is an arbitrary light direction used to calculate a BRDF on the characters.
- Bumpmapping — barely used.
- Real bumpmapping only used on characters.
- As much contrast and detail as possible is baked into the diffuse texture maps. Lighting information from bumpmaps is baked in.
- A good example is their statue texture, or their shiny wall, as seen on the right. No bumpmaps are used to render these, the specularity is faked by baking it into the texture. Lightmapping is combined with a vertex-lighting-based specular highlight to give these models a shiny look.
- If you want to learn how to create textures like this one, check out the Rendering Optimizations page.
- Dense particles — avoided.
- UV-scrolling textures used instead of dense particle effects.
- Fog effects — avoided.
- Their god rays are hand-modeled.
- Single planes that fade in and out are used to achieve cinematic fog effects without actually rendering any fog.
- This is faster because the planes are few and far between, and it means that fog doesn’t have to be calculated on every pixel and in every shader.
- Glow — avoided.
- Blended sprite planes are used to give the appearance of a glow on certain objects.
Sky Castle Demo
This demo was designed to show what Unity is capable of on high-end Android devices.
- Dynamic lighting — not used.
- Lightmaps only.
- Bumpmapping — used
- The bricks are all bumpmapped, lit by directional lightmaps. This is where the “high-end devices” part comes into play.
- Real time reflections — limited.
- They carefully placed their real-time reflecting surfaces separately and in isolated areas, so that only one runs at a time, and the environment that needs to be rendered twice can be easily culled.
Итог — Что это означает для вашей игры
Чем больше вы будете уделять внимания и лучше понимать ограничения мобильных устройств, тем лучше будет выглядеть ваша игра, и тем лучше будет производительность. Если вы хотите сделать игру высокого класса для мобильных, вы извлечете немалую пользу от понимания того, как строится графика в Unity и будете способны написать свои шейдеры. Если же вы хотите использовать уже готовые шейдеры из ShadowGun, они доступны здесь.
Не имитируйте! Запекайте!
Нет сомнений что игры пытаются следовать законам природы. Движение параболического снаряда и цвет каждого блестящего пикселя написанным по формулам, имитирующим наблюдения в реальном мире. Но научная симуляция — только одна часть игры, есть еще другая — рисование. На мобильном маркете вы не сможете конкурировать с физически точно воссозданной визуализацией; аппаратная часть не позволяет этого сделать. Если вы слишком увлечетесь в имитации реального мира, ваша игра может быть неограниченной, серой и залагованной.
Рисуйте свои полигоны и смешивайте краски как художник.
Запекание карт рельефа в Shadowgun отличный пример этого. Зеркальное освещение там уже в текстуре, человеческий глаз не замечает того, что они на самом деле не совпадают с направлением света, по текстуре это просто контрастные детали, полностью сфальсифицированные, но, в конечном итоге выглядящие превосходно. Это распространенные “обманки”, которые используются во многих успешных играх. Сравните шлем в первый скриншот из Halo, до релиза с этим шлемом релизный скриншот. Создается видимость того, что выступы брони отражаются в шлеме, но на самом деле это отражение запечено в текстуру шлема. В Лиге Легенд (League of Legends), есть небольшой эффект, создающий видимость пиксельного освещения, но на самом деле там смешанная плоскость с текстурой, которая возможно создана в момент записи снимка экрана, пиксельный свет, сияющий на земле.
Источник
Оптимизации
Так же как и ПК, мобильные платформы iOS и Android имеют множество девайсов с различными уровнями производительности. Вы можете найти телефон, в 10 раз превосходящий по мощности рендеринга другой телефон. Быстрый, легкий путь для измерения:
- Убедитесь, что он хорошо работает на базовой конфигурации
- Используйте больше “красивостей” для высокопроизводительных устройств:
- Разрешение
- Пост-обработка
- MSAA
- Анизотропия
- Шейдеры
- Плотность, включение и отключение fx/частиц
Фокус на GPU
Графическая производительность связана с филлрейтом, пиксельной и геометрической сложностью (количеством вершин). Их можно уменьшить. Здесь может помочь Occlusion culling, т.к. Unity не будет отображать объекты, не входящие в область обзора.
На мобильных, по сути, связь скорости заполнения (скорость заполнения = пиксели экрана * сложность шейдера * овердрафт) и более сложных шейдеров является наиболее распространенной причиной проблем. Поэтому рекомендуется использовать мобильные шейдеры, поставляемые с Unity или писать свои, как можно более простые. Если это возможно, заменяйте пиксельные шейдеры на вершинные.
Если уменьшение качества текстур в настройках качества сделает игру быстрее, то у вас, возможно, ограничена пропускная способность памяти. Поэтому используйте компрессию текстур, мипмапы, уменьшайте размер текстуры и т.д.
LOD (Level of Detail) — make objects simpler or eliminate them completely as they move further away.
Хорошая практика
Мобильные графические процессоры имеют огромные трудности в том, как много тепла они производят, сколько энергии они потребляют, насколько большие или шумные они могут быть. Так, по сравнению с настольными, мобильные графические процессоры имеют меньшую пропускную способность, низкую ALU производительность и производительность текстур. Архитектуры графических процессоров также настроены под использование низкой пропускной способности и производительности.
Unity оптимизирован под OpenGL ES 2.0, используется шейдерный язык GLSL ES(схожий с HLSL). Чаще всего шейдеры пишутся в HLSL (известен также как Cg). Это перекрестие, сделанное в GLSL ES для мобильных платформ. Также вы можете писать на GLSL, если хотите, но при этом придерживайтесь OpenGL платформ (mobile + Mac). При использовании float/half/fixed типов в HLSL, они в конечном итоге будут highp/mediump/lowp точными определителями в GLSL ES.
Вот контрольный список для хороший практики:
- Количество материалов должно быть как можно более низким. Это делает батчинг для Unity более легким.
- Используйте атласы текстур (большие изображения, содержащие более маленькие) вместо большого количества отдельных текстур. Это сделает загрузку более быстрой.
- Используйте Renderer.sharedMaterial вместо Renderer.material если используете атласы текстур и общие материалы.
- Рендер пиксельного освещения дорог.
- Используйте карты освещения вместо освещения в реальном времени там, где это возможно.
- Отрегулируйте пиксельное освещение в настройках качества. В сущности, на пикселе должен быть направленный свет, все остальное — на вертексе. Конечно, это зависит от игры.
- Экспериментируйте с Render Mode Освещения в настройках качества, для получения правильного приоритета.
- Избегайте cutout шейдеров (альфа тест), если это действительно необходимо.
- Сведите к минимуму прозрачную (альфа смешивание) часть экрана.
- Постарайтесь избежать ситуаций, когда несколько источников света освещают какой либо объект.
- Попробуйте уменьшить общее количество шейдерных проходов (тени, пиксельное освещение, отражения).
- Критический порядок визуализации. В общем случае:
- полностью непрозрачные объекты примерно спереди-сзади.
- альфа тестируемые объекты примерно спереди-сзади.
- скайбокс
- объекты со смешенной альфой (если это необходимо, задом наперед).
- Пост обработка дорога для мобильных, используйте аккуратно.
- Партиклы: уменьшите овердрафт, используйте как можно более простые шейдеры.
- Двойной буфер для мешей, умножаемый каждый кадр:
Shader optimizations
Проверка границ филлрейта (fillrate) проста: если вы уменьшите разрешение, игра будет идти быстрее? Если да, то ваш филлрейт ограничен.
Попробуйте уменьшить сложность шейдеров с помощью следующих методов:
- Избегайте шейдеров с альфа-тестом, вместо этого используйте альфа-смешанные версии.
- Используйте простой, оптимизированный код шейдеров (например, как у шейдеров “Mobile”, которые поставляются с Unity).
- Избегайте дорогих математических функций в коде шейдеров (pow, exp, log, cos, sin, tan и т.д.). Вместо этого постарайтесь использовать заранее вычисленные текстуры.
- Для лучшей производительности, сделайте количество точных рассчетов (float, half, fixedin Cg) как можно более низким.
Фокус на CPU
Часто бывает, что обработка пикселей в игре ограничивается процессором. Таким образом, в конечном итоге остаются неиспользуемые мощности, особенно на многоядерных процессорах. Таким образом, часто целесообразно перекладывать следующие функции с GPU на CPU (Unity их поддерживает): mesh skinning, батчинг маленьких объектов, обновления геометрии частиц.
Это следует делать с осторожностью. Если вы не связаны по графическим вызовам (draw calls), то батчинг на самом деле помешает производительности. Он сделает culling менее эффективным и сделает многие объекты зависимыми от освещения.
Хорошая практика
- FindObjectsOfType (и вцелом геттерные функции Unity) очень медленные, поэтому используйте их с умом.
- У неподвижных объектов активируйте свойство Static. Это позволит им участвовать во внутренних оптимизациях (таких как статический батчинг).
- Произведите множество циклов процессора для обеспечения лучшей сортировки occlusion culling (отсечение невидимых поверхностей).
Физика
Физика может сильно нагрузить процессор. Можно проследить это с помощью профайлера редактора. Если физика сильно нагружает процессор:
- Настройте Time.fixedDeltaTime (в Project settings -> Time) так, чтобы он был как можно более высоким. Если ваша игра с медленным движением, то, вероятно, вам понадобится меньше фиксированных обновлений, чем игре с быстрым движением. Быстрый темп игры нуждается в более частых расчетах, поэтому, чтобы не было сбоев с коллизиями, fixedDeltaTime должен быть ниже.
- Physics.solverIterationCount (Physics Manager).
- Используйте как можно меньше объектов типа Cloth.
- Rigidbodies используйте только там, где это необходимо.
- Вместо меш коллайдеров старайтесь использовать примитивные коллайдеры.
- Никогда не двигайте статический коллайдер (т.е. коллайдер без Rigidbody), так как это сильно скажется на производительности. В профайлере это отобразится как “Static Collider.Move”, но на самом деле будет обрабатываться в Physics.Simulate. Если понадобится, добавьте RigidBody и установите isKinematic в true.
- В Windows вы можете использовать NVidia’s AgPerfMon набор инструментов для профилирования, чтобы получить больше необходимых деталей.
Android
Это популярная мобильная архитектура. У нее отличные от ПК/Консоли поставщики программного обеспечения и архитектура GPU сильно отлична от “обычной”.
- ImgTec PowerVR SGX — основанный на тайлах: визуализирует все в маленьких тайлах (16×16), тени только на видимых пикселях
- NVIDIA Tegra — классический: визуализирует все
- Qualcomm Adreno — тайловый: визуализирует все в тайле, поддерживает большие тайлы (256к). Adreno 3xx может быть переключен в традиционный.
- ARM Mali — тайловый: визуализирует все в тайле, поддерживает маленькие тайлы(16×16)
Потратьте некоторое время на рассмотрение различных подходов к рендерингу и спроектируйте свою игру соответственно. Заострите внимание на сортировке. Определите самые низкие из поддерживаемых девайсов в начале разработки. Протестируйте на них с профайлером свою игру.
Используйте специфичное для платформы сжатие текстур.
Что еще почитать
- Руководство по архитектуре PowerVR SGX http://imgtec.com/powervr/insider/powervr-sdk-docs.asp
- Tegra GLES2 feature guide http://developer.download.nvidia.com/assets/mobile/files/tegra_gles2_development.pdf
- Руководство по производительности Qualcomm Adreno GLES http://developer.qualcomm.com/file/607/adreno200performanceoptimizationopenglestipsandtricksmarch10.pdf
- Engel, Rible http://altdevblogaday.com/2011/08/04/programming-the-xperia-play-gpu-by-wolfgang-engel-and-maurice-ribble/
- Руководство по оптимизации ARM Mali GPU http://www.malideveloper.com/developer-resources/documentation/index.php
Разрешение экрана
Версия android
Пострадает только PowerVR архитектура (основанная на тайлах).
- ImgTec PowerVR SGX. Tile based, deferred: render everything in tiles, shade only visible pixels.
- Карты освещения уже не так необходимы.
- Antialiasing and aniso are cheap enough, not needed on iPad 3 in some cases.
- Если вершинные данные каждого кадра (количество вершин * хранение требуется после вершинных шейдеров) превышает внутренние буферы, выделенные драйвером, то для лучшей производительности сцена должна быть разделена. После этого драйвер должен выделить буфер большего размера, или же вам нужно будет снизить количество вершин. Это становится видно на iPad2 (iOS 4.3) на отметке 100 000 вершин с довольно сложными шейдерами.
- TBDR нуждается в большем количестве транзисторов, выделяемых на тайлинг и отложенные части, оставляя концептуально меньше транзисторов для “чистой производительности”. Очень трудно (практически невозможно) выделить в GPU время на отрисовку вызова в TBDR, что делает профилирование сложным.
Что еще почитать
- Руководство по архитектуре PowerVR SGX http://imgtec.com/powervr/insider/powervr-sdk-docs.asp
Разрешение экрана
iOS версия
Динамические объекты
Asset Бандлы
- Asset Бандлы кешируются на устройстве до определенного предела
- создаем используя Editor API
- Загружаем используя WWW API: WWW.LoadFromCacheOrDownload или как ресурс: AssetBundle.CreateFromMemory или AssetBundle.CreateFromFile
- Выгружаем используя AssetBundle.Unload. Там есть опция для выгрузки бандла, но перед этим сохраните загруженный ассет. Также можно удалить все загруженные ассеты, даже если на них есть ссылки в сцене
- Resources.UnloadUnusedAssets выгружает все ассеты, на которые больше нет ссылок в сцене. Не забывайте убивать ссылки на ассеты, если они вам не нужны. Публичные и статические переменные не убираются сборщиком мусора.
- Resources.UnloadAsset выгружают специфические ассеты из памяти. Если нужно, они могут быть повторно загружены с диска.
Если предел на количество одновременно загружаемых ассет бандлов на iOS? (т.е. можем ли мы безопасно загрузить более 10 ассет бандлов одновременно (или каждый кадр)?)
Загрузки реализованы через асинхронный API, представленный ОС, потому что ОС решает как много потоков нужно для создания загрузки. При одновременном запуске нескольких загрузок, нужно учесть общую пропускную способность устройства, которую он может поддерживать и объем свободной памяти. Каждая параллельная загрузка выделяет отдельный временный буфер, поэтому нужно убедится что хватит оперативной памяти.
Ресурсы
- Ассеты должны быть признаны Unity, быть размещенными в билде.
- Добавьте к файлу .bytes если вам нужно чтобы Unity распознавал его как файл с двоичными данными.
- К текстовым файлам добавьте .txt, в этом случае Unity будет его распознавать как текстовый ассет
- Ресурсы преобразуются в формат платформы во время сборки.
- Resources.Load()
Список глупых проблем
- Текстуры без надлежащего сжатия
- Разные решения для различных случаев, не забудьте сжать текстуры если вам это нужно.
- ETC/RGBA16 — по умолчанию для android, но вы можете настроить его в зависимости от GPU. Лучший подход — использовать ETC везде, где это возможно. Альфа текстуры могут использовать два ETC файла с одним каналом для альфы.
- PVRTC — по умолчанию для iOS, хорош в большинстве случаев
- Текстуры, имеющие включенные Get/Set пиксели удваивают размер, деактивируйте Get/Set, если вам это нужно
- Текстуры, загруженные в JPEG/PNG во время исполнения будут несжаты
- Большие mp3 файлы помечайте как decompress on load
- Добавьте загрузку сцены
- Неиспользуемые ассеты остаются неочищенными в памяти.
- Если есть случайные сбои, попробуйте запустить на devkit или на устройстве с 2 GB памяти (например, на Ipad 3).
Иногда ничего нет в консоли, просто случайный сбой
- Fast script call и stripping могут привести к случайным сбоям на iOS. Попробуйте без них.
Источник