Оптимізація текстурних атласів мобільної гри
Неправильно упаковані текстури — одна з найчастіших причин того, що гра займає 300 МБ замість 80 МБ, а на старих Android-пристроях вилітає з SIGKILL через OOM. При цьому в редакторі все працює нормально: Unity зберігає текстури у несжатому вигляді, й реальний розмір VRAM стає очевидним лише при профілюванні на девайсі.
Типові проблеми з атласами
Формат за замовчуванням — RGBA32. Якщо не встановити явний Override для кожної платформи, Unity упакує текстури у несжатий RGBA32. 1024×1024 у RGBA32 — 4 МБ VRAM. Ті ж дані у ASTC 6×6 — близько 250 КБ. При десятку таких текстур різниця стає істотною.
Розмір атласу не кратен степені двійки. GPU не умеет ефективно працювати з текстурами розміром 700×900. Unity попереджує, але не виправляє автоматично. Non-power-of-two текстури не стискаються більшістю форматів та займають більше пам'яті, ніж найближчий POT.
Один атлас для всього. Всі спрайти в одному атласі 4096×4096 — це 16 МБ лише для однієї текстури у RGBA32. При переході на інший екран весь атлас залишається у пам'яті, навіть використовуючи 10% спрайтів.
Прозорість там, де вона не потрібна. JPEG не можна використовувати для спрайтів з прозорістю, але PNG з цілком непрозорим фоном упаковується як RGBA замість RGB — зайвий канал без смислу.
Формати стиску: що вибрати
| Платформа | Формат | Якість | Застосування |
|---|---|---|---|
| Android (більшість) | ASTC 6×6 | висока | всі текстури |
| Android (legacy, API < 23) | ETC2 | середня | непрозорі; ETC2 RGB для alpha |
| iOS | ASTC 6×6 | висока | всі текстури |
| iOS (fallback) | PVRTC | низька | лише при крайній нехватці пам'яти |
ASTC — адаптивний, підтримує будь-яке співвідношення сторін, доступний на всіх пристроях з Android 5.0+ та iOS A8+. Для ігрових спрайтів 6×6 дає хорошее соотношение якість/розмір. Для UI з дрібним текстом — 4×4.
ETC2 на Android потрібен лише якщо цільова аудиторія — пристрої старше 2015 року. У 2024 році це рідкість, але якщо у проекту є дані аналітики з долею таких пристроїв > 5% — враховуємо.
Структура атласів по контексту
Правильна стратегія — розбивка атласів по контексту використання, а не по типу об'єкта:
- ui-hud: елементи HUD, відображувані постійно під час гри
- ui-menus: кнопки, фони, іконки для меню (вивантажуються під час геймплею)
- gameplay-player: спрайти гравця та його анімації
- gameplay-enemies-tier1: враги першого рівня
- gameplay-vfx: частиці, взривы, ефекти
Така розбивка дозволяє вивантажувати невикористовувані атласи через Resources.UnloadUnusedAssets() або Addressables з явним Release. При єдиному атласі на всю гру це неможливо.
Пусте місце у атласі
Unity SpriteAtlas залишає padding між спрайтами (за замовчуванням 4 px) для запобігання bleeding. На атласі 1024×1024 це може давати до 15–20% втрат площі. Padding можна зменшити до 2 px для спрайтів без субпіксельного рендерингу, й це помітно покращує упаковку.
Глянути реальний процент заповнення можна в Preview атласу в інспекторі. Якщо менше 70% — варто переробити розбивку.
Процес оптимізації
Починаємо з Memory Profiler (Window → Analysis → Memory Profiler) на реальному девайсі: дивимось раздел Textures, сортуємо по розміру. Беремо топ-10 найтяжелішіх текстур — в 80% випадків там несжаті атласи або PNG без platform-specific настроїок.
Далі: настройка Overrides для Android/iOS у кожному атласі, реструктуризація по контексту використання, настройка Mip Maps (для 2D-ігор зазвичай вимикаємо — економія 33% пам'яти на кожній текстурі), перевірка POT-розмірів.
Фінальна перевірка — Android GPU Inspector або Xcode Metal System Trace. Дивимось розмір VRAM до та після.
Терміни: три-шість робочих днів залежно від кількості атласів та наявності Addressables у проекті.







