Ольга Стефанишина
← Назад

Начало работы с WebGL 2: Путь разработчика

Недавно я начала изучать WebGL 2, и обнаружила, что один из лучших способов закрепить новые знания — поделиться ими с другими. Я публиковала обновления в X (Twitter), но этот формат слишком ограничен для технических статей, поэтому я решила расширить свой опыт и начать писать статьи, чтобы задокументировать свой путь в мире графического программирования для браузеров.

Что такое WebGL 2?

WebGL (Web Graphics Library) — это JavaScript API, который позволяет отображать интерактивную 2D и 3D графику в совместимых веб-браузерах без необходимости использования плагинов. Он основан на OpenGL ES (Embedded Systems), специально разработанном для мобильных устройств и веб-приложений.

Это принципиально отличается от традиционных манипуляций с DOM. В то время как операции DOM в основном работают с элементами в древовидной структуре, WebGL 2 предоставляет низкоуровневый доступ к видеокарте через элемент canvas, позволяя использовать аппаратно-ускоренный рендеринг графики.

Вот простой пример инициализации контекста WebGL 2:

javascript
1// Получаем элемент canvas
2const canvas = document.getElementById('myCanvas');
3
4// Инициализируем контекст WebGL 2
5const gl = canvas.getContext('webgl2');
6
7if (!gl) {
8 console.error('WebGL 2 не поддерживается или не включен в этом браузере');
9 // Запасной вариант или сообщение об ошибке
10} else {
11 console.log('WebGL 2 успешно инициализирован');
12}

Чтобы лучше понять разницу в сложности между этими API, давайте сравним, что требуется для отрисовки простого красного квадрата в Canvas 2D и WebGL 2:

javascript
1// CANVAS 2D API - Рисуем красный квадрат (3 строки кода)
2const ctx = canvas.getContext('2d');
3ctx.fillStyle = 'red'; // Устанавливаем цвет на красный
4ctx.fillRect(10, 10, 100, 100); // Рисуем квадрат 100x100 в позиции (10,10)
5
6// WEBGL 2 - Рисуем красный квадрат (упрощенно, но все равно минимум ~30 строк)
7const gl = canvas.getContext('webgl2');
8
9// 1. Определяем вершинный шейдер (выполняется один раз для каждой вершины)
10const vertexShaderSource = `#version 300 es
11in vec4 a_position;
12void main() {
13 gl_Position = a_position;
14}`;
15
16// 2. Определяем фрагментный шейдер (выполняется один раз для каждого пикселя)
17const fragmentShaderSource = `#version 300 es
18precision highp float;
19out vec4 outColor;
20void main() {
21 outColor = vec4(1.0, 0.0, 0.0, 1.0); // Красный цвет
22}`;
23
24// 3. Создаем и компилируем шейдеры
25// ... (пропущено несколько строк кода настройки)
26
27// 4. Создаем программу и связываем шейдеры
28// ... (пропущено больше кода настройки)
29
30// 5. Определяем геометрию для квадрата
31// ... (пропущено больше кода настройки)
32
33// 6. Наконец, рисуем
34gl.clearColor(0.0, 0.0, 0.0, 1.0); // Очищаем до черного
35gl.clear(gl.COLOR_BUFFER_BIT);
36gl.useProgram(program);
37gl.bindVertexArray(vao);
38gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); // Рисуем квадрат

Это сравнение иллюстрирует фундаментальный компромисс: Canvas 2D разработан для простоты и требует минимум кода для базовых операций, в то время как WebGL 2 требует больше настроек, но дает прямой контроль над конвейером рендеринга GPU. Эта дополнительная сложность обеспечивает продвинутую 3D-графику и производительность, для которых и разработан WebGL 2.

Используя ускорение GPU, WebGL 2 может отображать сложные 3D-сцены со скоростью 60 кадров в секунду или выше, что позволяет создавать приложения, такие как:

  • Интерактивные 3D-визуализации данных
  • Браузерные игры с продвинутой графикой
  • Инструменты для архитектурной и продуктовой визуализации
  • Физические симуляции и системы частиц
  • Обработка изображений и фильтры с производительностью в реальном времени

Цена? Более крутая кривая обучения по сравнению с другими веб-технологиями, но вознаграждение — это огромная визуальная мощь, которая ранее была доступна только в нативных приложениях.

WebGL 2 как машина состояний

Одна из первых концепций, которую необходимо понять — это то, что WebGL 2 функционирует как машина состояний. Это означает, что его операции зависят от ранее установленных состояний, а не исключительно от параметров, переданных функциям — фундаментальная характеристика, которая делает WebGL 2 отличным от типичных паттернов JavaScript.

Диаграмма машины состояний WebGL 2
Диаграмма машины состояний WebGL 2

В большинстве JavaScript-кода поведение функции определяется в основном параметрами, которые вы в неё передаёте:

javascript
1// Обычный JavaScript: поведение определяется параметрами
2const result = calculateSomething(paramA, paramB);

WebGL 2, однако, работает иначе:

javascript
1// Устанавливаем состояние
2gl.useProgram(shaderProgram);
3gl.uniform1f(uniformLocation, 0.5);
4
5// Поведение этой функции зависит от состояний, установленных выше
6gl.drawArrays(gl.TRIANGLES, 0, 3);

В этом примере drawArrays() будет использовать те программы шейдеров и значения uniform, которые были ранее установлены. Понимание этой архитектуры, основанной на состояниях, крайне важно для эффективного программирования на WebGL 2.

Программируемый конвейер

Фундаментальным аспектом WebGL 2 является его улучшенный программируемый конвейер, реализованный через шейдерные программы.

Существует две обязательных шейдерных программы, которые нужно написать:

  • Вершинный шейдер: Выполняется один раз для каждой вершины. Должен вывести gl_Position (позиция в пространстве отсечения)
  • Фрагментный шейдер: Выполняется один раз для каждого фрагмента (потенциального пикселя). Должен вывести значение цвета

Вот минимальный пример обоих с использованием GLSL 3.00 ES (язык шейдеров для WebGL 2):

glsl
1// Вершинный шейдер (GLSL 3.00 ES)
2#version 300 es
3in vec4 position;
4void main() {
5 gl_Position = position;
6}
7
8// Фрагментный шейдер (GLSL 3.00 ES)
9#version 300 es
10precision highp float;
11out vec4 outColor;
12void main() {
13 outColor = vec4(1.0, 0.0, 0.0, 1.0); // Красный цвет
14}

Обратите внимание на ключевые отличия от WebGL 1:

  • Объявление #version 300 es
  • Использование in вместо attribute
  • Использование out для выходных данных вместо встроенных переменных вроде gl_FragColor

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

WebGL 2 значительно улучшает этот конвейер с такими функциями, как:

  • Несколько целей рендеринга
  • Трансформационная обратная связь
  • Объекты буферов uniform
  • Инстансинг
  • Целочисленные текстуры и операции

До программируемых шейдеров графическое оборудование использовало "конвейер с фиксированными функциями" с встроенными, неизменяемыми алгоритмами для:

  • Трансформации вершин (умножение на матрицы)
  • Освещения (обычно модель Фонга или Блинна-Фонга)
  • Наложения текстур (только базовая выборка)
  • Расчетов тумана
  • Смешивания цветов

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

Система координат WebGL 2

Ещё одна важная концепция — это система координат WebGL 2, которая принципиально отличается от того, к чему привыкли веб-разработчики в CSS.

В WebGL 2:

  • Начало координат (0,0) находится в центре холста, а не в верхнем левом углу
  • Ось Y направлена вверх (положительные значения вверх), а не вниз
  • Все координаты нормализованы между -1.0 и 1.0 независимо от размера холста
Система координат WebGL, показывающая нормализованные координаты устройства с началом координат (0,0) в центре
Система координат WebGL, показывающая нормализованные координаты устройства с началом координат (0,0) в центре

Понимание этой системы координат с самого начала помогает предотвратить распространенные ошибки позиционирования и ориентации в ваших проектах WebGL 2.

##Что дальше

В этой статье были рассмотрены основы WebGL 2. В следующих публикациях я детально разберу: работу с шейдерами, методы оптимизации, построение модели для симуляции.

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


Эта статья входит в цикл материалов по созданию интерактивных 3D-визуализаций на WebGL 2.

Поговорим?