WebGL - Режимы рисования
Здравствуйте, будущие маги WebGL! ? Сегодня мы окунемся в захватывающий мир режимов рисования в WebGL. Как ваш доброжелательный сосед-преподаватель информатики, я здесь, чтобы провести вас через это путешествие, даже если вы еще не писали ни строчки кода. Так что возьмите свою виртуальную кисть, и давайте создадимdigitальные шедевры!
Параметр mode
Прежде чем приступить к рисованию, давайте поговорим о звезде нашего шоу: параметре mode
. Представьте его как магическую палочку, которая говорит WebGL, как соединять точки (или в нашем случае, вершины) для создания разных фигур и узоров.
В WebGL, когда мы вызываем функцию gl.drawArrays()
или gl.drawElements()
, нам нужно указать параметр mode
. Этот параметр похож на то, как давать инструкции для головоломки "Соедини точки" - он tells WebGL, как соединять точки, которые мы определили.
Вот таблица с различными режимами рисования, доступными в WebGL:
Режим | Описание |
---|---|
gl.POINTS | Рисует одну точку для каждого вершины |
gl.LINES | Рисует линию между каждой парой вершин |
gl.LINE_STRIP | Рисует непрерывную линию, соединяющую вершины |
gl.LINE_LOOP | Подобно LINE_STRIP, но замыкает форму |
gl.TRIANGLES | Рисует треугольник для каждой тройки вершин |
gl.TRIANGLE_STRIP | Рисует connected группу треугольников |
gl.TRIANGLE_FAN | Рисует веерообразную форму из соединенных треугольников |
Не волнуйтесь, если это покажется вам сложным сейчас. Мы рассмотрим каждый из них с примерами по мере продвижения!
Пример - Рисование трех параллельных линий
Давайте начнем с простого примера: рисование трех параллельных линий. Это поможет нам понять, как работает параметр mode
на практике.
// Сначала настроим наш контекст WebGL
const canvas = document.getElementById('myCanvas');
const gl = canvas.getContext('webgl');
// Теперь определим наш vertex shader
const vertexShaderSource = `
attribute vec2 a_position;
void main() {
gl_Position = vec4(a_position, 0.0, 1.0);
}
`;
// И наш fragment shader
const fragmentShaderSource = `
precision mediump float;
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // Красный цвет
}
`;
// Создаем и компилируем шейдеры (не волнуйтесь, мы рассмотрим это подробнее в будущих уроках)
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
// Создаем программу и связываем шейдеры
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
// Определяем позиции наших линий
const positions = new Float32Array([
-0.8, -0.8, // Начало первой линии
-0.8, 0.8, // Конец первой линии
-0.3, -0.8, // Начало второй линии
-0.3, 0.8, // Конец второй линии
0.2, -0.8, // Начало третьей линии
0.2, 0.8 // Конец третьей линии
]);
// Создаем буфер и кладем в него позиции
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
// Говорим WebGL, как читать буфер и атрибутить его к `a_position`
const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
gl.enableVertexAttribArray(positionAttributeLocation);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
// Очищаем холст
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Рисуем линии
gl.drawArrays(gl.LINES, 0, 6);
Теперь разберем это:
-
Мы настраиваем наш контекст WebGL и определяем наши шейдеры. Не волнуйтесь о этом сейчас; мы рассмотрим шейдеры подробнее в будущих уроках.
-
Мы создаем программу и связываем наши шейдеры с ней. Это как подготовка нашей цифровой кисти.
-
Мы определяем позиции наших линий. Каждая линия определяется двумя точками (ее началом и концом), и каждая точка определяется двумя координатами (x и y). Так что у нас есть 6 точек для наших 3 линий.
-
Мы создаем буфер и кладем наши позиции в него. Представьте это как загрузку краски на кисть.
-
Мы говорим WebGL, как читать этот буфер и ассоциировать его с атрибутом
a_position
в нашем vertex шейдере. -
Наконец, мы вызываем
gl.drawArrays(gl.LINES, 0, 6)
. Вот где происходит магия!
-
gl.LINES
是我们的模式。 Он говорит WebGL рисовать линии между парами вершин. -
0
- это начальный индекс в нашем массиве позиций. -
6
- это количество вершин, которые нужно учитывать (помните, у нас 6 точек для наших 3 линий).
Запустите этот код, и voila! Вы должны увидеть три красные параллельные линии на черном фоне. Поздравляю, вы только что создали свое первое рисование в WebGL! ?
Режимы рисования
Теперь, когда мы видели gl.LINES
в действии, давайте рассмотрим другие режимы рисования. Мы будем использовать тот же набор, что и раньше, но изменим наши позиции и режим рисования.
gl.POINTS
Давайте начнем с самого простого режима: gl.POINTS
. Этот режим рисует одну точку для каждой вершины.
// ... (предыдущий код настройки)
const positions = new Float32Array([
-0.5, 0.5,
0.0, 0.0,
0.5, -0.5
]);
// ... (код настройки буфера)
gl.drawArrays(gl.POINTS, 0, 3);
Это нарисует три красные точки на вашем холсте. Просто, правда?
gl.LINE_STRIP
Теперь давайте попробуем gl.LINE_STRIP
. Этот режим рисует непрерывную линию, соединяющую каждую вершину с следующей.
// ... (предыдущий код настройки)
const positions = new Float32Array([
-0.5, 0.5,
0.0, -0.5,
0.5, 0.5
]);
// ... (код настройки буфера)
gl.drawArrays(gl.LINE_STRIP, 0, 3);
Вы должны увидеть V-образную линию, соединяющую три точки.
gl.LINE_LOOP
gl.LINE_LOOP
подобен LINE_STRIP
, но он замыкает форму, соединяя последнюю вершину с первой.
// ... (предыдущий код настройки)
const positions = new Float32Array([
-0.5, 0.5,
0.0, -0.5,
0.5, 0.5
]);
// ... (код настройки буфера)
gl.drawArrays(gl.LINE_LOOP, 0, 3);
Это нарисует контур треугольника.
gl.TRIANGLES
Теперь давайте перейдем к заполнению фигур с помощью gl.TRIANGLES
. Этот режим рисует отдельный треугольник для каждой тройки вершин.
// ... (предыдущий код настройки)
const positions = new Float32Array([
-0.5, -0.5,
0.5, -0.5,
0.0, 0.5
]);
// ... (код настройки буфера)
gl.drawArrays(gl.TRIANGLES, 0, 3);
Вы должны увидеть красный треугольник.
gl.TRIANGLE_STRIP
gl.TRIANGLE_STRIP
немного сложнее. Он рисует connected группу треугольников, где каждый треугольник делит два вершины с предыдущим.
// ... (предыдущий код настройки)
const positions = new Float32Array([
-0.5, -0.5,
0.5, -0.5,
-0.5, 0.5,
0.5, 0.5
]);
// ... (код настройки буфера)
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
Это нарисует два соединенных треугольника, forming矩形.
gl.TRIANGLE_FAN
Наконец, рассмотрим gl.TRIANGLE_FAN
. Этот режим рисует веерообразную форму, где все треугольники делят первую вершину.
// ... (предыдущий код настройки)
const positions = new Float32Array([
0.0, 0.0, // Центральная точка
0.5, 0.0, // Точка 1
0.35, 0.35, // Точка 2
0.0, 0.5, // Точка 3
-0.35, 0.35 // Точка 4
]);
// ... (код настройки буфера)
gl.drawArrays(gl.TRIANGLE_FAN, 0, 5);
Это нарисует форму, которая resemblesчетверть круга.
И вот и все! Мы рассмотрели все режимы рисования в WebGL. Помните, ключ к их освоению - это практика. Попробуйте combine разные режимы, change цвета и experiment с положениями вершин. Before you know it, вы будете создавать сложные сцены WebGL с легкостью!
В следующем уроке мы углубимся в шейдеры и научимся добавлять немного пышности нашим рисункам с помощью цветов и текстур. Пока что, счастливого кодирования, будущие художники WebGL! ?????
Credits: Image by storyset