Упорядочение состояния в эффекте (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 или несколько выходящих примитивов.
- Шейдеры пикселей — работают с данными пикселей. Один входной пиксель соответствует одному выходному пикселю (если только пиксель не исключается из отрисовки).
Шейдеры — это локальные функции и следуйте правилам функций стиля 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).
Связанные разделы