GLSL: Основы шейдеров: Типы данных и переменные

В GLSL доступны следующие простые типы данных:

  • float
  • bool
  • int 

Эти типы данных — точно такие же, как в C.

Также доступны векторы для перечисленных выше типов данных с двумя, тремя или четырьмя компонентами.
Она обьявляются как:

  • vec{2,3,4} — вектор из 2/¾ float
  • bvec{2,3,4} — вектор из 2/¾ bool
  • ivec{2,3,4} — вектор из 2/¾ int 

Также доступны квадратные матрицы 2×2, 3×3 и 4×4, т.к. они часто используются в графике.
Соответствующие типы данных:

  • mat2
  • mat3
  • mat4 

Также доступен ряд специальных типов данных для работы с текстурами. Они называются «samplers» и
нуждаются в доступе к значениям текстур, так же известным как «texels». Типы данных:

  • sampler1D — для 1D-текстур
  • sampler2D — для 2D-текстур
  • sampler3D — для 3D-текстур
  • samplerCube — для текстур кубических карт
  • sampler1DShadow — для карт теней
  • sampler2DShadow — для карт теней 

Массивы в шейдерах обьявляются так же, как в C, однако они не могут быть инициализированы при обьявлении.
Доступ к элементам — такой же, как в C.

Также в GLSL доступны структуры. Синтаксис такой же, как в C:

    struct dirlight {
vec3 direction;
vec3 color;
};

 

Переменные

Объявление простых переменных — точно такое же, как в C, вы даже можете инициализировать
переменную при объявлении.

    float a,b;  // Два вектора. Да, коментарии тоже точно как в C
int c=2;    // Обьявление и инициализация «c»
bool d = true;  // d = true

 

Объявление других типов переменных соответствует тому же принципу, но есть отличия от C касаемо инициализации. GLSL нужен конструктор для указания типа данных и инициализации.

    float b = 2;        // Неправильно, автоматического указания типа данных тут нет
float e = (float)2; // Неправильно, для указания типа вызывается конструкторint a=2;
float c = float(a); // Правильно, c == 2.0

vec3 f;         // Обьявление f как vec3
vec3 g = vec3(1.0, 2.0, 3.0);   // Обьявление и инициализация вектора g

 

GLSL приятно гибок в отношении инициализации переменных. Всё, что нужно — передать соответствующее типу данных число переменных. Посмотрите примеры:

    vec2 a = vec2(1.0, 2.0);
vec2 b = vec2(3.0, 4.0);vec4 c = vec4(a,b);     // c = vec4 (1.0, 2.0, 3.0, 4.0)

vec2 g = vec2(1.0, 2.0);
float h = 3.0;
vec3 j = vec3(g,h);

 

Матрицы тоже соответствуют этому принципу. К вашим услугам широкий выбор конструкторов матриц.
Например, доступны следующие конструкторы:

    mat4 m = mat4(1.0) // инициализация диагонали матрицы с 1.0

vec2 a = vec2(1.0,2.0);
vec2 b = vec2(3.0,4.0);

mat2 n = mat2(a,b);

mat2 k = mat2(1.0,0.0,1.0,0.0); // указаны все элементы

 

Пример объявления и инициализации структур:

    struct dirlight {       // обьявление типа
vec3 direction;
vec3 color;
};dirlight d1;
dirlight d2 = dirlight(vec3(1.0,1.0,0.0), vec3(0.8,0.8,0.4));

 

Также в GLSL реализованы некоторые возможности, упрощающие нам жизнь и делающие код немного чище. Так же, как и в стандартном C, для присваивания векторам значений можно использовать буквы:

    vec4 a = vec4(1.0, 2.0, 3.0, 4.0);
float posX = a.x;
float posY = a[1];vec2 posXY = a.xy;

float depth = a.w;

 

Как показано в этом коде, для доступа к компонентам вектора можно использовать буквы x,y,z,w.
Если речь идет о цветах, можно использовать буквы r,g,b. Для текстурных координат — s,t,p,q.
Имейте в виде, что по соглашению текстурные координаты часто обьявлялись как s,t,r,q. Однако «r» уже занят для «RGBA». Пришлось искать другую букву, и выбор пал на «p».

Селекторы матриц могут занимать 1 или элемента, например, m[0], или m[0][1]. В первом случае выбирается весь ряд, во втором — только один элемент из него.

Что до структур, то их селекторы работают точно так же, как в C, так что для структуры описанной выше может быть написано:

    d1.direction = vec3(1.0,1.0,1.0);

 

Квалификаторы переменных

Квалификаторы задают переменным особый смысл. В GLSL доступны следующие:

  • const — обьявление константы
  • attribute — Глобальные переменные, которые могут изменятся для каждой вершины, и передаются
    в вершинные шейдеры. Может использоватся только в них. Для шейдера переменная — read-only.
  • uniform — глобальная переменная, которая может изменятся для каждого полигона (не может быть
    между glBegin/glEnd), передаётся OpenGL в шейдеры. Может использоваться в обоих типах
    шейдеров, для шейдеров является read-only.
  • varying — используются для передачи интерполированных данных между вершинным и пикселным шейдерами.
    Доступны для записи в вершинном шейдере, и read-only для пикселного шейдера.
Понравилась статья? Поделиться с друзьями: