Управление drawcalls: профилирование

Введение в drawcalls

Drawcall — это команда, которую графический процессор (GPU) получает от процессора (CPU) для рендеринга объектов в сцене. В контексте игровых движков и 3D-графики drawcall означает отправку данных о геометрии, материалах и других объектах в GPU для рендеринга. Чем больше drawcalls, тем выше нагрузка на систему и, как следствие, хуже производительность игры или приложения.

PlayCanvas предоставляет механизмы для мониторинга и оптимизации drawcalls, что критично для достижения высокой производительности в веб-играх и приложениях. Понимание работы с drawcalls и использование инструментов профилирования позволяет минимизировать их количество, ускоряя рендеринг и обеспечивая плавную работу на различных устройствах.

Что влияет на количество drawcalls?

Количество drawcalls в сцене зависит от множества факторов, включая:

  • Количество объектов на сцене: каждый объект, который использует разные материалы или шейдеры, может требовать отдельного drawcall.
  • Использование текстур и материалов: объекты, использующие разные текстуры или материалы, часто требуют отдельного drawcall для каждого материала.
  • Использование разных шейдеров: если на сцене есть объекты с различными шейдерами, это может увеличить количество drawcalls.
  • Геометрия объектов: сложные объекты с большим количеством полигонов могут потребовать большее количество drawcalls для рендеринга.
  • Прозрачные объекты: объекты, отображаемые с прозрачными текстурами, часто требуют дополнительных drawcalls из-за особенностей их рендеринга.

Профилирование drawcalls в PlayCanvas

PlayCanvas предлагает встроенные инструменты для профилирования и мониторинга drawcalls, что позволяет разработчикам отслеживать производительность и предпринимать меры по её улучшению.

Профилирование с помощью stats

В PlayCanvas есть инструмент pc.stats, который позволяет получить информацию о различных аспектах производительности, включая количество drawcalls. Этот объект предоставляет данные о производительности сцены в реальном времени. Основные метрики, связанные с drawcalls:

  • drawCalls: количество выполненных drawcalls.
  • triangles: количество треугольников, отрендеренных за один кадр.
  • vertices: количество вершин, участвующих в рендеринге.

Использование pc.stats позволяет отслеживать и анализировать, как различные элементы сцены влияют на общую производительность.

// Пример использования pc.stats для вывода статистики по drawcalls
console.log('Draw Calls: ', app.graphicsDevice.stats.drawCalls);
console.log('Triangles: ', app.graphicsDevice.stats.triangles);
console.log('Vertices: ', app.graphicsDevice.stats.vertices);

Этот код выводит в консоль количество drawcalls, треугольников и вершин, что помогает разработчикам выявить узкие места в производительности.

Использование инструментов разработчика в браузере

Кроме стандартного профилирования через PlayCanvas API, можно использовать встроенные инструменты разработчика в браузере (например, Google Chrome DevTools), чтобы анализировать производительность. Вкладка “Performance” позволяет записывать и анализировать рендеринг сцены, показывая, сколько времени занимает каждый drawcall. Это особенно полезно для выявления источников задержек и оптимизации кода.

Оптимизация drawcalls

Уменьшение количества drawcalls — ключевая задача для улучшения производительности 3D-приложений. В PlayCanvas существует несколько подходов, которые помогают минимизировать количество drawcalls:

1. Объединение объектов

Если несколько объектов используют одинаковые материалы и шейдеры, их можно объединить в один объект, что сократит количество drawcalls. В PlayCanvas для этого используется механизм “Batching”, который позволяет группировать геометрии с одинаковыми материалами в один drawcall.

// Включение автоматической оптимизации батчинга
app.graphicsDevice.setRenderTarget(null);
app.scene.render();

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

2. Использование атласов текстур

Если в сцене используется множество текстур, можно объединить их в один атлас текстур. Это позволяет уменьшить количество drawcalls, поскольку объекты, использующие разные текстуры, могут быть сгруппированы и отрендерены одним drawcall.

// Пример использования атласа текстур
var textureAtlas = new pc.Texture(app.graphicsDevice, {
    width: 1024,
    height: 1024,
    format: pc.PIXELFORMAT_R8_G8_B8_A8
});
// Загрузка текстур в атлас
textureAtlas.setSource([texture1, texture2, texture3]);

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

3. Использование Instancing

PlayCanvas поддерживает технику instancing, которая позволяет рендерить множество экземпляров одного и того же объекта, используя один drawcall. Это особенно полезно для сцены с множеством одинаковых объектов, например, деревьев или камней в ландшафтных сценах.

var model = new pc.Model();
var instances = [];
for (var i = 0; i < 1000; i++) {
    var instance = new pc.Entity();
    instance.model = model;
    instances.push(instance);
}

// Рендеринг с использованием одного drawcall
app.scene.render();

Таким образом, вместо того чтобы отправлять множество отдельных drawcalls для каждого объекта, можно рендерить несколько экземпляров за один раз.

4. Оптимизация прозрачных объектов

Прозрачные объекты требуют особого подхода к рендерингу, так как они часто рендерятся последними, с учетом порядка слоев. Рекомендуется использовать прозрачность только там, где это абсолютно необходимо, и применять оптимизацию через технику “cutout” или “alpha testing”, чтобы уменьшить количество прозрачных объектов.

material.blendType = pc.BLEND_NORMAL;
material.alphaTest = 0.5;

Эти настройки позволяют уменьшить количество необходимых drawcalls для прозрачных объектов, повышая общую производительность.

Заключение

Оптимизация drawcalls является важной частью разработки производительных 3D-приложений в PlayCanvas. Использование методов, таких как batching, instancing, атласы текстур и оптимизация прозрачных объектов, позволяет существенно улучшить производительность, минимизируя нагрузку на систему. Регулярное профилирование и мониторинг с помощью инструментов PlayCanvas и внешних средств помогает вовремя выявлять узкие места и предпринимать меры для улучшения работы приложения.