Шейдеры

Введение в шейдеры

Последнее обновление: 1.11.2015

Шейдеры являются одним из базовых элементов любой программы на WebGL. Без шейдеров сложно что-то сделать. На вход в графический процессов передается лишь набор вершин. Но благодаря вершинному и фрагментному шейдерам этот набор сначала прекращается в набор примтивов, а затем окрашивается, и мы в итоге видим какие-нибудь трехмерные модели.

Если вы посмотрите на ранее использовавшиеся шейдеры (все они пока однотипны), то вы увидите, что в нем используется особый язык с Си-подобным синтаксисом. Например, код вершинного шейдера:

attribute vec3 aVertexPosition;
void main(void) {
  gl_Position = vec4(aVertexPosition, 1.0);
}

Этот язык называется GLSL, а если точнее, то язык шейдеров OpenGL ES Shading Language. В свою очередь GLSL основан на C++. GLSL довольно распространен, лично встречал как минимум три книги по данному языку, поэтому при желании вы можете найти соответствующую литературу и более подробно ознакомиться с данным языком.

Этот язык используется в двух частях программы WebGL - в вершинном шейдере и фрагментном шейдере. Для написания кода на OpenGL ES Shading Language используются выражения языка JavaScript.

Вершинный шейдер

Практически в самом начале работы конвейера WebGL буфер вершин передается в вершинный шейдер. Вершинный шейдер проходит по всем переданным вершинам и выполняет определенные преобразования, которые применил в программе вершинного шейдера разработчик. Именно вершинный шейдер отвечает за матричные преобразования координат, их смещения и т.д. На выходе он генерирует финальные координаты вершины и передает ее для дальнейшей обработки дальше. До сих пор я использовал простейшее определение шейдера:

attribute vec3 aVertexPosition;
void main(void) {
  gl_Position = vec4(aVertexPosition, 1.0);
}

Атрибут aVertexPosition, имеющий тип vec3, как раз и передает координаты вершины из буфера вершин. И так как каждая вершина представлена тремя координатами x, y, z, то для передачи вершины используется трехмерный вектор vec3.

Как и каждая программа на С/С++, шейдер имеет основную процедуру main, в которой происходит генерация окончательных координат вершины, только уже в виде четырехмерного вектора. А gl_Position по сути это и есть преобразованные координаты вершины. В данном случае у нас никаких преобразований и трансформаций не производится, и финальная вершина будет иметь те же координаты, что и переданная в шейдер.

Фрагментный шейдер

Фрагментный шейдер уже наполняет набор примитивов цветом, раскрашивает их. Фрагменный шейдер никак не влияет на координаты вершины, он влияет только на цветовую составляющую, преобразуя вершины уже в пиксели или фрагменты.

Для простоты ранее также были использованы простейшие определения фрагментных шейдеров, например:

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

Здесь также основная программа main, которая устанавливает финальный цвет для пикселя, представленного вершиной. Так как представление цвета состоит из четырех элементов - RGBA, то также используется для установки цвета тип четырехмерного вектора vec4. В данном случае каждый пиксель примитивов у нас окрашивается в белый цвет. А если бы мы захотели покрасить примитивы в зеленый цвет, то могли бы задать следующее определение цвета: gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850