我正在学习用于DirectX 11的HLSL,想知道在顶点着色器中作为输出,在像素着色器中作为输入的SV_POSITION到底是什么。
1:这是屏幕上每个像素的x、y、z坐标还是对象的坐标?
2:为什么要使用4个32位浮点数?
3:对于顶点输出,是否需要此系统变量?
谢谢!
我正在学习用于DirectX 11的HLSL,想知道在顶点着色器中作为输出,在像素着色器中作为输入的SV_POSITION到底是什么。
1:这是屏幕上每个像素的x、y、z坐标还是对象的坐标?
2:为什么要使用4个32位浮点数?
3:对于顶点输出,是否需要此系统变量?
谢谢!
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
是深度位置(用于深度缓冲区),范围为规范化0
到1
。
例如:
float4 VS( float4 Pos : SV_Position ) : SV_Position
{
return Pos;
}
像素着色器可以选择性地获取位置,但不一定需要。 (x,y)
是以像素为单位的坐标。顶点输出(“裁剪空间”)通过使用在D3D11_VIEWPORT
中提供的视口状态来转换为像素。
像素着色器必须生成一个标记为SV_Target
的float4
结果。
例如:
// 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 );
}
从技术上讲,顶点着色器不需要将位置作为输入。使用Shader Model 4.0或更好的硬件,您可以使用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;
}
SV_Position
(或SV_POSITION
)语义的地方使用旧的Direct3D 9 POSITION
语义。唯一的要求是您必须在输入布局和顶点着色器输入之间保持一致。否则,它将无法绑定。SV_Position是指屏幕空间坐标。
这回答了未决的问题。