Организация состояния в эффекте (Direct3D 11)

В Direct3D 11 состояние эффекта для определенных этапов конвейера упорядочено по структурам. Ниже приведены структуры.

Состояние конвейера Структура
Растеризации D3D11_RASTERIZER_DESC
Средство слияния выхода D3D11_BLEND_DESC и D3D11_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 11). Синтаксис для образцов текстур эффектов более подробно описан в разделе Тип выборки (DirectX HLSL).

Шейдеры

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

  • Шейдеры вершин — работают с данными вершин. Одна вершина в возвращает одну вершину.
  • Шейдеры корпуса — работают с данными исправлений. Этап контрольной точки: один вызов дает одну контрольную точку; Для каждой фазы вилки и соединения: одно исправление дает некоторое количество данных о константе исправления.
  • Шейдеры предметной области — работают с примитивными данными. Один примитив может получить 0, 1 или множество примитивов.
  • Геометрические шейдеры — работают с примитивными данными. Один примитив в может дать 0, 1 или много примитивов.
  • Пиксельные шейдеры — работают с пиксельными данными. Один пиксель в возвращает 1 пиксель (если пиксель не выбирается из отрисовки).

Конвейер шейдера вычислений использует один шейдер:

  • Шейдеры вычислений — работают с данными любого типа. Выходные данные не зависят от количества потоков.

Шейдеры являются локальными функциями и следуют правилам функций в стиле C. При компиляции эффекта компилируется каждый шейдер, а указатель на каждую функцию шейдера сохраняется внутри. Интерфейс ID3D11Effect возвращается при успешной компиляции. На этом этапе скомпилированный эффект имеет промежуточный формат.

Чтобы узнать больше о скомпилированных шейдерах, необходимо использовать отражение шейдера. По сути, это похоже на запрос среды выполнения декомпилировать шейдеры и вернуть вам сведения о коде шейдера.

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 11).

Группы, методы и проходы

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

Группы являются необязательными. Существует одна неименованная группа, которая охватывает все глобальные методы. Все остальные группы должны иметь имена.

Ниже приведен пример одного метода (который включает один проход) из BasicHLSL10.fx.

technique10 RenderSceneWithTexture1Light
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, RenderSceneVS( 1, true, true ) ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, RenderScenePS( true ) ) );
    }
}

fxgroup g0
{
    technique11 RunComputeShader
    {
        pass P0
        {
            SetComputeShader( CompileShader( cs_5_0, CS() ) );
        }
    }
}

Синтаксис шейдеров эффектов более подробно описан в разделе Синтаксис методов эффектов (Direct3D 11).

Эффекты (Direct3D 11)