DirectX 11像素着色器什么是SV_POSITION?

时间:2017-10-02 14:25:57

标签: directx-11 hlsl vertex-shader pixel-shader

我正在学习DirectX 11的HLSL,我想知道什么是顶点着色器的输出SV_POSITION,以及像素着色器的输入。

1:屏幕上每个像素或对象的x,y,z是什么?

2:为什么它是4个32位浮点数?

3:您是否需要此系统变量用于顶点输出?

谢谢!

1 个答案:

答案 0 :(得分:3)

顶点着色器阶段只有一个必需的输出:顶点的位置。然后,固定功能光栅化器使用此值来计算正在绘制哪些像素,并为每个像素调用像素着色器。这是系统值语义SV_Position在顶点着色器的输出上指示的内容。像素着色器实际上并不需要将像素位置作为输入,但如果有用则可以。输入布局还必须具有使用SV_Position语义的顶点着色器的位置。

通常设置为:

  • Tnput布局描述了世界空间中顶点的位置,表示为SV_Position。输入布局描述了数据的格式。

例如:

D3D11_INPUT_ELEMENT_DESC layout[] =
{
    { "SV_Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
  • 顶点着色器输入从输入汇编程序接收该信息,该信息由顶点缓冲区的输入布局解码,也可选择使用索引缓冲区。无论位置采用何种格式,通常都会将其转换为float以供着色器使用。

  • 顶点着色器必须生成输出顶点位置,再次由SV_Position表示。这是(x, y)(-1, -1)范围内归一化坐标中像素的(1, 1)位置。 z是标准化范围01中的深度位置(用于深度缓冲区)。

例如:

float4 VS( float4 Pos : SV_Position ) : SV_Position
{
    return Pos;
}
  • 像素着色器可以选择占据位置,但不是必须的。 (x,y)位于像素坐标中。顶点输出('剪辑空间')通过使用D3D11_VIEWPORT中提供的视口状态转换为像素。

  • 像素着色器必须生成标记为float4的{​​{1}}结果。

例如:

SV_Target

从技术上讲,顶点着色器不必将位置作为输入。使用Shader Model 4.0或更好的硬件,您可以使用// We can omit the position float4 PS() : SV_Target { return float4( 1.0f, 1.0f, 0.0f, 1.0f ); } // Or you can take it as input if that's helpful float4 PS( float4 Pos : SV_Position ) : SV_Target { return float4( 1.0f, 1.0f, 0.0f, 1.0f ); } 在顶点着色器中自生生四边形的角,其代码如下所示,它不会使用任何输入布局,顶点缓冲区,或索引缓冲区。当然,它仍然必须为像素着色器生成输出位置。

SV_VertexId
  

请注意,您可以在几乎任何可以使用新VSInputTx VSQuad(uint vI : SV_VertexId) { VSInputTx vout; float2 texcoord = float2(vI & 1, vI >> 1); vout.TexCoord = texcoord; vout.Position = float4((texcoord.x - 0.5f) * 2, -(texcoord.y - 0.5f) * 2, 0, 1); return vout; } (或POSITION)语义的地方使用较旧的Direct3D 9 SV_Position语义。唯一的要求是您必须在输入布局和顶点着色器输入之间保持一致。否则它将无法绑定。

由于您不熟悉DirectX,我建议您查看DirectX Tool Kit,尤其是built-in shader source