组织效果中的状态 (Direct3D 11)

使用 Direct3D 11 时,某些管道阶段的效果状态按结构进行组织。 下面是结构:

管道状态 结构
光栅化 D3D11_RASTERIZER_DESC
输出合并器 D3D11_BLEND_DESCD3D11_DEPTH_STENCIL_DESC
着色器 请参阅下文

 

对于着色器阶段,状态更改的数量需要由应用程序控制,状态已划分为常量缓冲区状态、采样器状态、着色器资源状态和无序访问视图状态 (像素和计算着色器) 。 这允许经过精心设计的应用程序仅更新正在更改的状态,从而通过减少需要传递到 GPU 的数据量来提高性能。

那么,如何组织效果中的管道状态呢?

答案是,顺序并不重要。 全局变量不必位于顶部。 但是,SDK 中的所有示例都遵循相同的顺序,因为最好以相同的方式组织数据。 因此,这是 DirectX SDK 示例中数据排序的简要说明。

全局变量

与标准 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) (效果