Оптимизация рендеринга мобильной игры

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.
Разработка и поддержка любых видов мобильных приложений:
Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 1735 услуг
Оптимизация рендеринга мобильной игры
Сложная
~3-5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    445

Оптимизация рендеринга мобильной игры

На Samsung Galaxy A52 (Adreno 618) игра держит 28–32 FPS при целевых 60. На Xiaomi Redmi Note 11 с Helio G96 и Mali-G57 — стабильные 55–60 FPS. Разная производительность на похожих по цене устройствах — типичная ситуация для мобильного геймдева. Причина почти всегда в том, что оптимизация проводилась на флагмане, а mid-range GPU с другой архитектурой даёт совсем другую картину.

Диагностика: что тормозит

CPU-bound vs GPU-bound

Прежде чем оптимизировать — понять что является bottleneck. В Unity: Frame Debugger + Profiler. Включаем Profile GPU в Android Player Settings и смотрим Profiler → GPU. Если GPU-время на кадр близко к 16ms (60 FPS) а CPU-время значительно меньше — GPU-bound. Если наоборот — CPU-bound.

На Unreal Engine: stat GPU в консоли, ProfileGPU команда, RenderDoc для захвата кадра. r.ScreenPercentage 50 — быстрый тест: если FPS резко вырос при снижении разрешения вдвое — точно GPU-bound.

// Unreal console commands для диагностики
stat unit       // общий breakdown CPU/GPU/frame time
stat drawcalls  // количество draw calls текущего кадра
r.ShowFlag.Rendering 1 // включаем detailed rendering stats

Draw calls

На мобильных GPU draw call overhead выше чем на консолях/PC. 500+ draw calls в кадре — красная зона для mid-range Android. Каждый уникальный материал = отдельный draw call. Каждый MeshRenderer с уникальным материалом = ещё один.

Static batching (Unity): объекты с одинаковым материалом объединяются в один mesh. Требование — одинаковый Material asset (не просто одинаковые настройки). Mark as Static в Inspector. Работает автоматически при сборке.

GPU Instancing: для повторяющихся объектов (трава, деревья, враги одного типа):

// Материал должен поддерживать instancing
material.enableInstancing = true;

// Рисуем 1000 экземпляров одним draw call
Graphics.DrawMeshInstanced(mesh, 0, material, matrices, 1000);

SRP Batcher (Unity URP/HDRP): автоматически батчит объекты с разными материалами но одинаковым шейдером. Включается в URP Asset → SRP Batcher = enabled. Самый простой способ сократить draw calls без ручного batching.

Шейдеры для мобильных GPU

Tile-based rendering (TBIMR)

Мобильные GPU (Adreno, Mali, PowerVR, Apple) используют Tile-Based Immediate Mode Rendering. Экран делится на тайлы, каждый рендерится целиком в быстром on-chip памяти. Это означает:

  • Framebuffer fetch — чтение из текущего framebuffer внутри тайла — практически бесплатно. Используем для deferred lighting: gl_LastFragData в GLSL (GLES extension EXT_shader_framebuffer_fetch).
  • Depth pre-pass на мобиле — часто лишний overhead, TBIMR и так эффективно работает с depth test внутри тайла.
  • Discard в фрагментном шейдере (alpha-test, clip) — на tile-based GPU убивает ранний depth test для целого тайла. Заменяем alpha-blend или alpha-to-coverage там где возможно.

Precision qualifiers в GLSL/Metal

// МЕДЛЕННО — highp везде по умолчанию
uniform highp mat4 ModelMatrix;
varying highp vec2 TexCoord;

// БЫСТРО — минимально необходимая точность
uniform highp mat4 ModelMatrix;    // матрицы — highp обязательно
varying mediump vec2 TexCoord;     // UV-координаты — mediump достаточно
varying lowp vec4 VertexColor;     // цвет — lowp

На Mali GPU переход с highp на mediump для texture samplers — от 10 до 25% прирост производительности фрагментного шейдера.

ALU vs Texture Fetch

На большинстве мобильных GPU texture fetch дешевле чем тяжёлые ALU-вычисления (sin, pow, sqrt). Предварительно запечённые lookup таблицы в текстуре быстрее чем вычисление в шейдере:

// Медленно: вычисляем fresnel в шейдере
float fresnel = pow(1.0 - dot(viewDir, normal), 5.0);

// Быстро: lookup texture
float fresnel = texture2D(fresnelLUT, vec2(dot(viewDir, normal), roughness)).r;

Разрешение и Dynamic Resolution Scaling

Рендерить в нативном разрешении iPhone 15 Pro (2556×1179) — избыточно для мобильной игры с интенсивным рендерингом. Стандартная практика — render scale 0.7–0.85 от нативного с последующим upscale.

Unity URP Dynamic Resolution:

ScalableBufferManager.ResizeBuffers(0.75f, 0.75f); // 75% от нативного

Unreal Mobile Super Resolution (MSR) — встроенный temporal upscaler для мобильных платформ с Unreal 5.1+. r.Mobile.TemporalAA 1. Даёт качество близкое к нативному при значительно меньшей GPU-нагрузке.

Adaptive Performance (Samsung Game SDK + Unity): автоматически снижает нагрузку при перегреве:

using UnityEngine.AdaptivePerformance;
var ap = Holder.Instance;
ap.ThermalStatus.ThermalMetrics // текущая температура
ap.PerformanceStatus.PerformanceMetrics // bottleneck info

Кейс: 40 → 58 FPS на Adreno 618

Runner-игра: на Galaxy A52 — 40 FPS. Профилирование через AGI показало: Fragment ALU 87%, fragment bandwidth — перегружен. Три изменения:

  1. Шейдер воды: заменили pow(fresnel, 5.0) на LUT-текстуру → -8ms GPU
  2. highpmediump для всех texture samplers → -4ms GPU
  3. Dynamic resolution 0.80 вместо нативного → -6ms GPU

Итого: с 40 до 58 FPS без изменения визуального стиля. На Pro-устройствах — без изменений, они держали 60 FPS с запасом.

Сроки

Профилирование и анализ рендеринга — 2–3 дня. Оптимизация шейдеров, batching, dynamic resolution — 1–3 недели в зависимости от состояния проекта.