Входные переменные (Input Variables)

Входные переменные шейдера объявляются спецификатором памяти in. Они формируют входной интерфейс между предыдущими шагами конвейера и объявляемым шейдером. Входные переменные должны быть объявлены в глобальной области видимости. Значения из предыдущих шагов конвейера копируются в новые переменные в начале выполнения шейдера. Запись в переменную объявленную как входную приводит к ошибке времени компиляции.

Только входные статические переменные должны быть записаны на предыдущем этапе; можно объявлять лишние (не используемые) входные переменные. Все это показано в следующей таблице:

Обработка несовместимых входных переменных
Прием/потребление шейдера (входные переменные)
Нет объявления Объявлены но не статично используются Определены и статично используются
Генерация шейдера (выходные переменные)
Не объявлены Допускается Допускается Ошибка времени линковки
Объявлены но не статично используются Допускается Допускается Допускается (значения не определены)
Объявлены и статично используются Допускается Допускается Допускается (значения потенциально не определены)

Consumption errors (ошибки получения/потребления) базируются только на статическом использовании. Компилятор может сгенерировать лишь предупреждение, но не ошибку, для любого динамического использования компилятор может сообщить, что это может привести к получению неопределенного значения.

Смотрите раздел 7 «Built-in Variables» для списка встроенных входных переменных.

Вершинный шейдер принимает переменные (или атрибуты) получает данные по-вершинно (*для каждой вершины отдельно в данном контексте). Они объявлены в вершинном шейдере со спецификатором in. Использование любого вспомогательного или интерполяционного спецификатора на входе вершинного шейдера приводит к ошибке времени компиляции. Значение копируется в шейдер по средством API или с использованием идентификатора расположения макета. Следующие примеры объявления вода в вершинный шейдер приведут к ошибке времени компиляции

  • Булевый тип (bool, bvec2, bvec3, bvec4)
  • Непрозрачный тип
  • Структура

Пример объявления в вершинном шейдере:

in vec4 position;
in vec3 normal;
in vec2 texCoord[4];

Ожидается, что графическое устройство будет иметь малое количество фиксированных векторных ячеек памяти для передачи входов вершин. Поэтому OpenGL Shading language определяет каждую не матричную входную переменную как занимающую одну такую векторную ячейку. Реализация ограничена количеством ячеек, которые могут быть использованы, и превышение их количества приведет к ошибке времени линковки. (Объявленные входные НЕ статические переменные, не учитывают этот предел.) Входные скалярные счетчики имеют тот же лимит, что и vec4, так что приложениям может потребоваться учитывать группы из четырех несвязанных float объединяемых в вектор, для более эффективного использования ресурсов железа. Матричный вход будет использовать множество ячеек памяти. Количество используемых ячеек памяти будет равно количеству столбцов в матрице.

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

in float foo[]; // вход геометрического шейдера, для вершинного “out float foo”

Каждый элемент подобного массива соответствует одной вершине обрабатываемого примитива. Каждый массив может иметь объявленный размер (опционально). Для геометрических шейдеров размер масиива будет установлен, (или если он должен быть согласован) объявление входящего layout (макета) устанавливает тип входного примитива, как будет описано в разделе 4.4.1 “Input Layout Qualifiers”.

Некоторые входы и выходы — это массивы, что означает, что интерфейс меж двумя шейдерными этапами требует наличия дополнительной передачи индекса для правильного объявления. Например интерфейс между вершинным и геометрическим шейдерами, исходящие переменные вершинного шейдера и входящие переменные геометрического шейдера с одинаковым именем должны иметь совпадающие типы, за исключением того, что геометрический шейдер будет иметь иметь одно дополнительное измерение массива что бы учитывать индексы вершин. Если такая переменная интерфейса массивов не объявлена с необходимым дополнительным входом и выходом, то в результате будет ошибка времени линковки. Вход геометрического шйдера, вход и выход шейдера управления тесселяции и вход оценки тесселяции имеют дополнительный уровень без-массивных связей со входами и выходами других шейдеров. Лимиты компонентов для интерфейсов массивов (например gl_MaxTessControlInputComponents) — это лимиты на вершину, а не на интерфейс в целом.

Для интерфейсов не-массивов (имеются в виду массивы не изменяющие размер между этапами), если типы входящей и исходящей переменных (включая размерность массива) не совпадают, то это приводит к ошибке времени линковки.

Правила согласования типов времени компиляции применяются ко всем объявленным входным и выходным переменным, вне зависимости от того используются ли они.

Так же шейдеры оценки тесселяции поддерживают входные переменные для отрывков (patch) объявленных с использованием спецификаторов patch и in. Входящие переменные для отдельных отрывков заполняются значениями выходных переменных других отрывков, записываемых шейдером контроля тесселяции. Входы отрывков могут быть объявлены как одномерные массивы, но не индексируются по количеству вершин. Применение спецификатора patch ко входам может быть выполнено только в шейдерах оценки тесселяции. Как и в случае с другими входными переменными, данные входы должны иметь тот же тип и спецификатор, что и выход на предыдущем (управление тесселяцией) шейдерном этапе. Использование patch для входов на других этапах приводит к ошибке времени компиляции.

Входы фрагментного шейдера принимают значения для отдельных фрагментов, обычно интерполированных с выхода предыдущего этапа. Они объявляются в фрагментном шейдере с помощью спецификатора in.  Могут так же применяться вспомогательные спецификаторы памяти  centroid и sample, как и интерполяционные спецификаторы  flat, noperspective, and smooth. Объявление входа фрагментного шейдера, содержащего следующее приводит к ошибке времени компиляции:

  • Булевый тип (bool, bvec2, bvec3, bvec4)
  • Непрозрачный тип

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

Примеры объявлений входов фрагментного шейдера:

in vec3 normal;
centroid in vec2 TexCoord;
invariant centroid in vec4 Color;
noperspective in float temperature;
flat in vec3 myColor;
noperspective centroid in vec2 myTexCoord;

Входы фрагментного шейдера образуют интерфейс с последним активным шейдером на вершинном этапе конвейера. Для этого интерфейса выходные переменных последнего активного шейдера этапа и входящие переменные фрагментного шейдера с таким же именем должны иметь одинаковые тип и спецификатор, за некоторым исключениям: спецификатор памяти должен, конечно, немного отличаться (in и out). Так же определение интерполяции (например flat) и вспомогательное определение (например centroid) могут отличаться. Эти несоответствия допускаются между любыми парами этапов. Когда интерполяция или вспомогательные квалификаторы не совпадают, указанные в фрагментном шейдере вытесняют предыдущие. Если какие либо спецификаторы полностью отсутствуют в фрагментном шейдере, то используется значение по умолчанию, а не спецификаторы предыдущих этапов. В общем важно то, что объявлено в фрагментном шейдере, а не на предыдущих этапах.

Когда интерфейс между шейдерными этапами формируется используя шейдеры из двух отдельных програмных объектов, невозможно выявить несоответствия между входами и выходами во время линковки. При наличии несоответствий между входами и выходами в таких интерфейсах значения, переданные через интерфейс, будут частично или полностью неопределенными. Шейдеры могут обеспечить соответствие между такими интерфейсами либо с помощью спецификаторов макета ввода и вывода (разделы 4.4.1 “Input Layout Qualifiers” и 4.4.2 “Output Layout Qualifiers”) или по средствам использования идентичных входных и выходных объявлений блоков или переменных. Полный список правил для сопоставления интерфейса между программами можно найти в разделе 7.4.1 “Shader Interface Matching” OpenGL Graphics System Specification.

Вычислительные шейдеры не допускают определяемые пользователем входные переменные и не образуют формальный интерфейс с любым другим шейдерным этапом. Смотрите раздел 7.1 “Built-In Variables” для описания встроенных входящих переменных вычислительного шейдера. Все остальные входы в вычислительный шейдер извлекаются явно через загрузки изображений, получения текстур, загрузки из uniforms или uniform buffers, или другого предоставленного пользователем кода. Не допускается переопределения встроенных входящих переменных вычислительных шейдеров.

Main Admin

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *