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

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

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Оптимизация текстурных атласов мобильной игры
Средний
от 1 дня до 3 дней
Часто задаваемые вопросы

Оптимизация текстурных атласов: где проседает кадр

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

Типовая ошибка — один большой лист на всю категорию ресурсов: интерфейс, окружение и эффекты лежат вместе, и движок поднимает в память весь лист ради двух-трёх нужных элементов. Параллельно растёт объём сборки: часть листа не сжимается, часть каналов остаётся без потерь, а декодирование крупного изображения занимает заметную долю времени старта уровня.

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

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

Что даёт перепаковка атласов мобильной сцены

Правильно собранный атлас в первую очередь сокращает объём ресурсов сборки: повторяющиеся элементы и мелкие изображения укладываются в общие листы, дубликаты и лишние поля по краям уходят. Из поставки пропадает заметная доля исходных данных, а вместе с ней — время на их распаковку и проверку целостности при первом запуске.

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

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

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

Итог проверяется по четырём измеримым признакам: вес сборки стал меньше, сцена грузится быстрее, память расходуется экономнее, кадры идут ровно без провалов. Если хотя бы один пункт не сдвинулся, перепаковку атласов стоит пересобрать заново — по замерам, а не по ощущениям.

Режимы упаковки и сжатия: сравнение подходов

Ресурсы мобильной игры упираются в два ограничения: объём видеопамяти и число переключений материалов на кадр. Режим упаковки и сжатия выбирают не «по вкусу», а под содержимое атласа — градиенты, мелкие иконки интерфейса и полноэкранные фоны ведут себя по-разному.

Сжатие без потерь сохраняет каждый пиксель, но в памяти такая текстура всё равно разворачивается целиком — выигрыш остаётся только в размере сборки. Блочное сжатие с потерями (ASTC) держит данные сжатыми прямо в памяти ускорителя: объём и пропускная способность падают, но появляются артефакты на тонких линиях и градиентах.

Вариант Когда подходит Ограничения
Без потерь Интерфейс, шрифты, маски, превью В памяти разворачивается целиком, видеопамять не экономит
Блочное с потерями Крупные фоны, карты материалов Артефакты на градиентах, требования к кратности блока
Разбиение на страницы Атлас не влезает в лимит устройства Больше переключений материалов на кадр
Плотная упаковка с ротацией Разнородные спрайты, чёткая сетка Ротация ломает девятисегментные элементы и шейдеры

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

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

Порядок работ: от замера до передачи проекта

Атлас перепаковываем не «на глаз», а по результатам замера: сначала снимаем профиль на целевых устройствах и находим, что именно упирается — заполнение текстурного блока, объём занимаемой видеопамяти, число вызовов отрисовки или время загрузки сцены. Дальше идёт последовательность шагов, где каждое решение опирается на данные предыдущего, а не на привычку разработчика.

  1. Замер узких мест. Профилируем проблемные сцены и меню на репрезентативной выборке устройств — от слабых до топовых. Фиксируем базовые метрики: время кадра, потребление памяти, длительность загрузки, число переключений материала.
  2. Схема разбиения атласа. Группируем спрайты по частоте совместного появления в кадре и по общему материалу, считаем бюджет площади и запас на технологический отступ между элементами, чтобы не ловить «протекание» краёв на мип-уровнях.
  3. Перепаковка и пересборка. Собираем атласы по утверждённой схеме, приводим размеры к удобным для сжатия значениям, обновляем привязки в ресурсах и проверяем, что сборка проходит без ручных правок.
  4. Проверка на целевых устройствах. Прогоняем те же сцены повторно и сверяем метрики с базовыми: смотрим, ушло ли узкое место и не появилось ли новое — например, рост времени загрузки из-за дробления файлов.
  5. Стабилизация и регресс. Фиксируем эталонные замеры и добавляем автопроверку схемы упаковки, чтобы следующая порция графики не сломала достигнутый результат.
  6. Передача проекта команде. Отдаём схему разбиения, скрипты перепаковки, регламент добавления новых ресурсов и короткую инструкцию для художников — дальше команда заказчика ведёт упаковку сама, без нас.

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

Артефакты: схемы разбиения, профили памяти, регламенты

После работ у команды заказчика остаётся не отчёт, а рабочий комплект: по нему новый инженер воспроизводит сборку атласов и получает тот же результат без обращения к нам. Каждый документ привязан к конкретному шагу конвейера ресурсов, поэтому расхождение между «как договорились» и «как собирается» видно сразу — на этапе проверки, а не на устройстве игрока.

  • Схема разбиения ресурсов — какие группы изображений сводятся в один атлас, по какому признаку (частота одновременного показа, общий материал, экран), какие остаются отдельными файлами. С указанием предельного размера листа и правил добора свободного места.
  • Профиль памяти приложения — замеры потребления на целевых устройствах до и после правок, разбитые по сценам: загрузка, бой, интерфейс, длительная сессия. Служит эталоном для сравнения при следующих релизах.
  • Правила именования ресурсов — единый шаблон для изображений, атласов и производных файлов, чтобы сборщик автоматически находил зависимости, а поиск нужного листа не превращался в перебор директорий.
  • Регламент ревизий графики — кто и когда пересматривает состав атласов, что считается поводом для пересборки (новый набор контента, рост потребления, жалобы на подгрузки), как фиксируется результат.
  • Документация по сборке ресурсов — порядок шагов, состав инструментов и точки контроля с проверками: незаполненные области, дубли, ресурсы вне схемы. Новый человек проходит путь от исходников до готового набора без устных пояснений.
  • Карта владения — какие файлы и настройки закреплены за конкретными ролями, что меняется только через ревизию, а что можно править локально.

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

Кейс: убрали просадки на слабых устройствах

Что было до работ

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

Что изменили

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

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

Как измерили результат

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

Что делать, если приложение уже выпущено и обновляется?

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

Ключевое условие — обратная совместимость ресурсов. Старые сборки на устройствах продолжают читать прежние листы, новые — уже переупакованные: имена слотов и ключи доступа к кадрам сохраняются, меняется только раскладка. Прежний набор остаётся в дистрибутиве до момента, когда доля игроков на устаревших версиях падает до пренебрежимой.

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

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

Так оптимизация идёт параллельно выпуску версий, а не вместо него: каждая волна даёт измеримый срез по памяти и загрузке, а согласованный вид и поведение игры для игрока остаются неизменными.

Фильтрация, прозрачность, память: частые вопросы

Такие вопросы обычно всплывают уже на созвоне, когда черновой атлас собран и видно, где он проседает. Ниже — короткие ответы на то, что чаще всего вызывает сомнения у команды заказчика.

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

По краям элементов появляется кайма — это лечится?

Да, это самый частый артефакт, и причина техническая: фильтрация захватывает пиксели соседнего элемента. Закрывается запасом в 2–4 пикселя по краю, куда дублируются крайние пиксели, и корректно собранными уменьшенными копиями листа — иначе кайма проявится на дальних уровнях детализации.

Можно ли держать полупрозрачные элементы в общем атласе?

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

Почему после разбиения атласа память выросла?

Потому что каждый лист — отдельная текстура со своим минимальным размером, запасом по краям и своими уменьшенными копиями. Дробим не «по папкам», а по формату сжатия и частоте использования элементов: редкие элементы уезжают в отдельный лист, который грузится по требованию.

Как убедиться, что сжатие не убило качество?

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

С чего начинать, если приложение просто «тормозит»?

С замера. Снимаем объём загружаемых текстур, их число и время подготовки сцены, затем смотрим, что меняется при переходе между экранами. Чаще всего узкое место — не геометрия, а объём текстур и лишние переключения материалов в кадре.

Обсудим задачу: замер сцены, план работ, оценка

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

  • текущая сборка игры или доступ к репозиторию — снимок реального состояния, а не пересказ;
  • перечень сцен, где видны просадки: загрузка уровня, бой, экран магазина, инвентарь;
  • статистика по памяти и времени отрисовки, если команда её уже собирает;
  • список атласов с размерами и правилами упаковки: какие наборы спрайтов к какому экрану относятся;
  • ограничения по целевым устройствам и минимальной поддерживаемой версии системы;
  • данные аналитики падений и отзывов — где чаще жалуются на подтормаживания и нагрев корпуса.

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

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

Наши компетенции:

Последние работы

  • Разработка мобильного приложения для компании FEEDME
    Разработка мобильного приложения для компании FEEDME
    1010
  • Разработка мобильного приложения для компании XOOMER
    Разработка мобильного приложения для компании XOOMER
    903
  • Разработка мобильного приложения для компании RHL
    Разработка мобильного приложения для компании RHL
    1332
  • Разработка мобильного приложения для компании ZIPPY
    Разработка мобильного приложения для компании ZIPPY
    1180
  • Разработка мобильного приложения для компании Affhome
    Разработка мобильного приложения для компании Affhome
    1107
  • Разработка мобильного приложения для компании FLAVORS
    Разработка мобильного приложения для компании FLAVORS
    714