Загрузка и использование шейдера HLSL?

#c #c #direct3d #hlsl

#c #c #direct3d #hlsl

Вопрос:

Я искал везде, и все, что я могу найти, это руководства по написанию шейдеров. Ни один из них не показал мне, как включить их в мою сцену.

Итак, по сути:

Учитывая шейдер hlsl, если бы у меня была функция с именем drawTexturedQuad (), и я хотел, чтобы шейдер был применен к результату, как именно я мог бы это сделать?

Спасибо

Ответ №1:

ID3DXEffect предоставляет Begin() и BeginPass() методы. Просто вызовите drawQuad() в течение этого времени. В любом базовом руководстве по шейдерам должен быть показан такой пример.

Просто дополнительное замечание — если сомневаетесь, спросите MSDN.

Ответ №2:

Ответ на этот вопрос на удивление сложен и становится все сложнее по мере того, как аппаратное обеспечение GPU становится все более мощным. Система D3DX FX является примером всей работы, которую необходимо выполнить, поэтому ее использование — хороший шаг к тому, чтобы просто заставить вещи работать для краткосрочного использования.

Шейдеры — это код, но они находятся на другой машине от центрального процессора, поэтому все их данные должны быть упорядочены заново. Фиксированные части: базовые состояния визуализации, такие как состояния глубины, состояния трафарета, режимы наложения, команды рисования; чрезвычайно просты в реализации. Самое сложное — создать мост для программируемых частей: шейдеров, буферов, сэмплеров и текстур.

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

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

Сэмплеры и текстуры — следующие «более легкие» из сложных частей для подключения: у них есть имя переменной и довольно жесткий тип. Например, при компиляции шейдера ‘foo’ текстуре ‘myNormalMap’ присваивается текстурный слот 3. Вам нужно посмотреть (через API отражения), какой слот был назначен текстуре, и установить текстуру, которую ваш движок считает ‘myNormalMap’, в слот 3 во время выполнения, и, конечно, также использовать API, чтобы определить, нужна ли текстура вообще. Именно здесь начинают иметь значение соглашения об именовании переменных шейдера, поэтому несколько шейдеров могут быть совместимы с одним и тем же кодом C .

Постоянные буферы (или необработанные константы шейдера в D3D9) намного сложнее, особенно с программируемой шейдерной платформой, которую вы можете найти в движках вроде Unreal. Константы, используемые любым данным шейдером, являются подмножеством полного списка, но сторона C обычно должна быть написана так, как будто все они необходимы. API отражения снова необходимы для определения не только того, на какие переменные на самом деле ссылаются в шейдере, но и того, где они расположены. Это стало немного более управляемым в D3D10 и новее, поскольку cbuffers являются структурами и менее гибкими, чем система D3D9, которая была сильно ограничена количеством регистров, но это также добавляет необходимость использования API отражения для определения порядка привязок cbuffer (и на какие сами cbuffers также ссылаются).

В конце концов, есть один дизайн, позволяющий заставить все это работать:

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

Комментарии:

1. «но это также добавляет необходимость использования API-интерфейсов отражения для определения порядка привязок cbuffer (и на какие сами cbuffers также ссылаются).» — Почему бы просто не использовать соответствующее смещение буфера, например, если вы загрузили ShaderResourceView, используйте соответствующие t0, t1 и т.д., На Которые ссылаются в порядке, в котором вы устанавливаете ресурсы для шейдера.