Производительность WebGPU vs WebGL

Графические приложения в браузере долгое время строились на основе WebGL — API, предоставляющего доступ к возможностям GPU через интерфейс, основанный на принципах OpenGL ES. Появление WebGPU изменило модель взаимодействия между JavaScript и графическим процессором, предложив значительно более низкоуровневый и предсказуемый механизм управления ресурсами и командами.

В контексте библиотеки Babylon.js оба интерфейса поддерживаются через разные движки рендеринга:

  • WebGLRenderingEngine
  • WebGPUEngine

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

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


Модель работы WebGL

WebGL построен на принципах немедленного режима исполнения команд. Каждый вызов API немедленно влияет на состояние графического контекста.

Пример типичной последовательности:

gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(0);
gl.drawArrays(gl.TRIANGLES, 0, vertexCount);

Каждый вызов:

  • изменяет состояние контекста
  • требует проверки валидности
  • может вызывать синхронизацию между CPU и GPU

Особенности производительности WebGL

Основные ограничения:

1. Высокая стоимость вызовов API

Каждый вызов WebGL проходит через слой валидации браузера.

2. Частые переключения состояния

Изменение:

  • буферов
  • текстур
  • шейдерных программ
  • параметров рендеринга

вызывает дополнительные накладные расходы.

3. Ограниченный контроль над памятью

WebGL автоматически управляет многими ресурсами, что снижает контроль над временем выделения и освобождения памяти GPU.

4. Низкая эффективность при большом количестве draw calls

Сцены с тысячами объектов приводят к значительным накладным расходам.


Архитектура WebGPU

WebGPU проектировался как современный графический API, близкий по концепции к:

  • Vulkan
  • Metal
  • Direct3D 12

Основная идея — разделение подготовки команд и их выполнения.

Типичный цикл WebGPU включает:

  1. Создание командного буфера
  2. Запись команд рендеринга
  3. Отправку буфера на GPU

Пример (упрощённая схема):

const commandEncoder = device.createCommandEncoder();

const pass = commandEncoder.beginRenderPass(renderPassDescriptor);

pass.setPipeline(pipeline);
pass.setVertexBuffer(0, vertexBuffer);
pass.draw(vertexCount);

pass.end();

device.queue.submit([commandEncoder.finish()]);

Ключевые преимущества

1. Предварительная запись команд

Команды формируются заранее и выполняются GPU без дополнительных проверок.

2. Минимизация синхронизации CPU–GPU

Браузер не вмешивается в каждый вызов API.

3. Явное управление ресурсами

Разработчик контролирует:

  • буферы
  • текстуры
  • пайплайны
  • дескрипторы

4. Высокая масштабируемость

Большое количество draw calls обрабатывается значительно эффективнее.


Реализация WebGPU в Babylon.js

Babylon.js реализует WebGPU через отдельный движок:

const engine = new BABYLON.WebGPUEngine(canvas);

await engine.initAsync();

После инициализации API Babylon.js остаётся практически неизменным:

const scene = new BABYLON.Scene(engine);

Это позволяет переключать backend без изменения логики сцены.

Внутри движка происходят существенные изменения:

Подсистема WebGL WebGPU
Шейдеры GLSL WGSL
Буферы GL Buffer GPUBuffer
Текстуры WebGLTexture GPUTexture
Команды immediate mode command buffers

Влияние количества draw calls

Один из главных факторов производительности графического приложения — количество draw calls.

Поведение WebGL

Каждый draw call требует:

  1. переключения состояния
  2. проверки валидности
  3. передачи команд драйверу

В сценах с тысячами объектов производительность резко падает.

Типичный предел:

2000–5000 draw calls

После этого наблюдается сильная нагрузка на CPU.

Поведение WebGPU

В WebGPU команды записываются в буфер и отправляются на GPU пакетно.

Это уменьшает накладные расходы CPU.

Практические тесты показывают, что WebGPU способен обрабатывать:

20 000 – 100 000 draw calls

без значительных потерь производительности.

Babylon.js дополнительно оптимизирует этот процесс через:

  • hardware instancing
  • thin instances
  • GPU buffer batching

Компиляция шейдеров

Шейдеры играют важную роль в производительности графического конвейера.

WebGL

Использует язык GLSL.

Проблемы:

  • компиляция происходит во время выполнения
  • драйвер GPU может выполнять дополнительные оптимизации
  • компиляция может блокировать поток

Пример:

gl.compileShader(shader);
gl.linkProgram(program);

При сложных сценах возможно заметное время загрузки.

WebGPU

Использует язык WGSL (WebGPU Shading Language).

Особенности:

  • строгая типизация
  • предсказуемая компиляция
  • меньше зависимостей от драйвера GPU

Babylon.js автоматически преобразует шейдеры системы материалов в WGSL при использовании WebGPU.


Управление памятью GPU

WebGL скрывает многие аспекты управления памятью.

Например:

gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);

В этом случае браузер и драйвер GPU самостоятельно решают:

  • где разместить буфер
  • когда его переместить
  • когда освободить память

Ограничения WebGL

  • возможные скрытые копирования памяти
  • неоптимальные размещения
  • непредсказуемые паузы

Подход WebGPU

WebGPU требует явного указания параметров буфера:

device.createBuffer({
    size: data.byteLength,
    usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST
});

Это позволяет:

  • оптимально размещать ресурсы
  • избегать лишних копирований
  • более эффективно использовать VRAM

Babylon.js автоматически создаёт такие буферы при загрузке геометрии.


Параллелизм и многопоточность

WebGL работает преимущественно в одном потоке JavaScript.

Даже при использовании Web Workers передача данных требует копирования или использования Transferable.

WebGPU

WebGPU изначально проектировался с учётом параллелизма.

Поддерживаются:

  • параллельная подготовка команд
  • асинхронные очереди
  • более эффективная работа с Web Workers

Это особенно важно для:

  • генерации процедурной геометрии
  • симуляций
  • сложных сцен.

Babylon.js использует этот потенциал при:

  • генерации теней
  • подготовке буферов
  • обновлении инстансов.

Производительность материалов

Материалы в Babylon.js создают значительную нагрузку на графический конвейер.

Сложные материалы включают:

  • multiple texture sampling
  • lighting calculations
  • PBR модели освещения

WebGL

Каждый материал требует:

  • отдельной программы шейдера
  • переключения pipeline

Это создаёт overhead.

WebGPU

Pipeline state создаётся заранее.

Babylon.js формирует pipeline cache, который снижает стоимость переключений.

Результат:

  • более быстрые переключения материалов
  • меньшая нагрузка на CPU.

Производительность постобработки

Постобработка (post-processing) включает:

  • bloom
  • SSAO
  • motion blur
  • depth of field

Каждый эффект требует дополнительных проходов рендеринга.

WebGL

Каждый проход:

  • переключает framebuffer
  • устанавливает новые текстуры
  • запускает отдельный draw call

WebGPU

Render pass может объединять несколько операций.

Это уменьшает:

  • переключения состояния
  • количество синхронизаций.

Babylon.js оптимизирует post-processing через render graph, особенно эффективно при использовании WebGPU.


Пропускная способность передачи данных

Передача данных между CPU и GPU является критическим фактором.

WebGL

Обновление буфера:

gl.bufferSubData(...)

Может вызывать:

  • блокировки
  • синхронизацию.

WebGPU

Использует staging buffers и асинхронные операции:

queue.writeBuffer(...)

Это позволяет:

  • обновлять данные без блокировки GPU
  • выполнять загрузку ресурсов параллельно.

Практическая производительность в Babylon.js

Результаты тестирования сложных сцен показывают:

Параметр WebGL WebGPU
draw calls ~3000 >30000
CPU нагрузка высокая ниже
загрузка шейдеров медленнее быстрее
масштабируемость ограничена высокая

Наиболее заметный прирост наблюдается в:

  • больших сценах
  • CAD-визуализациях
  • симуляциях
  • сложных PBR-материалах.

Ограничения WebGPU

Несмотря на преимущества, WebGPU имеет ряд ограничений.

1. Поддержка браузеров

Поддержка постепенно расширяется, но всё ещё уступает WebGL.

Наиболее стабильная реализация присутствует в:

  • Chrome
  • Edge

Safari и Firefox внедряют поддержку постепенно.

2. Увеличенная сложность реализации

WebGPU требует:

  • управления пайплайнами
  • работы с дескрипторами
  • контроля памяти

Babylon.js скрывает большую часть этой сложности, однако внутренняя архитектура движка становится значительно более сложной.

3. Потребление памяти

Явное управление ресурсами может приводить к большему использованию VRAM, если ресурсы не освобождаются своевременно.


Сценарии, где WebGPU даёт наибольший выигрыш

Максимальный прирост производительности наблюдается в следующих случаях:

Большие сцены

10 000+ объектов

Инстансинг

100 000+ экземпляров моделей

Сложные PBR материалы

Большое количество источников света

Интенсивная постобработка

В простых сценах разница между WebGL и WebGPU может быть минимальной, поскольку узким местом становится не GPU, а логика JavaScript.


Эволюция Babylon.js в сторону WebGPU

Развитие движка Babylon.js постепенно смещается в сторону WebGPU.

Основные направления оптимизации:

  • новый shader pipeline
  • улучшенное управление ресурсами
  • GPU driven rendering
  • compute shaders

Compute shaders открывают новые возможности:

  • GPU-симуляции
  • обработка частиц
  • процедурная генерация.

Эти возможности практически недоступны в WebGL.


Вывод о сравнительной производительности

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

WebGPU предоставляет:

  • более эффективное использование GPU
  • снижение нагрузки на CPU
  • значительно лучшую масштабируемость

В контексте Babylon.js WebGPU становится основой для построения высокопроизводительных 3D-приложений следующего поколения.