在光栅化阶段,来自顶点(或几何)着色器的顶点属性输出在三角形的像素进行插值。插值的取值之后会输入到像素着色器中。假设没有几何着色器,下图解释了到目前为止顶点数据所采用的路径。
像素着色器函数和顶点着色器很像,但它会对每个像素片段都执行一次操作。给像素着色器一个输入,他就会计算每一个像素片段的颜色值。我们注意到像素片段可能不会保留下来并进入到后台缓冲区;比如,它可能在像素着色器中被裁剪(HLSL有一个cilp函数,可以通过进一步的处理丢弃像素片段)、被另一个具有更小深度值的像素片段遮挡,或者是被之后的管线测试丢弃,比如模版缓冲测试。因此,后台缓冲区的一个像素可能有多个候选像素片段;这就是“像素”和“像素片段”的区别,尽管有时候这两个术语可以互换,但是通过上下文,它的含义就很清晰了。
下例是一个简单的与上一篇文章提到的
顶点着色器示例
对应的像素着色器,为了完整性,会再写一遍顶点着色器:
cbuffer cbPerObject
{
float4x4 gWorldViewProj;
};
void VS(float3 iPos : POSITION, float4 iColor : COLOR,
out float4 oPosH : SV_POSITION,
out float4 oColor : COLOR)
{
// Transform to homogeneous clip space.
oPosH = mul(float4(iPos, 1.0f), gWorldViewProj);
// Just pass vertex color into the pixel shader.
oColor = iColor;
}
float4 PS(float4 posH : SV_POSITION, float4 color : COLOR) : SV_Target
{
return pin.Color;
}
在本例中,像素着色器简单地返回插值的颜色值。注意像素着色器的输入和顶点着色器的输出是确切地匹配的;而且要求也是这样的。像素着色器返回一个4D的颜色值,参数列表之后的语义
SV_TARGET
表示返回值类型要和渲染目标的格式匹配。
我们可以将上述代码等效地重写为使用接头体输入/输出的形式。符号的不同之处在于,我们将语义附加到成员的输入/输出结构体,而且用return语句输出而不是参数输出。
cbuffer cbPerObject
{
float4x4 gWorldViewProj;
};
struct VertexIn
{
float3 Pos : POSITION;
float4 Color : COLOR;
};
struct VertexOut
{
float4 PosH : SV_POSITION;
float4 Color : COLOR;
};
VertexOut VS(VertexIn vin)
{
VertexOut vout;
// Transform to homogeneous clip space.
vout.PosH = mul(float4(vin.Pos, 1.0f), gWorldViewProj);
// Just pass vertex color into the pixel shader.
vout.Color = vin.Color;
return vout;
}
float4 PS(VertexOut pin) : SV_Target
{
return pin.Color;
}
版权声明:本文为qq_38319794原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。