Учебники

WebGL — геометрия

После получения контекста WebGL вы должны определить геометрию примитива (объект, который вы хотите нарисовать) и сохранить его. В WebGL мы определяем детали геометрии — например, вершины, индексы, цвет примитива — используя массивы JavaScript. Чтобы передать эти детали шейдерным программам, нам нужно создать объекты буфера и сохранить (присоединить) массивы JavaScript, содержащие данные, в соответствующих буферах.

Примечание. Позже эти объекты буфера будут связаны с атрибутами программы шейдера (вершинный шейдер).

Определение необходимой геометрии

2D или 3D модель, нарисованная с использованием вершин, называется сеткой . Каждый фасет в сетке называется многоугольником, а многоугольник состоит из 3 или более вершин.

Чтобы нарисовать модели в контексте рендеринга WebGL, вы должны определить вершины и индексы, используя массивы JavaScript. Например, если мы хотим создать треугольник, который лежит на координатах {(5,5), (-5,5), (-5, -5)}, как показано на диаграмме, то вы можете создать массив для вершины как —

var vertices = [
   0.5,0.5,    //Vertex 1
   0.5,-0.5,   //Vertex 2
   -0.5,-0.5,  //Vertex 3
]; 

Геометрия

Точно так же вы можете создать массив для индексов. Индексы для вышеуказанных индексов треугольника будут [0, 1, 2] и могут быть определены как —

var indices = [ 0,1,2 ]

Для лучшего понимания индексов рассмотрим более сложные модели, такие как квадрат. Мы можем представить квадрат в виде набора из двух треугольников. Если (0,3,1) и (3,1,2) — это два треугольника, с помощью которых мы собираемся нарисовать квадрат, то индексы будут определены как —

var indices = [0,3,1,3,1,2];

Пример геометрии

Примечание

Для рисования примитивов WebGL предоставляет следующие два метода:

  • drawArrays () — при использовании этого метода мы передаем вершины примитива, используя массивы JavaScript.

  • drawElements () — при использовании этого метода мы передаем и вершины, и индексы примитива, используя массив JavaScript.

drawArrays () — при использовании этого метода мы передаем вершины примитива, используя массивы JavaScript.

drawElements () — при использовании этого метода мы передаем и вершины, и индексы примитива, используя массив JavaScript.

Буферные объекты

Буферный объект — это механизм, предоставляемый WebGL, который указывает область памяти, выделенную в системе. В этих буферных объектах вы можете хранить данные модели, которую вы хотите нарисовать, соответствующие вершинам, индексам, цвету и т. Д.

Используя эти объекты буфера, вы можете передать несколько данных в программу шейдера (вершинный шейдер) через одну из ее переменных атрибута. Поскольку эти объекты буфера находятся в памяти графического процессора, они могут отображаться напрямую, что, в свою очередь, повышает производительность.

Для обработки геометрии существует два типа буферных объектов. Они —

  • Буферный объект вершины (VBO) — содержит данные для каждой вершины графической модели, которая будет отображаться. Мы используем объекты буфера вершин в WebGL для хранения и обработки данных о вершинах, таких как координаты вершин, нормали, цвета и координаты текстуры.

  • Индексные буферные объекты (IBO). Содержит индексы (индексные данные) графической модели, которая будет отображаться.

Буферный объект вершины (VBO) — содержит данные для каждой вершины графической модели, которая будет отображаться. Мы используем объекты буфера вершин в WebGL для хранения и обработки данных о вершинах, таких как координаты вершин, нормали, цвета и координаты текстуры.

Индексные буферные объекты (IBO). Содержит индексы (индексные данные) графической модели, которая будет отображаться.

После определения необходимой геометрии и сохранения их в массивах JavaScript вам необходимо передать эти массивы в буферные объекты, откуда данные будут передаваться в шейдерные программы. Чтобы сохранить данные в буферах, необходимо выполнить следующие шаги.

  • Создайте пустой буфер.

  • Привязать соответствующий объект массива к пустому буферу.

  • Передайте данные (вершины / индексы) в буфер, используя один из типизированных массивов .

  • Отсоедините буфер (необязательно).

Создайте пустой буфер.

Привязать соответствующий объект массива к пустому буферу.

Передайте данные (вершины / индексы) в буфер, используя один из типизированных массивов .

Отсоедините буфер (необязательно).

Создание буфера

Чтобы создать пустой буферный объект, WebGL предоставляет метод с именем createBuffer () . Этот метод возвращает вновь созданный буферный объект, если создание было успешным; иначе он возвращает нулевое значение в случае сбоя.

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

var vertex_buffer = gl .createBuffer();

Примечаниеgl является ссылочной переменной для текущего контекста WebGL.

Привязать буфер

После создания пустого объекта буфера вам необходимо привязать к нему соответствующий буфер массива (целевой объект). Для этой цели WebGL предоставляет метод bindBuffer () .

Синтаксис

Синтаксис метода bindBuffer () следующий:

void bindBuffer (enum target, Object buffer)

Этот метод принимает два параметра, и они обсуждаются ниже.

target — первая переменная является значением enum, представляющим тип буфера, который мы хотим связать с пустым буфером. У вас есть два предопределенных значения перечисления в качестве опций для этого параметра. Они —

  • ARRAY_BUFFER, который представляет данные вершины.

  • ELEMENT_ARRAY_BUFFER, который представляет данные индекса.

ARRAY_BUFFER, который представляет данные вершины.

ELEMENT_ARRAY_BUFFER, который представляет данные индекса.

Буфер объекта — вторая является ссылочной переменной для объекта буфера, созданного на предыдущем шаге. Переменная-ссылка может быть объектом буфера вершин или объектом буфера индекса.

пример

В следующем фрагменте кода показано, как использовать метод bindBuffer ().

//vertex buffer
var vertex_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

//Index buffer
var Index_Buffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);

Передача данных в буфер

Следующим шагом является передача данных (вершин / индексов) в буфер. До сих пор данные представлены в виде массива, и прежде чем передавать их в буфер, нам нужно обернуть их в один из типизированных массивов WebGL. Для этой цели WebGL предоставляет метод с именем bufferData () .

Синтаксис

Синтаксис метода bufferData () следующий:

void bufferData (enum target, Object data, enum usage)

Этот метод принимает три параметра, и они обсуждаются ниже —

target — первый параметр — это значение enum, представляющее тип буфера массива, который мы использовали. Варианты этого параметра:

  • ARRAY_BUFFER, который представляет данные вершины .

  • ELEMENT_ARRAY_BUFFER, который представляет данные индекса .

ARRAY_BUFFER, который представляет данные вершины .

ELEMENT_ARRAY_BUFFER, который представляет данные индекса .

Данные объекта . Второй параметр — это значение объекта, которое содержит данные, которые должны быть записаны в буферный объект. Здесь мы должны передать данные, используя типизированные массивы .

Использование . Третьим параметром этого метода является переменная enum, которая определяет, как использовать данные объекта буфера (сохраненные данные) для рисования фигур. Для этого параметра есть три параметра, перечисленных ниже.

  • gl.STATIC_DRAW — Данные будут указаны один раз и использованы много раз.

  • gl.STREAM_DRAW — Данные будут указаны один раз и использованы несколько раз.

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

gl.STATIC_DRAW — Данные будут указаны один раз и использованы много раз.

gl.STREAM_DRAW — Данные будут указаны один раз и использованы несколько раз.

gl.DYNAMIC_DRAW — данные будут указываться многократно и использоваться многократно.

пример

В следующем фрагменте кода показано, как использовать метод bufferData () . Предположим, что вершины и индексы — это массивы, содержащие данные вершин и индексов соответственно.

//vertex buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

//Index buffer
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);

Типизированные массивы

WebGL предоставляет специальный тип массива, называемый типизированными массивами, для передачи элементов данных, таких как вершина индекса и текстура. Эти типизированные массивы хранят большие объемы данных и обрабатывают их в собственном двоичном формате, что приводит к повышению производительности. Типизированными массивами, используемыми в WebGL, являются Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, UInt32Array, Float32Array и Float64Array.

Заметка

  • Как правило, для хранения данных вершин мы используем Float32Array ; и для хранения данных индекса мы используем Uint16Array .

  • Вы можете создавать типизированные массивы так же, как массивы JavaScript, используя новое ключевое слово.

Как правило, для хранения данных вершин мы используем Float32Array ; и для хранения данных индекса мы используем Uint16Array .

Вы можете создавать типизированные массивы так же, как массивы JavaScript, используя новое ключевое слово.

Уберите буферы

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

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);

WebGL предоставляет следующие методы для выполнения операций с буфером:

void bindBuffer ( цель перечисления, буфер объектов)

цель — ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER

void bufferData ( цель enum, длинный размер , использование enum)

цель — ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER

использование — STATIC_DRAW, STREAM_DRAW, DYNAMIC_DRAW

void bufferData ( цель перечисления, данные объекта, использование перечисления)

цель и использование — То же, что и для bufferData выше

void bufferSubData (enum target , long offset , Object data )

цель — ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER

any getBufferParameter (enum target , enum pname )

цель — ARRAY_BUFFER, ELEMENT_ ARRAY_BUFFER

pname — BUFFER_SIZE, BUFFER_USAGE