Модель шейдера 3 (справочник по HLSL)

Шейдеры вершин и шейдеры пикселей значительно упрощаются из более ранних версий шейдеров. Если вы реализуете шейдеры в оборудовании, вы можете не использовать vs_3_0 или ps_3_0 с другими версиями шейдеров, и вы не можете использовать любой тип шейдера с конвейером фиксированной функции. Эти изменения позволяют упростить драйверы и среду выполнения. Единственным исключением является то, что шейдеры только для программного обеспечения vs_3_0 могут использоваться с любой версией шейдера пикселей. Кроме того, если вы используете шейдер только для программного обеспечения vs_3_0 с предыдущей версией шейдера пикселей, шейдер вершин может использовать только выходные семантики, совместимые с кодами гибкого формата вершин (FVF).

Семантика, используемая для выходных данных шейдера вершин, должна использоваться для входных данных шейдера пикселей. Семантика используется для сопоставления выходных данных шейдера вершин с входными данными шейдера пикселей, аналогично тому, как объявление вершин сопоставляется с регистрами входных данных вершинного шейдера и предыдущими моделями шейдеров. См. раздел "Семантика соответствия" для шейдеров 3.0 и ps 3.0.

Добавлены дополнительные состояния отрисовки режима оболочки для покрытия возможности дополнительных координат текстур в этой новой схеме. Атрибуты с индексом D3DDECLUSAGE_TEXCOORD и использования от 0 до 15 интерполируются в режиме оболочки при установке соответствующего D3DRS_WRAP*.

Возможности модели шейдера вершин 3

Типы выходных регистров шейдеров вершин были свернуты в двенадцать регистров (см. регистры выходных данных). Каждый регистр, который используется, должен быть объявлен с помощью инструкции dcl и семантики (например, dcl_color0 o0.xyzw).

Модель шейдера вершин 3_0 (vs_3_0) расширяет возможности vs_2_0 с более мощным индексированием регистров, набором упрощенных регистров выходных данных, возможностью выборки текстуры в вершинном шейдере и возможностью управлять скоростью, с которой инициализированы входные данные шейдера.

Индексирование любого регистра

Все регистры (регистр входных данных и регистры выходных данных) можно индексировать с помощью регистра счетчика циклов (только регистры констант можно индексировать в более ранних версиях).)

Перед их индексированием необходимо объявить входные и выходные регистры. Однако вы не можете индексировать любой выходной регистр, объявленный с семантикой размера позиции или точки. Фактически, если индексирование используется позицией и семантикой psize, необходимо объявить в регистрах o0 и o1 соответственно.

Можно индексировать только непрерывный диапазон регистров; То есть нельзя индексировать регистры, которые не объявлены. Хотя это ограничение может оказаться неудобным, это позволяет выполнять оптимизацию оборудования. При попытке индексироваться между несвязанными регистрами будут возникать неопределенные результаты. Проверка шейдера не применяет это ограничение.

Упрощение регистров выходных данных

Все различные типы регистров вывода были свернуты в двенадцать выходных регистров: 1 для позиции, 2 для цвета, 8 для текстуры и 1 для тумана или размера точек. Эти регистры интерполируют все данные, содержащиеся в шейдере пикселей. Объявления регистра выходных данных являются обязательными, а семантика назначается каждому регистру.

Регистры можно разбить следующим образом:

  • По крайней мере один регистр должен быть объявлен как регистр положения четырехкомпонентных компонентов. Это единственный обязательный регистр шейдера вершин.
  • Первые десять регистров, потребляемых шейдером, могут использовать максимум до четырех компонентов (xyzw).
  • Последний (или двенадцатый) регистр может содержать только скалярный (например, размер точки).

Список регистров см. в разделе Registers — vs_3_0.

Пример текстуры в шейдере вершин

Вершинный шейдер 3_0 поддерживает поиск текстур в шейдере вершин с помощью texldl - vs.

Возможности модели шейдера пикселей 3

Цвета и регистры текстур пикселей были свернуты в десять входных регистров (см. раздел Типы входных регистров). Регистр лиц — это скалярный регистр с плавающей запятой. Допустимы только знак этого регистра. Если знак отрицательный, то примитив является задней лицой. Это можно использовать внутри шейдера пикселей для достижения двухстороннего освещения, например. Регистр позиции ссылается на текущие пиксели (x,y).

Регистры констант шейдера можно задать с помощью следующих способов:

Сопоставление семантики на vs_3_0 и ps_3_0 шейдерах

Существуют некоторые ограничения на использование семантики с vs_3_0 и ps_3_0. Как правило, при использовании семантики для входных данных шейдера, который соответствует семантике, используемой в выходных данных шейдера.

Например, этот шейдер пикселей упаковывает несколько имен в один регистр:

ps_3_0 
dcl_texcoord0 v0.x 
dcl_texcoord1 v0.yz // Valid to pack multiple names into one register 
dcl_texcoord2_centroid v1.w
...

Каждый регистр имеет другую семантику. Обратите внимание, что вы также можете назвать v0.x и v0.yz с разными семантиками (несколько) из-за использования маски записи.

Учитывая шейдер пикселей, с ним нельзя связать следующее vs_3_0 шейдер:

vs_3_0 
... 
dcl_texcoord0 o5.x 
dcl_texcoord1 o6.yzw 
...

Эти два шейдера конфликтуют с использованием D3DDECLUSAGE_TEXCOORD0 И D3DDECLUSAGE_TEXCOORD1 семантики.

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

vs_3_0 
... 
dcl_texcoord2 o3 
dcl_texcoord3 o9 
...

Аналогичным образом, семантические имена, объявленные для разных входных регистров в шейдере пикселей (v0 и v1 в шейдере пикселей), нельзя использовать в одном регистре выходных данных в этом шейдере вершин. Например, этот шейдер вершин не может быть связан с шейдером пикселей, так как D3DDECLUSAGE_TEXCOORD1 используется для входных регистров шейдера пикселей (v0, v1) и выходного регистра вершинного шейдера o3.

vs_3_0 
... 
dcl_texcoord0 o3.x 
dcl_texcoord1 o3.yz 

dcl_texcoord2 o3.w // BAD! Would be valid if this were not o3 
dcl_texcoord3 o9 ... 

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

vs_3_0 
... 
dcl_texcoord0 o5.x 
dcl_texcoord1 o5.yzw 
dcl_texcoord2 o7.yz // BAD! Would be valid if w were included 
dcl_texcoord3 o9 
... 

Этот шейдер вершин не предоставляет выходные данные с одним из семантических имен, запрошенных шейдером пикселей, поэтому связывание шейдера недопустимо:

vs_3_0 
... 
dcl_texcoord0 o5.x 
dcl_texcoord1 o5.yzw 
dcl_texcoord3 o9 
// The pixel shader wants texcoord2, with a w component, 
// but it isn't output by this vertex shader at all! 
... 

Изменения режима тумана, глубины и заливки

Если D3DRS_SHADEMODE задано для плоской заливки во время вырезки и растеризации треугольников, атрибуты с D3DDECLUSAGE_COLOR интерполируются как плоские оттенки. Если какие-либо компоненты регистра объявлены семантикой цвета, но другие компоненты одного и того же регистра имеют другую семантику, интерполяция неструктурированных (линейная и плоская) будет не определена для компонентов в этом регистре без семантики цвета.

Если требуется отрисовка тумана, vs_3_0 и ps_3_0 шейдеры должны реализовать туман. За пределами шейдеров не выполняются вычисления тумана. Нет регистра тумана в vs_3_0, а дополнительные семантики D3DDECLUSAGE_FOG (для коэффициента тумана, вычисляемого на вершину) и D3DDECLUSAGE_DEPTH (для передачи значения глубины в шейдер пикселей для вычисления коэффициента смешения тумана) были добавлены.

Состояние стадии текстуры D3DTSS_TEXCOORDINDEX игнорируется при использовании шейдера пикселей 3.0.

Для удовлетворения этих изменений добавлены следующие значения:

// Fog and Depth usages
D3DDECLUSAGE_FOG 
D3DDECLUSAGE_DEPTH 

// Additional wrap states for vs_3_0 attributes with D3DDECLUSAGE_TEXCOORD 
D3DRS_WRAP8 
D3DRS_WRAP9 
D3DRS_WRAP10 
D3DRS_WRAP11 
D3DRS_WRAP12 
D3DRS_WRAP13 
D3DRS_WRAP14 
D3DRS_WRAP15

Преобразования с плавающей запятой и целыми числами

Математика с плавающей запятой выполняется с разными точностью и диапазонами (16-разрядная, 24-разрядная и 32-разрядная) в разных частях конвейера. Значение, превышающее динамический диапазон конвейера, который входит в этот конвейер (например, 32-разрядная карта текстуры с плавающей запятой выполняется в 24-разрядном конвейере с плавающей запятой в ps_2_0) создает неопределенный результат. Для прогнозируемого поведения следует зажать такое значение в максимальном динамическом диапазоне.

Преобразование из значения с плавающей запятой в целое число происходит в нескольких местах, например:

  • При обнаружении mova - vs инструкции.
  • Во время адресации текстур.
  • При записи в целевой объект отрисовки не с плавающей запятой.

Указание полной или частичной точности

Обе ps_3_0 и ps_2_x обеспечивают поддержку двух уровней точности:

ps_3_0 ps_2_0 Точность Ценность
x Полный fp32 или более поздней версии
x Частичная точность fp16=s10e5
x x Полный fp24=s16e7 или более поздней версии
x x Частичная точность fp16=s10e5

 

ps_3_0 поддерживает большую точность, чем ps_2_0. По умолчанию все операции выполняются на полном уровне точности.

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

Модификатор _pp может выполняться в двух контекстах:

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

Приложение может намеренно отключать точность для повышения производительности. Существует несколько типов входных данных шейдера, которые являются естественными кандидатами для частичной обработки точности:

  • Цветовые итераторы хорошо представлены значениями частичной точности.
  • Значения текстур из большинства форматов могут быть точно представлены значениями частичной точности (значения, полученные из 32-разрядных текстур с плавающей запятой, являются очевидным исключением).
  • Константы могут быть представлены частичным представлением точности в соответствии с шейдером.

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

Программные вершины и шейдеры пикселей

Реализация программного обеспечения (время выполнения и справочник по шейдерам вершин и справочник по шейдерам пикселей) шейдеров версии 2_0 и более поздних версий имеют некоторое расслабление проверки. Это полезно для отладки и создания прототипов. Приложение указывает среде выполнения или сборщику, что он нуждается в некоторой проверке, расслабленной с помощью флага _sw в сборщике (например, vs_2_sw). Программный шейдер не будет работать с оборудованием.

vs_2_sw — это расслабление до максимального количества vs_2_x; аналогичным образом, ps_2_sw является расслаблением до максимальных ограничений ps_2_x. В частности, следующие проверки расслаблены:

Модель шейдера Ресурс Предел
vs_2_sw, vs_3_sw, ps_2_sw, ps_3_sw Счетчики инструкций Неограниченный
vs_2_sw, vs_3_sw, ps_2_sw, ps_3_sw Регистры с плавающей константой 8192
vs_2_sw, vs_3_sw, ps_2_sw, ps_3_sw Целые регистры констант 2048
vs_2_sw, vs_3_sw, ps_2_sw, ps_3_sw Логические регистры констант 2048
ps_2_sw Глубина чтения зависимых данных Неограниченный
vs_2_sw Инструкции и метки управления потоком Неограниченный
vs_2_sw, vs_3_sw, ps_2_sw, ps_3_sw Цикл запуска, шага и подсчета Размер шага итерации для инструкций по повторению и циклу — 32-разрядные целые числа со знаком. Число может составлять до MAX_INT/64.
vs_2_sw, vs_3_sw, ps_2_sw, ps_3_sw Ограничения портов Ограничения портов для всех файлов регистрации расслаблены.
vs_3_sw Количество интерполяторов 16 выходных регистров в vs_3_sw.
ps_3_sw Количество интерполяторов Входные регистры 14(16-2) для ps_3_sw.

 

модель шейдера 3 (DirectX HLSL)