Поделиться через


Модель шейдера 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 And D3DDECLUSAGE_TEXCOORD1 .

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

vs_3_0 
... 
dcl_texcoord2 o3 
dcl_texcoord3 o9 
...

Аналогичным образом семантические имена, объявленные в разных входных регистрах в пиксельном шейдере (версии 0 и 1 в пиксельном шейдере), не могут использоваться в одном регистре выходных данных в этом вершинном шейдере. Например, этот вершинный шейдер нельзя связать с пиксельным шейдером, так как 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 - и инструкции.
  • Во время адресации текстуры.
  • При записи в целевой объект отрисовки без плавающей запятой.

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

И 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 Начало цикла, шаг и счетчики Размер шага начала итерации для инструкций rep и цикла — это 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)