Как уменьшить количество вызовов draw calls?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Оптимизация Draw Calls в Unity
Уменьшение количества draw calls — критическая задача для производительности игры. Draw call — это команда, отправляемая видеокартой для отрисовки объекта. Каждый вызов требует переключения состояния графического конвейера, что является узким местом даже на мощном оборудовании.
Основные техники оптимизации
1. Batching (объединение объектов)
-
Static Batching: объединение статичных объектов в один меш на этапе разработки. Экономит draw calls за счёт снижения данных, отправляемых на видеокарту. Увеличивает использование памяти, но для статичных объектов это приемлемо.
-
Dynamic Batching: автоматическое объединение динамичных объектов за один вызов. Работает для объектов с одинаковым материалом, если их меш содержит менее 900 вертексов (для SkinnedMeshRenderer — менее 300).
-
GPU Instancing: техника рендеринга множества одинаковых объектов за один draw call. Используется для травы, деревьев, врагов. Требует специального шейдера с поддержкой instancing.
// Включение GPU Instancing в материале
material.enableInstancing = true;
2. Atlas текстур и материалы
-
Используй Atlas вместо отдельных текстур. Один draw call может отрисовать разные объекты, если они используют одну текстуру с разными UV координатами.
-
Минимизируй количество уникальных материалов. Один материал — один draw call за набор объектов.
3. Управление LOD (Level of Detail)
Создавай несколько версий модели разного качества. На дальних дистанциях используй более простые версии.
LODGroup lodGroup = GetComponent<LODGroup>();
// LOD Group автоматически выбирает уровень детализации
4. Occ Culling (окклюзионный culling)
Отключай рендеринг объектов, скрытых за другими. Unity автоматически подсчитывает видимость.
5. Отключение ненужных компонентов
- Отключай камеры, источники света, частицы, которые не видны.
- Используй Frustum Culling (отсечение за границами камеры) — включено по умолчанию.
6. Оптимизация UI
- UI Canvas каждого экрана требует отдельного draw call. Группируй элементы в один Canvas.
- Избегай пересоздания UI элементов часто — это вызывает rebuild Canvas.
Практический пример
// Правильно: используй GPU Instancing для рекурсивного рендеринга
Graphics.DrawMeshInstanced(mesh, 0, material, matrices, count);
// Неправильно: каждый объект отдельно
for (int i = 0; i < objects.Count; i++) {
Graphics.DrawMesh(objects[i].mesh, objects[i].transform.localToWorldMatrix, material, 0);
}
Инструменты профилирования
Используй Profiler (Window → Analysis → Profiler) для просмотра количества draw calls. Вкладка Rendering показывает статистику вызовов. Frame Debugger позволяет пошагово просмотреть все операции рендеринга.
Выводы
Комбинируй несколько техник: batching + atlas + LOD + culling. Профилируй регулярно. Оптимизация draw calls часто даёт 2-3x улучшение FPS на мобильных устройствах.