Поделиться через


Упорядочение состояния в эффекте (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).

Эффекты (Direct3D 10)