Серия WebGL едет на ветру и волны - узнавать WebGL

JavaScript
Серия WebGL едет на ветру и волны - узнавать WebGL

передняя часть Seewo ENOW

Официальный сайт компании: CVTE (Гуанчжоу CVTE)

Команда: enow team центра программных платформ Seewo для будущего образования в рамках CVTE

Автор этой статьи:

Знакомство с WebGL

В области внешнего интерфейса мы можем рисовать графику четырьмя способами, включая HTML+CSS, SVG, Canvas2d и WebGL.WebGL — очень редко используемый метод рисования, но он занимает незаменимую позицию. Далее, давайте начнем с этих четырех методов рисования, чтобы понять WebGL.

Четыре способа рисовать интерфейсную графику

HTML+CSS

HTML+CSS является наиболее часто используемым способом рисования графики, его работа проста, а производительность в целом хорошая Событие Dom можно использовать для привязки графических событий, но это не так удобно при работе со сложной и нестандартной графикой.
image.png

SVG

SVG — это формат изображения, основанный на синтаксисе XML, поэтому он имеет характеристики привязки событий HTML. SVG также обеспечивает богатую инкапсуляцию, которая может легко реализовать графику, такую ​​как прямоугольники, круги и кривые Безье. В то же время он имеет множество встроенных эффектов фильтрации.По сравнению с HTML+CSS, SVG может очень удобно и быстро реализовывать сложные неправильные формы. При этом SVG можно увеличивать и уменьшать по желанию без искажений. Конечно, SVG всегда основан на узлах Dom, поэтому, если количество узлов велико, производительность рендеринга также снизится.
svg-anim-low.gif

Canvas2d

Canvas2d выполняет динамическое рисование с помощью инструкций JavaScript, поэтому он имеет очень гибкие возможности логической обработки и может сохранять и восстанавливать состояние холста и другие операции. В то же время Canvas может выполнять операции на уровне пикселей, поэтому он может создавать более интересные эффекты, такие как различные эффекты фильтров изображений.
image.png
По сравнению с SVG, в котором требуется манипулировать несколькими тегами HTML, Canvas2d нужно манипулировать только одним тегом Canvas, поэтому при рисовании той же сложной графики Canvas2d будет работать лучше. Как показано на рисунке ниже, с увеличением графической области время рендеринга Canvas2d будет становиться все больше и больше, а при постоянном увеличении количества элементов в сцене время рендеринга Canvas2d не столь очевидно. по сравнению с СВГ.
image.png

WebGL

Вышеупомянутые три метода рисования все являются обработкой 2D-графики.Что касается обработки 3D, это может быть достигнуто только с помощью подключаемых модулей браузера, таких как Flash или SilverLight.Появление стандарта WebGL позволяет нам использовать более унифицированный и стандартный способ. Рисовать 3д графику. Проще говоря, WebGL — это OpenGL ES, использующий язык Javascript, но рисующий графику в элементе Canvas HTML.
image.png
В дополнение к рисованию 3D-графики WebGL может напрямую вызывать базовый интерфейс для достижения характеристик аппаратного ускорения.WebGL имеет лучшую производительность, чем Canvas2d, при рендеринге 2D-графики. Как показано ниже, тот же алгоритм используется для достижения эффекта растворения изображения.Рисунок 1 — это решение Canvas2d, а рисунок 2 — решение WebGL.Наблюдая за значением FPS, вы можете видеть, что решение WebGL относительно более плавное.

Для HTML/CSS, SVG и Canvas нам не нужно заботиться об их конкретных базовых механизмах, мы можем напрямую использовать предоставляемые ими теги и API для рисования графики.Например, нам нужно только понять объявления рисования для создания Элементы SVG и научитесь выполнять инструкции по рисованию, соответствующие Canvas. , график можно вывести. Однако WebGL может рисовать только основные примитивы, такие как точки, отрезки и треугольники.Если вы хотите использовать WebGL для выполнения более сложных задач, вам необходимо предоставить соответствующий код и использовать комбинацию точек, линий и треугольников вместо реализации. . Итак, чтобы рисовать с помощью WebGL, мы должны вникать в детали. Другими словами, нам приходится иметь дело с памятью, графическим процессором и действительно контролировать каждую деталь вывода графики.

Основы графики

графическая система

Графическая система в основном разделена на 6 основных элементов, а именно устройство ввода, ЦП, ГП, память, буфер кадра и устройство ввода.
图形系统组成.jpg
ЦП в основном отвечает за загрузку и подготовку данных сцены, настройку состояний рендеринга, таких как материалы, текстуры и свойства источника света, рендеринг основных графических блоков и отправку инструкций графическому процессору.
Графический процессор получает инструкции от ЦП для рисования графики и генерирует массивы пикселей для ввода в буфер кадров посредством обработки вершин и обработки фрагментов.
Буфер кадра используется для хранения пикселей. Количество пикселей в буфере называется разрешением. Глубина буфера кадра указывает количество битов, используемых каждым пикселем, что определяет, сколько цветов может представлять система. Например, кадровый буфер с глубиной 8 бит может отображать 256 (2^8) цветов.
framebuffer.jpg

Конвейер отрисовки графики

Конкретный процесс графического рендеринга называется конвейером рендеринга, конвейер включает в себя две функции: во-первых, 3D-координаты объекта в координатах 2D-пространства экрана, а во-вторых, окрашивание каждого пикселя экрана, рендеринг общей линии потока, как показано ниже. Это: обработка вершин и сборка режущих элементов, процесс растеризации.
图形绘制流水线.jpg
Обработка вершин: этот процесс в основном для выполнения преобразования координат на вершинах, преобразуя объект из его представления в определенной системе координат к системе координат под камерой.
image.png
Примитивная сборка и отсечение: Примитивная сборка относится к объединению вершин для создания примитивов (точек/линий/треугольников), отсечение относится к отсечению объектов за пределами окна просмотра, а отсечение выполняется для каждого фрагмента, а не по одной вершине.
image.png

Растеризация: примитивные данные, полученные модулем отсечения, должны быть дополнительно обработаны, чтобы сгенерировать пиксели в буфере кадра. На самом деле растеризация — это процесс превращения геометрических примитивов в двухмерные изображения. Процесс состоит из двух частей работы. Первая часть работы: определить, какие области целочисленной сетки в оконных координатах заняты примитивами; вторая часть работы: присвоить каждой области значение цвета и значение глубины. Процесс растеризации создает фрагменты.
image.png
Обработка фрагмента: на этом этапе в основном вычисляются окончательные значения цвета и глубины фрагмента с помощью шейдера фрагментов, а также оценивается, виден ли текущий фрагмент с помощью теста глубины и теста трафарета.Если фрагмент проходит тест, его можно использовать. непосредственно в фреймбуфер.image.png

WebGL-программа

Полная программа WebGL, включающая как минимум HTML, JavaScript и код шейдера OpenGL (GLSL), в котором код HTML в основном обеспечивает холст Canvas; JavaScript используется для получения контекста WebGL, обработки координат, цветов и другой информации вершин модели , и передать эти обработанные данные графическому процессору; GLSL — это C-подобный язык программирования шейдеров, который в основном включает две части, а именно вершинный шейдер и фрагментный шейдер. Давайте посмотрим на программы WebGL на примере WebGL, который рисует треугольники.

  1. Объявить холст Canvas
<canvas id="webgl" width="500" height="300" style="border: 1px solid;"></canvas>
  1. Получить контекст WebGL
// 和 canvas2D 一样,先获取 webgl 上下文
const canvas = document.getElementById("webgl");
const gl = canvas.getContext("webgl");
  1. Написать код вершинного шейдера и код фрагментного шейдера
// 着色器源码
const vertexShaderSource = `
  // 声明一个属性变量 a
  attribute vec3 a;
  void main() {
    // 顶点在作色器处理后的位置信息
    gl_Position = vec4(a, 1.0);
  }    
`;

const fragmentShaderSource = `
  void main() {
      // 片段颜色
      gl_FragColor = vec4(0.1, 0.7, 0.3, 1.0);
    }
`;
  1. Объявить использование кода шейдера
 // 初始化着色器方法
 function initShader(gl, vertexSource, fragmentSource) {
   const vertexShader = gl.createShader(gl.VERTEX_SHADER);
   const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
   // 将着色器源码附加到着色器上
   gl.shaderSource(vertexShader, vertexSource);
   gl.shaderSource(fragmentShader, fragmentSource);

  // 编译着色器
  gl.compileShader(vertexShader);
  gl.compileShader(fragmentShader);

  // 创建一个程序对象
  const program = gl.createProgram();
  // 将编译好的着色器附加到程序对象上
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  // 链接程序对象
  gl.linkProgram(program);
  // WebGL引擎使用该程序对象
  gl.useProgram(program);

  return program;
}

 const program = initShader(gl, vertexShaderSource, fragmentShaderSource);
  1. Передать данные вершины в вершинный шейдер
function sendDataToSharder(gl, data) {
  // 将顶点数据写入缓存区,并将数据传递给顶点着色器
  var vertexBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
  var vertexAttribLocation = gl.getAttribLocation(program, "a");
  gl.vertexAttribPointer(vertexAttribLocation, 3, gl.FLOAT, false, 0, 0);
  // 设置通过顶点着色器将缓冲的输入数据转换为一系列顶点数组
  gl.enableVertexAttribArray(vertexAttribLocation);
}

// 定义顶点数据,这里定义了三角形的三个顶点坐标,以中心点为坐标原点,z 轴为 0
var data = [0.0, 0.5, 0.0, -0.5, -0.5, 0.0, 0.5, -0.5, 0.0];
sendDataToSharder(gl, data);
  1. рисовать графику
// 绘制缓冲数组
gl.drawArrays(gl.TRIANGLES, 0, 3);

Окончательный эффект нарисованного треугольника выглядит следующим образом:
image.png
Демонстрационный адрес:код sandbox.IO/yes/draw-other day...

На данный момент, я считаю, что вы должны иметь простое представление о WebGL Я объясню, как писать свои собственные шейдеры в следующей статье, так что вы можете с нетерпением ждать этого!

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

  1. Geek Time «Визуализация с Луной» — основы графикиtime.geekhelp.org/column/int R…
  2. Интерактивная компьютерная графика — нисходящий подход на основе WEBGL (7-е издание)
  3. Руководство по программированию OpenGL (8-е издание)
  4. Буклет Nuggets "Введение и практика WebGL"Наггетс Талант/книга/684473…