组织效果中的状态 (Direct3D 11)
使用 Direct3D 11 时,某些管道阶段的效果状态按结构进行组织。 下面是结构:
管道状态 | 结构 |
---|---|
光栅化 | D3D11_RASTERIZER_DESC |
输出合并器 | D3D11_BLEND_DESC 和 D3D11_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) 中更详细地描述了效果着色器的语法。
相关主题