WebGL - Шейдеры: Путеводитель для начинающих
Здравствуйте, ambitные программисты! Сегодня мы отправимся в увлекательное путешествие в мир шейдеров WebGL. Не волнуйтесь, если вы никогда не писали ни строчки кода — я буду вашим доброжелательным проводником по этому красочному ландшафту компьютерной графики.
Что такое шейдеры?
Прежде чем мы углубимся, давайте поймем, что такое шейдеры. Представьте, что вы пишете картину. Холст — это ваш компьютерный экран, а шейдеры — это словно магические кисти, которые 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);
}
Давайте разберем это:
- Мы объявляем
attribute
под названиемaVertexPosition
— это положение нашей вершины. - У нас есть две
uniform
матрицы — они помогают нам positioned и projekтировать нашу 3D модель на 2D экран. - В функции
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;
}
Эта функция делает несколько вещей:
- Она находит наш код шейдера в HTML документе.
- Создает шейдер подходящего типа (vertex или fragment).
- Компилирует шейдер и проверяет ошибки.
Объединенная программа
Наконец, нам нужно объединить наш 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