Оптимізація відрисовки (Draw Calls) в іграх

Наша компанія з розробки відеоігор веде незалежні проекти, спільно з клієнтом створює ігри та надає додаткові операційні послуги. Досвід нашої команди дозволяє нам охопити всі ігрові платформи та розробити приголомшливий продукт, що відповідає баченню клієнта та перевагам гравців.

Від імерсивних застосунків до ігрових світів і 3D-сцен

Наша виділена команда для VR/AR/MR-розробки, Unity-продакшну і 3D-моделювання та анімації — з власними кейсами і презентаціями.

Відвідати персоналізований сайт
Показано 1 з 1 послугУсі 242 послуг
Оптимізація відрисовки (Draw Calls) в іграх
Складна
від 2 робочих днів до 2 тижнів
Часті питання

Наші компетенції

Які етапи розробки гри?

Останні роботи

  • image_games_mortal_motors_495_0.webp
    Розробка гри для компанії Mortal Motors
    683
  • image_games_a_turnbased_strategy_game_set_in_a_fantasy_setting_with_fire_and_sword_603_0.webp
    Покрокова стратегія у фентезі сеттингу With Fire And Sword
    862
  • image_games_second_team_604_0.webp
    Розробка ігри для компанії Second term
    491
  • image_games_phoenix_ii_606_0.webp
    3D-анімація – тизер для гри phoenix 2.
    533

Оптимізація отрисовки (Draw Calls) у грах

200 Draw Calls на мобільному пристрої при отрисовці UI через Canvas у Overlay-режимі — це не рідкість. Це типова ситуація на проекті, який «просто зробили», не думаючи про batching-стратегію з самого початку. До того моменту, коли починається оптимізація, у сцені вже 15 унікальних матеріалів на UI-елементах, кожен Sprite рендерится окремим викликом, а GPU на iPhone 12 видає 28 fps там, де повинно бути 60.

Draw Call — це команда CPU до GPU: «нарисуй вот цій mesh з вот цім матеріалом». Кожен виклик несе overhead на стороні CPU (State Change, Command Buffer preparation). На мобільних чипах цей overhead критичний. На PC — менше, але теж рахується.

Де Draw Calls розростаються безконтрольно

Найчастіший джерело — Unity Canvas. Стандартна помилка: кілька Canvas-елементів з різними матеріалами в одному Canvas Root. Кожна смена матеріалу — новий Draw Call. Рішення: всі UI-спрайти в один Sprite Atlas, один матеріал на весь Canvas. Canvas Rebuild при зміні одного елемента перерисовує весь Canvas — розбиваємо динамічні елементи в дочірній Canvas.

Skinning та анімовані персонажі. SkinnedMeshRenderer не бере участь у стандартному Static Batching та погано підтримує GPU Instancing у Unity (потрібен кастомний підхід через Graphics.DrawMeshInstanced з попередньо обчисленими bone matrices). Якщо у сцені 50 однакових NPC — це 50 окремих Draw Calls по замовчуванню.

Particle System з унікальними матеріалами. Кожна Particle System з унікальним матеріалом — окремий Draw Call, навіть якщо система складається з 2 частинок. На мобільному проекті бачили 60 Draw Calls тільки від партиклів в одній локації.

Dynamic GI та real-time освітлення. Кожен додатковий real-time джерело світла у Forward Rendering збільшує Draw Calls пропорційно кількості об'єктів, що потрапили в радіус. 3 point-light'а у кімнаті × 20 об'єктів = 60 додаткових викликів. Deferred Rendering вирішує це архітектурно, але вимагає підтримки G-Buffer.

Інструменти та конкретні техніки зниження

SRP Batcher — перше, що включаємо у URP/HDRP проектах. Не зменшує кількість Draw Calls, але резко знижує CPU overhead через уніфікацію Constant Buffer layout. Вимагає, щоб всі шейдери були SRP Batcher-compatible (перевіряємо в Shader Inspector — повинна бути напис «compatible»). Якщо шейдер написаний під Built-in Pipeline та не переписаний — SRP Batcher на нього не поширюється.

GPU Instancing — для повторюючихся мешів з одним матеріалом. Включається галочкою у Material Inspector. У нативному виді працює тільки для однакових мешів з однаковими матеріалами. Для різних кольорів/параметрів — MaterialPropertyBlock. Типовий кейс: 200 дерев одного типу → 1 Draw Call замість 200.

Static Batching — помічаємо статичні об'єкти як Static, Unity при сборці об'єднує їхні меші в один великий VBO. Мінус: збільшується споживання пам'яті, так як кожен batched mesh зберігається окремо. На мобільних проектах з обмеженою RAM — баланс між Draw Calls та пам'яттю.

Dynamic Batching — для дрібних мешів (менше 900 вершин). У URP включений по замовчуванню, але на практиці майже не працює для більшості ігрових об'єктів — надто суворі вимоги до verts count та UV-каналів. Краще не розраховувати на нього як на основний інструмент.

Frame Debugger — основний інструмент діагностики. Відкриваємо, починаємо Play, натискаємо Enable. Бачимо кожен Draw Call з поясненням, чому він не був batched («different materials», «not in same layer», «different lightmap indices»). Саме тут розумієм реальну картину, а не ту, що показує Stats у Game View.

Реальний кейс: мобільна Tower Defense, сцена з 380 Draw Calls. Frame Debugger показав: 80 веж одного типу — не інстансяться, тому що у кожної унікальний LightProbe baked (через те, що вони були перемішені після запічки освітлення та не переіндексовані). Пересборка Light Probe Groups + включення GPU Instancing → 80 викликів перетворилися на 4. Загальний результат по сцені: 380 → 140 Draw Calls, fps на Samsung Galaxy S21 виріс з 38 на 58.

Як вибудовуємо роботу

Перший крок — знімаємо метрики через Unity Profiler у режимі Standalone (не Editor). Editor додає свої виклики та спотворює картину. Підключаємо пристрій через USB, Deep Profile тільки якщо потрібна точна атрибуція по скриптам.

Аналізуємо через Frame Debugger категорії Draw Calls: UI, Environment, Characters, VFX, Shadow Casters. Для кожної категорії — своя стратегія batching.

Готуємо план змін з оцінкою impact. Зміна стратегії batching для UI займає 1–2 дні. Переробка архітектури матеріалів для персонажів — тиждень. Впровадження GPU Instancing для рослинності — 2–3 дні.

Масштаб завдання Орієнтовні строки
Аудит + звіт з рекомендаціями 2–3 дні
Оптимізація UI-шару (Canvas batching) 3–5 днів
Оптимізація ігрової сцени (оточення + пропси) 1–3 тижні
Повна переробка Draw Call-стратегії проекту 4–8 тижнів

Вартість розраховується індивідуально після аудиту проекту.