我正在学习DirectX 11的HLSL,我想知道SV_POSITION是什么,它是Vertex Shader的输出,还是Pixel Shader的输入。

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

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

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中提供的视口(viewport)状态,将顶点输出(“剪辑空间”)转换为像素。
  • 像素着色器必须产生标记为float4SV_Target结果。

  • 例如:
    // 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;
    }
    



    由于您是DirectX的新手,因此建议您看看DirectX Tool Kit,尤其是built-in shader source

    10-06 05:43