Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
insrukcii k lr3_ robota z podiyamy.doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
883.71 Кб
Скачать

Функции и семантики hlsl

Данные в HLSL упаковываются в функции для выполнения определенных действий, например, можно объявить такую функцию

float4 MainVS(float3 pos)

{

return float4(pos, 1.0);

}

Но она не является полноценным векторным шейдером VS. С точки зрения DirectX это всего лишь простая функция, принимающая в качестве параметра трехмерный вектор и возвращающая четырехмерный вектор. Описание вершины может содержать множество разнородных данных: цвет, геометрические координаты и т.п. Поэтому мы должны указать, какой именно вид данных нужно обрабатывать в функции. В HLSL для этой цели используются так называемые семантики (semantics), предназначенные для указания именно тех данных, которые будут проходить через различные ступени обработки графического конвейера.

Для более сложных данных в названии семантики требуется указывать целочисленный индекс. При отсутствии индекса в названии семантики он полагается равным 0. Вот пример некоторых семантик с индексом n:

Семантика

Описание

POSITION[n]

Координаты вершины

COLOR[n]

Цвет вершины

PSIZE[n]

Размер точки (при визуализации набора точек)

Уточняющая семантика пишется через двоеточие после объявления обрабатываемого данного: для входного параметра функции - после его объявления в списке параметров, для выходного - после заголовка функции. Таким образом, в нашем примере для связи входного (выходного) параметра pos функции MainVS() с координатами вершины необходимо использовать семантику POSITION:

float4 MainVS(float3 pos : POSITION) : POSITION

{

return float4(pos, 1.0);

}

Вот теперь мы наконец-то получили полноценный вершинный шейдер VS. Следующий этап - написание пиксельного шейдера PS. Наш пиксельный шейдер будет просто закрашивать все пикселы цветом морской волны ( Aqua = {0, 255, 255} ). Но в HLSL для определения цветов приняты вещественные значения и яркость соответствующего цвета модели RGB задается в диапазоне (0.0, 1.0). Поэтому для цвета Aqua и непрозрачного альфа-канала окончательный код пиксельного шейдера будет таким

float4 MainPS() : COLOR

{

return float4(0.0, 1.0, 1.0, 1.0); // RGB hex=(0x00FFFF) и непрозрачный альфа-канал 0xFF

}

Техники, проходы и профили hlsl

Мы получили функции для вершинного и пиксельного процессора - вершинный и пиксельный шейдеры. Заключительный этап написания эффекта - создание техники (technique), использующей эти шейдеры. Ниже приведено определение техники с названием Fill, использующей вершинный шейдерMainVS() и пиксельный шейдер MainPS():

technique Fill

{

pass p0

{

VertexShader = compile vs_1_1 MainVS();

PixelShader = compile ps_1_1 MainPS();

}

}

Как видно, техника определяется с использованием ключевого слова technique. Каждая техника содержит один или несколько проходов, объявляемых с использованием ключевого слова pass. В свою очередь, каждому проходу ставится в соответствие пиксельный и вершинный шейдер. Наша техникаFill содержит единственный проход с названием p0, внутри которого используется синтаксис:

VertexShader = compile {используемый профиль} {вершинный шейдер};

PixelShader = compile {используемый профиль} {пиксельный шейдер};

Профиль шейдера (shader profile) определяет версию языка HLSL, на котором будет скомпилирован шейдер. Профиль учитывает архитектурные особенности целевого графического процессора при генерации промежуточного ассемблерного кода. В большинстве случаев каждой версии HLSLсоответствует один профиль. Например, языку Vertex Shader 1.1 соответствует профиль vs_1_1, Pixel Shader 1.4 – профиль ps_1_4, Pixel Shader 2.0 – профиль ps_2_0, и так далее. Однако некоторым языкам, вроде Pixel Shader 2.x, соответствует два профиля: в данном случае это ps_2_a и ps_2_b, при этом первый профиль генерирует код Pixel Shader 2.x, оптимизированный под архитектуру графического процессора NV3x, а второй – под R4xx. Ниже приведено соответствие между профилями и версиями HLSL.

Профиль

Версия вершинных шейдеров

vs_1_0

1.0

vs_1_1

1.1

vs_2_0

2.0

vs_2_a

2.x

vs_3_0

3.0

Профиль

Версия пиксельных шейдеров

ps_1_0

1.0

ps_1_1

1.1

ps_1_2

1.2

ps_1_3

1.3

ps_1_4

1.4

ps_2_0

2.0

ps_2_a

2.x (оптимизация для NV3x)

ps_2_b

2.x (оптимизация для R4xx)

ps_3_0

3.0

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

Допустим, необходимо, чтобы наша программа могла работать на видеокартах класса ATI Radeon 9500 (R3xx) и выше, NVIDIA GeForce FX 5200 (NV3x)и выше, а так же Intel GMA 900 и выше. Все эти видеокарты поддерживают профили вершинных шейдеров vs_1_0, vs_1_1, vs_2_0 и профили пиксельные шейдеров ps_1_0, ps_1_1, ps_1_2, ps_1_3, ps_1_4 и ps_2_0. Таким образом, можно смело использовать профили vs_2_0 и ps_2_0 для всех шейдеров. При этом для некоторых эффектов можно предусмотреть дополнительные техники (technique) для видеокарт класса High End, использующих профили vs_3_0 и ps_3_0.

Если мы хотим поступиться эффективностью в пользу масштабируемости приложения, следует использовать минимальную версию профилей, необходимую для нормальной компиляции шейдеров, например, профили vs_1_1 и ps_1_1. Это позволит работать нашему приложению даже на стареньких видеокартах семейства GeForce3 (NV20).

Добавление эффекта в приложение

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

  • В панели Solution Explorer вызовите контекстное меню для узла Application2 и командой Add/New Folder создайте папку с именем Data

  • В панели Solution Explorer вызовите контекстное меню для папки Data и командой Add/New Item добавьте в нее текстовый файл с именемColorFill.fx

увеличить изображение

  • В панели Solution Explorer выделите файл ColorFill.fx и в панели Properties установите для него свойство Copy to Output Directory в значение Copy if newer (копировать в каталог сборки свежую версию файла)

  • Заполните файл с эффектом следующим кодом

struct VertexInput

{

float4 pos : POSITION;

float4 color : COLOR;

};

struct VertexOutput

{

float4 pos : POSITION;

float4 color : COLOR;

};

VertexOutput MainVS(VertexInput input)

{

return input;

}

float4 MainPS(VertexOutput input):COLOR

{

return input.color;

}

technique Fill

{

pass p0

{

VertexShader = compile vs_1_1 MainVS();

PixelShader = compile ps_1_1 MainPS();

}

}

Для использования созданного эффекта его нужно загрузить из файла эффекта в приложение и откомпилировать в байт-код. Для этого применяется одна из перегрузок статического метода класса Effect, в том числе

public static Microsoft.Xna.Framework.Graphics.CompiledEffect CompileEffectFromFile(

string effectFile,

Microsoft.Xna.Framework.Graphics.CompilerMacro[] preprocessorDefines,

Microsoft.Xna.Framework.Graphics.CompilerIncludeHandler includeHandler,

Microsoft.Xna.Framework.Graphics.CompilerOptions options,

Microsoft.Xna.Framework.TargetPlatform platform

)

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]