Доступные в GLSL циклы и выражения, что приятно, практически идентичны с C.
В GLSL есть выражения-условия, такие, как if-else, и циклы, как for, while, do-while.
…
else
…for(инициализация; выражение; выражение)
…
while(bool)
…
do
…
while(bool)
Но несмотря на то, что всё это описано в спецификации GLSL, только оператор if полностью поддерживается текущим железом.
Также доступно несколько «прыжковых» директив:
- continue
- break
- discard — используется только в пикселных шейдерах. Вызывает терминацию шейдера для текущего
пиксела без передачи его во фреймбуфер или буфер глубины.
Функции
Как и C, шейдеры структурированы функциями. По крайней мере каждый тип шейдера должен
иметь функцию main() со следующим синтаксисом:
void main()
Пользователь также может объявлять функции. Как и в C, функция может возвращать значение,
и использует это значение для передачи результата своей работы. Возвращаемое значение может
быть любым кроме массива.
Параметры функции могут иметь следующие квалификаторы:
- in — для входящих параметров
- out — выходные данные функции
- inout — параметры, могущие быть и входными и выходными
Если квалификатор не указан явно, по умолчанию он рассматривается как «in».
Несколько финальных замечаний:
- 1. Функция может быть перезагружена, если указать для неё разные параметры
- 2. Рекурсивное поведение в спецификации не определено
Пример функции, показывающей всё вышеизложенное:
vec4 toonify(in float intensity) {
vec4 color;
if (intensity > 0.98)
color = vec4(0.8,0.8,0.8,1.0);
else if (intensity > 0.5)
color = vec4(0.4,0.4,0.8,1.0);
else if (intensity > 0.25)
color = vec4(0.2,0.2,0.4,1.0);
else
color = vec4(0.1,0.1,0.1,1.0);
return(color);
}