Сдам Сам

ПОЛЕЗНОЕ


КАТЕГОРИИ







Предшеств. Операторы Приемл. типы Описание





1 () --- Группировка операций

2 [ ] arrays, matrices, vectors Нижняя индексация массивов

f() functions Запросы функций и конструкторов

. (period) structures Доступ к полям функций или методов

++ -- arithmetic Пост-инкремент и -декремент

3 ++ -- arithmetic Пре-инкремент и -декремент

+ - arithmetic Унарный позитив или отрицание

~ integer Унарный по-битовый not

! bool Унарный логический not

4 * / % arithmetic Операции умножения

5 + - arithmetic Операции сложения

6 << >> integer По-битовые операции

7 < > <= >= arithmetic Рациональные операции

8 ==!= any Операции равенств

9 & integer По-битовый and

10 ^ integer Bit-wise exclusive or

11 | integer Bit-wise inclusive or

12 && bool Logical and operation

13 ^^ bool Logical exclusive-or operation

14 || bool Logical or operation

15 a? b: c bool? any: any Ternary selection operation (inline ‘‘if’’

operation; if (a) then (b) else (c))

16 = any Назначение

+= -= arithmetic Арифметическое назначение

*= /= arithmetic

%= <<= >>= integer

&= ^= |= integer

17, (comma) any Последовательность операций

 

Управление потоками

Логические структуры контроля в GLSL это популярные if-else и swtich операторы. Как и на “С”, раздел else - необязательный и разные операторы требуют отдельный блок.

if (truth) {

// true clause

}

else {

// false clause

}

Похоже тому, как это происходит на “С”, операторы switch доступны в знакомом виде (начиная с GLSL 1.30):

switch (int_value) {

case n:

// statements

break;

case m:

// statements

break;

default:

// statements

break;

}

Switch операторы GLSL также принимают операторы выбора “fall-through”, это такие, в которые не оканчиваются разрывом. Каждый выбор требует исполнения оператора до окончания switch (до зарывающей скобки). Также, в отличае от С++, ни один оператор не может стоять перед оператором выбора. Если switch не соответствует ни одного выбора, и ярлык по умолчанию присутствует, тогда его выполняют.

 

Циклические структуры

GLSL поддерживает знакомые по “С” типы for, while и do … while циклы.

Цикл ofr позволяет заявку переменной шага цикла в начальном блоке цикла. Шаг цикла заявленный таким образом действитетлен только внутри цикла.

declared in this manner is only for the lifetime of the loop.

for (int i = 0; i < 10; ++i) {

...

}

while (n < 10) {

...

}

do {

...

} while (n < 10);

 

Операторы контроля потока

Дополнительные операторы контроля доступны в GLSLю Таблица 2.7 перечисляет доступные операторы контроля потока.

Описаные заявления доступны только в фрагментных программах. Исполнение фрагментарного шейдера может завершено отменой заявки, но ее использование зависимо.

Table 2.7 GLSL операторы контроля потока

Statement Description

break Обрывает исполнение блока цикла, и продолжает исполнеие кода за ним

continue Обрывает текущий шаг цикла охватывающий блок цикла, начиная со

следующего шага цикла

return [result] Возвращается из текущей подпрограммы, при необходимости указывая

значения для возврата из функции (при условии, что это значение соответствует типу возврата охватываемой функции)

discard Отсеивает текущий фрагмент и останавливает исполнение шейдера.

Оператор discard действителен только в программах фрагментного шейдера.

 

Функции

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

 

Определения

Синтаксис определения функий очень похож на “С”, с разницой в модификаторах доступа к переменным:

returnType functionName([accessModifier] type1 variable1,

[accessModifier] type2 varaible2,

...)

{

// function body

return returnValue; // unless returnType is void

}

 

Наименования функций могут быть набором из букв, цифр и нижнего подчеркивания, но не могут начинаться с цифры или с gl_, и не могут иметь в названии 2 последовательных нижних подчеркивания.

Возвратные типы могут быть любым из встроенных типов GLSL или определяемым пользователем типом массивов или структур. В качестве возвратных типов, массивы должны явно указывать свой размер. Если функция не дает возвратные переменные, она устанавливается на тип void.

Параметры функций также могут быть любого типа, в том числе массивов (которые должны указывать свой размер).

Функции должны быть или заданы по прототипу, или определаться в своем body, до того, как будут запрошены. Точно также как в С++, компилятор должен видет определение функции до того как она будет применена, иначе произойдет ошибка. Если функция используется объектом шейдера, отличным от того, где она определена, необходимо заявить прототип. Прототип это лишь заголовок функции без всего её body. Вот пример прототипа:

float HornerEvalPolynomial(float coeff[10], float x);

 

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

Хотя функции GLSL и могут изменять и возвращать значения после своего выполнения, в них нет понятия указателя или отсылки, как в “С” и С++. Вместо этого, параметры функций имеют ассоциированные с ними квалификаторы параметров, которые указывают, далжны ли данные копироваться из или в функцию по ее исполнении. Таблица 2.8 перечисляет доступные в GLSL квалификаторы параметров.

Таблица 2.8 GLSL Модификаторы доступа к параметрам функций

Модификатор Описание

in Значение, копируемое в функцию (умолчание, если не указано иначе)

const in Значение только для чтения

out Значение копируемое из функции (неопределенное при попадании в функцию)

inout Значение копируемое и в, и из функции

 

Ключевое слово in необязательно, так как если переменная не имеет при себе модификатора доступа, она по умолчанию будет распознаваться как in. Однако, если значение переменной нужно вывести из функции, необходимо добавить обозначение модификатора out (для данных только вывода) или inout (для ввода-вывода). Запись в переменную не определенную одним из этих модификаторов приведет к ошибке при компиляции.

Дополнительно, для проверки при компиляции, не изменяет ли функция переменную только для ввода, можно добавить модификатор “const in”, который даст компилятору команду не вписывать данную переменную в функцию. Если этого не сделать и записать в функцию переменную только для чтения, это повлияет только на локальную копию в функции.

 

Вычислительная инвариантность

GLSL не гарантирует, что два идентичных вычисления в разных шейдерах дадут одинаковые результаты. Это ничем не отличается от того, как работают вычислительные приложения в ПК, когда оптимизация выбора может привести к микро-отличиям в результатах. Такие маленькие нестыковки могут создать трудности при многопроходных алгоритмах, для которых необходима постоянность производимых вычислений для каждого шейдера. В GLSL есть два метода закрепления инвариантности между шейдерами, доступные по командам invariant или precise.

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

uniform float ten; // application sets this to 10.0

const float f = sin(10.0); // computed on compiler host

float g = sin(ten); // computed on graphics device

void main()

{

if (f == g) // f and g might be not equal

;

}

В этом примере, не имеет значения, применялись ли invariant или precise к использованным переменным, так как они влияют только на 2 вычисления в графическом оборудовании.

 

Квалификатор invariant

Квалификатор invariant может применяться к любой переменный вывода с шейдера. Он гарантирует, что если два вызова в шейдрах задают переменную вычисляя её одинаково, то и значения этой переменной по вычислении будут одинаковы.

Переменная вывода заявленная в invariant может быть как встроенной переменной, так и определяемой пользователем. Например:

invariant gl_Position;

invariant centroid out vec3 Color;

 

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

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

#pragma STDGL invariant (all)

Глобальная инвариантность такого рода удобна для отладки, однако, скорее всего скажется на производительности шейдера. Для гарантирования инвариантности обычно требуется отключение оптимизаций, которые мог бы произвести компилятор GLSL.

 

Квалификатор precise

Квалификатор precise может применяться к любой вычисленной переменной или возвратному значению функции. Несмотря на свое название, его функция не заключается в повышении точности, а скорее в повышении воспроизводимости вычисления. В основном он используется в мозаичных шейдерах, для предотвращения появления зазоров в геометрии. Основы мозаичного шейдера описаны в Главе 9, “Мозаичные шейдеры”, также дополнительно там описывается применение квалификатора precise.

В общих чертах, о применение precise вместо invariant можно сказать, что когда вам нужно получить одинаковый результат из выражения, даже если значения в этом выражении изменяются так, что это не влияет математически на результат. Например, следующее выражение должно иметь один и тот же результат, даже если значения a и b переставить местами, и если переставить c и d? и даже если поменять местами значения a и c, и b и d, и т.д.

Location = a * b + c * d;

Квалификатор precise может быть задан встроенной переменной, пользовательской переременной и возвратной переменной функции.

precise gl_Position;

precise out vec3 Location;

precise vec3 subdivide(vec3 P1, vec3 P2) {... }

Ключевое слово precise может быть использовано в любой момент до употребления переменной в шейдере и может модифицировать ранее указанные переменные.

Особенностью использования precise при компиляции является то, что выражения (как то, что выше) не может быть вычислено двумя разными способами умножения для двух операций умножения. Например, инструкция для первого умножения и комбинации умножение-сложение для второго. Потому что эти инструкции дадут немного разные результаты для одинаковых значений. Поскольку это стало недопустимым с использованием precise, компилятор не сможет это сделать. Но поскольку применение умножения-сложения важно для исполнительности, было бы нежелательно запретить их полностью. Поэтому есть встроенная функция fma(), которая четко говорит, что это допустимо.

precise out float result;

...

float f = c * d;

float result = fma(a, b, f);

Конечно её стоит использовать только в том слаче, если вы не хотите перестановки a и c, иначе использование precise потеряет смысл.

 

Процессор шейдера

Первым шагом в компиляции шейдера на GLSL является синтаксический анализ предпроцессором. Схоже тому как работает предпроцессор “С”, есть некоторое количество указаний по созданию условных компиляционных блоков и определению переменных. Однако в отличие от предпроцессора “С”, не существует включения файлов (#include).

 

Указания предпроцессора

Таблица 2.9 перечисляет указания, принимаемые GLSL предпроцессором и их функции.

Таблица 2.9 GLSL указания предпроцессора







Система охраняемых территорий в США Изучение особо охраняемых природных территорий(ООПТ) США представляет особый интерес по многим причинам...

Что вызывает тренды на фондовых и товарных рынках Объяснение теории грузового поезда Первые 17 лет моих рыночных исследований сводились к попыткам вычис­лить, когда этот...

ЧТО ПРОИСХОДИТ, КОГДА МЫ ССОРИМСЯ Не понимая различий, существующих между мужчинами и женщинами, очень легко довести дело до ссоры...

Что делает отдел по эксплуатации и сопровождению ИС? Отвечает за сохранность данных (расписания копирования, копирование и пр.)...





Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:


©2015- 2024 zdamsam.ru Размещенные материалы защищены законодательством РФ.