Упорядочение состояния в эффекте (Direct3D 10)
В Direct3D 10 состояние эффекта для определенных этапов конвейера упорядочено по следующим структурам:
Состояние конвейера | Структура |
---|---|
Сборщик входных данных | D3D10_INPUT_ELEMENT_DESC |
Растеризации | D3D10_RASTERIZER_DESC |
Средство слияния выхода | D3D10_BLEND_DESC и D3D10_DEPTH_STENCIL_DESC |
Для этапов шейдера, где количество изменений состояния должно более контролироваться приложением, состояние было разделено на постоянное состояние буфера, состояние выборки и состояние ресурса шейдера. Это позволяет приложению, которое тщательно предназначено для обновления только изменяющегося состояния, что повышает производительность за счет уменьшения объема данных, которые необходимо передать в GPU.
Итак, как организовать состояние конвейера в эффекте?
Ответ в том, что порядок не имеет значения. Глобальные переменные не обязательно должны находиться вверху. Однако все примеры в пакете SDK соответствуют тому же порядку, так как рекомендуется упорядочивать данные одинаково. Итак, это краткое описание порядка данных в примерах пакета SDK для DirectX.
Глобальные переменные
Как и в стандартной практике C, сначала объявляются глобальные переменные в верхней части файла. Чаще всего это переменные, которые будут инициализированы приложением, а затем используются в эффекте. Иногда они инициализируются и никогда не изменяются, в других случаях они обновляются для каждого кадра. Как и функция C область правил, переменные эффекта, объявленные вне область функций эффекта, видны во всем эффекте; любая переменная, объявленная внутри функции эффекта, видна только внутри этой функции.
Ниже приведен пример переменных, объявленных в BasicHLSL10.fx.
// Global variables
float4 g_MaterialAmbientColor; // Material's ambient color
Texture2D g_MeshTexture; // Color texture for mesh
float g_fTime; // App's time in seconds
float4x4 g_mWorld; // World matrix for object
float4x4 g_mWorldViewProjection; // World * View * Projection matrix
// Texture samplers
SamplerState MeshTextureSampler
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
Синтаксис переменных эффекта более подробно описан в разделе Синтаксис переменной эффекта (Direct3D 10). Синтаксис для дискретизаторов текстур эффектов более подробно описан в разделе Тип выборки (DirectX HLSL).
Шейдеры
Шейдеры — это небольшие исполняемые программы. Шейдеры можно рассматривать как инкапсуляцию состояния шейдера, так как код HLSL реализует функциональные возможности шейдера. Конвейер использует три разных типа шейдеров.
- Шейдеры вершин — работают с данными вершин. Одна вершина в дает одну вершину.
- Геометрические шейдеры — работают с примитивными данными. Один примитив в может привести к получению 0, 1 или многих примитивов.
- Пиксельные шейдеры — работают с пиксельными данными. Один пиксель в дает 1 пиксель из (если пиксель не выбраковывается из отрисовки).
Шейдеры являются локальными функциями и следуют правилам функций в стиле C. При компиляции эффекта компилируется каждый шейдер, а указатель на каждую функцию шейдера хранится внутри. При успешной компиляции возвращается интерфейс ID3D10Effect. На этом этапе скомпилированный эффект имеет промежуточный формат.
Чтобы получить дополнительные сведения о скомпилированных шейдерах, необходимо использовать отражение шейдера. По сути, это похоже на запрос среды выполнения на декомпилию шейдеров и возврат сведений о коде шейдера.
struct VS_OUTPUT
{
float4 Position : SV_POSITION; // vertex position
float4 Diffuse : COLOR0; // vertex diffuse color
float2 TextureUV : TEXCOORD0; // vertex texture coords
};
VS_OUTPUT RenderSceneVS( float4 vPos : POSITION,
float3 vNormal : NORMAL,
float2 vTexCoord0 : TEXCOORD,
uniform int nNumLights,
uniform bool bTexture,
uniform bool bAnimate )
{
VS_OUTPUT Output;
float3 vNormalWorldSpace;
....
return Output;
}
struct PS_OUTPUT
{
float4 RGBColor : SV_Target; // Pixel color
};
PS_OUTPUT RenderScenePS( VS_OUTPUT In,
uniform bool bTexture )
{
PS_OUTPUT Output;
if( bTexture )
Output.RGBColor = g_MeshTexture.Sample(MeshTextureSampler, In.TextureUV) * In.Diffuse;
....
return Output;
}
Синтаксис шейдеров эффектов более подробно описан в разделе Синтаксис функции эффектов (Direct3D 10).
Методы и проходы
Метод — это коллекция проходов отрисовки (должно быть по крайней мере один проход). Каждый проход эффекта (который в область похож на один проход в цикле отрисовки) определяет состояние шейдера и любое другое состояние конвейера, необходимое для отрисовки геометрии.
Ниже приведен пример одного метода (который включает один проход) из BasicHLSL10.fx.
technique10 RenderSceneWithTexture1Light
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0, RenderSceneVS( 1, true, true ) ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, RenderScenePS( true ) ) );
}
}
Синтаксис шейдеров эффектов более подробно описан в разделе Синтаксис метода эффектов (Direct3D 10).
Связанные темы