WebGL - Шейдеры: Путеводитель для начинающих

Здравствуйте, ambitные программисты! Сегодня мы отправимся в увлекательное путешествие в мир шейдеров WebGL. Не волнуйтесь, если вы никогда не писали ни строчки кода — я буду вашим доброжелательным проводником по этому красочному ландшафту компьютерной графики.

WebGL - Shaders

Что такое шейдеры?

Прежде чем мы углубимся, давайте поймем, что такое шейдеры. Представьте, что вы пишете картину. Холст — это ваш компьютерный экран, а шейдеры — это словно магические кисти, которые tell компьютеру, как закрасить каждый пиксель. Круто, правда?

Типы данных

В мире шейдеров у нас есть некоторые особые типы данных для работы. Давайте посмотрим на них:

Тип данных Описание Пример
float Число с плавающей запятой одинарной точности 3.14
vec2 2D вектор vec2(1.0, 2.0)
vec3 3D вектор vec3(1.0, 2.0, 3.0)
vec4 4D вектор vec4(1.0, 2.0, 3.0, 4.0)
mat2 2x2 матрица mat2(1.0, 2.0, 3.0, 4.0)
mat3 3x3 матрица mat3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0)
mat4 4x4 матрица mat4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0)

Не волнуйтесь, если это покажется вам сложным — мы будем использовать их по шагам!

Модификаторы

Модификаторы — это словно особые ярлыки, которые мы ставим на наши переменные. Они tell шейдеру, как обращаться с этими переменными. Вот основные из них:

Модификатор Описание
attribute Входные значения, которые изменяются для каждого вершика
uniform Входные значения, которые постоянны для всех вершин
varying Значения, передаваемые от vertex шейдера к fragment шейдеру

Vertex Шейдер

Vertex шейдер — это словно скелет нашей 3D модели. Он вычисляет, где каждая точка (вершина) нашей модели должна быть на экране. Вот пример простого vertex шейдера:

attribute vec3 aVertexPosition;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;

void main(void) {
gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aVertexPosition, 1.0);
}

Давайте разберем это:

  1. Мы объявляем attribute под названием aVertexPosition — это положение нашей вершины.
  2. У нас есть две uniform матрицы — они помогают нам positioned и projekтировать нашу 3D модель на 2D экран.
  3. В функции main, мы вычисляем конечное положение нашей вершины.

Fragment Шейдер

Если vertex шейдер — это скелет, то fragment шейдер — это кожа. Он decides цвет каждого пикселя. Вот пример простого fragment шейдера:

precision mediump float;

void main(void) {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

Этот шейдер закрашивает все красным! vec4(1.0, 0.0, 0.0, 1.0) represents полный красный, нет зелени, нет синего и полная непрозрачность.

Хранение и компиляция шейдерных программ

Теперь, когда мы написали наши шейдеры, нам нужно tell WebGL о них. Вот как мы делаем это на JavaScript:

function getShader(gl, id) {
const shaderScript = document.getElementById(id);
if (!shaderScript) return null;

const str = shaderScript.text;
let shader;

if (shaderScript.type === "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderScript.type === "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
}

gl.shaderSource(shader, str);
gl.compileShader(shader);

if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}

return shader;
}

Эта функция делает несколько вещей:

  1. Она находит наш код шейдера в HTML документе.
  2. Создает шейдер подходящего типа (vertex или fragment).
  3. Компилирует шейдер и проверяет ошибки.

Объединенная программа

Наконец, нам нужно объединить наш vertex и fragment шейдеры в программу:

const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);

if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Could not initialize shaders");
}

gl.useProgram(shaderProgram);

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

И вот вы это сделали! Вы только что сделали свои первые шаги в мир шейдеров WebGL. Помните, как при изучении любого нового языка, это требует практики. Не отчаивайтесь, если это не сработает сразу — продолжайте экспериментировать, и вскоре вы будете создавать потрясающую 3D графику в вашем веб-браузере!

За годы моего преподавания я видел, как countless студенты перешли от абсолютных новичков к магам шейдеров. Один из моих студентов даже использовал эти навыки, чтобы создать виртуальную художественную галерею для своего финального проекта — представьте себе, как пройти через 3D музей прямо в вашем веб-браузере!

Так что вы создадите с своими новыми навыками шейдеров? Единственным ограничением является ваша фантазия! Счастливого кодирования, будущие графические гуру!

Credits: Image by storyset