Philip Taylor "Programmable Shaders for Direct 8.0" Опубликовано 15 января 2001

Программные шейдеры Direct3D, Часть 2

Пиксельные шейдеры

Когда используются программируемые пиксельные шейдеры, они заменяют мультитекстурирование в пиксельном конвейере Direct3D. Пиксельная обработка, выполняемая шейдером, охватывает операции, применяемые только к одному пикселю (по аналогии с вершинными шейдерами). Последовательность операций в пиксельном конвейере такова:

Пиксельные шейдеры контролируют операции над цветом и альфа-смешиванием, и операции над адресацией текстуры. Результат, полученный пиксельным шейдером, записывается в регистр r0. Его значение передается для дальнейшей обработки в пиксельном конвейере.

Тип ресурса
Макс. количество
   Текстурные регистры (Texture registers)
4
   Временные регистры (Temp registers)
2
   Цветовые регистры (Color registers)
2
   Константные регистры (Constant registers)
8
   Нет выходных регистров
результат записывается в r0
   Максимальное количество команд
8

Таблица 1. Ресурсы пиксельного шейдера

Команда пиксельного шейдера имеет следующий формат:

op, dest, src0,src1,src2

где:

В пиксельных шейдерах имеются два вида команд: смешивание цвета/альфа-канала и команды адресации текстур. Другие две команды шейдера эквивалентны двум командам вершинных шейдеров: определение константы и версии шейдера. Имейте ввиду, я пропустил дополнительную операцию и модификаторы аргументов. Смотрите документацию Direct3D, чтобы узнать о них больше. Операции пиксельных цвето- и альфа-смешиваний влияют на данные о цвете пикселя.

В командах пиксельного шейдера нет операций условного перехода, что означает возможность их быстрой реализации. Каждая команда выполняется за один машинный цикл, подобно командам вершинного шейдера. Аппаратно пиксельные шейдеры выполняются на двух параллельных конвейерах: векторный конвейер для RGB данных и скалярный конвейер для данных альфа-канала. Команды могут быть спарены для параллельного выполнения на обоих конвейерах. При их параллельном использовании, значительно уменьшается загрузка процессора и сокращается общее число машинных циклов, необходимых для выполнения шейдера.

Ниже показан пример спаривания команд, где знак (+) указывает на вторую команду в паре:

    mul r0.rgb, t0, v0 // Перемножаем цветовые компоненты регистров t0 и v0
 + add r0.a, t0, v0 // Но альфа-компоненты просто суммируем

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

dp3 r0.rgb, t0, v0
mul r0.a, t0, v0

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

Текстурные декларации (команды адресации текстур), в отличие от команд цвето- и альфа-смешивания, являются отдельным набором инструкций пиксельного шейдера. Эти команды должны находиться в самом начале шейдера и могут использовать только заранее определенные величины. Они также выполняют другие действия. Например, вы можете использовать их для того, чтобы менять текстурные координаты с помощью различных эффектов смещения. Есть прямое распределение между цветом входного регистра и этапами текстур. Временные регистры пиксельного шейдера Direct3D хранят в себе предварительные цвета текстур с этапов соответствующей текстуры. И наоборот, текстуры связываются со временными регистрами, при вызове метода IDirect3DDevice8::SetTexture. Кроме того, текстурные координаты напрямую отображаются и определяются текстурными декларациями. Синтаксис для получения эффекта смещения адреса текстуры определяется в пределах программы шейдера в форме деклараций текстуры. Подмножество команд адресаций показана в таблице 2. Они должны быть впереди других команд.

Команда
Описание
tex
   без изменений
texbem
   карта рельефного окружения (bump environment map)
texbeml
   карта рельефного окружения с яркостью
texcoord
   текстурная координата
texkill
   маскирование пикселя
texm3x2pad
   входное значение умножается на матрицу 3х2
texm3x2tex
   результат умножается на матрицу 3х2
texreg2ar
   переназначения красного и альфа компонентов
texreg2gb
   переназначения зеленого и синего компонентов

Таблица 2. Команды адресации текстур

Кроме того, пикселный шейдер поддерживает много методов попиксельного умножения матрицы 3x3 на вектор, взятый из текстуры. Матрица 3x3 составляется из текстурных координат из трех последовательных этапов текстурных деклараций.

Команда
Описание
texm3x3pad
   входное значение умножается на матрицу 3х3
texm3x3tex
   результат умножается на матрицу 3х3
texm3x3spec
   наложение карт окружения и отражение
texm3x3vspec
   то же самое, но без вектора наблюдения

Таблица 3. Команды адресации текстур 3x3

Остались команды, оперирующие цветом и альфа-каналом. Эти команды меняют цвет пикселя. Все команды пиксельного шейдера выполняются над одним пикселом, и ничего не известно о других пикселах в конвейере.

Команда
Описание
add
   сумма
cnd
   условный оператор
dp3
   трех-компонентное скалярное векторное произведение
lrp
   линейное интерполирование
mad
   умножить и сложить
mov
   копировать
mul
   произведение
sub
   разность

Таблица 4. Команды, оперирующие цветом и альфа-каналом.

Теперь, когда мы понимаем назначение пиксельного шейдера, посмотрите на рисунок 1, чтобы представить себе его архитектуру.

Рисунок 1. Архитектура пиксельного шейдера

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

ps.1.0 ; Версия шейдера
tex t0 ; Назначение текстуры
texm3x3pad t1, t0_bx2 ; Первый столбец трансформации
texm3x3pad t2, t0_bx2 ; Второй столбец трансформации
texm3x3pad t3, t0_bx2 ; Третий столбец трансформации
dp3_sat r0, t3_bx2, v0_bx2

Метод IDirect3DDevice::CreatePixelShader используется для создания пиксельного шейдера. Вы можете контроллировать состояния пиксельного конвейера, вызывая методы IDirect3DDevice8::SetTexture, IDirect3DDevice8::SetTextureStageState, IDirect3DDevice8::SetPixelShader, и IDirect3Ddevice8::SetPixelShaderConstant. Чтобы скомпилировать шейдер, используйте D3DXAssembleShader и D3DXAssembleShaderFromFileA / D3DXAssembleShaderFromFileW.

Hosted by uCoz