模板测试和深度测试很相似:
1.如果模板测试不通过,则该像素会被舍弃
2.有模板缓冲区,每像素对应存放一个8位整数(0-255)
3.模板测试也是一个比较值的过程,将参考值和模板缓冲的值进行比较
当然也有很不同的地方:
1.即使模板测试不通过,仍然可以修改模板缓冲中的值
一.语法
1.Ref referenceValue
设置参考值,referenceValue(范围0-255)
2.ReadMask readMask
参考值和模板缓冲的值,会和readMask进行按位与(&)操作,readMask(范围0-255),默认值为255,即对读取值不作修改
3.WriteMask writeMask
当将值写入模板缓冲时,值会和writeMask进行按位与(&)操作,writeMask(范围0-255),默认值为255,即对写入值不作修改
4.Comp comparisonFunction
参考值和缓冲值要怎样比较,默认值为always,comparisonFunction可以取的值如下:
5.Pass stencilOperation
当模板测试和深度测试都通过时,模板缓冲的值要怎么处理,默认值为keep,stencilOperation可以取的值如下:
6.Fail stencilOperation
当模板测试不通过时,模板缓冲的值要怎么处理,默认值为keep
7.ZFail stencilOperation
当模板测试通过,深度测试不通过时,模板缓冲的值要怎么处理,默认值为keep
二.判断依据
if (参考值 & readMask comparisonFunction 缓冲值 & readMask) 像素通过
else 像素舍弃
因为readMask默认值为255,所以这时可以简化为:if (参考值 comparisonFunction 缓冲值)
三、案例
{
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
Stencil
{
Ref 2
Comp Greater
Pass replace
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return fixed4(1,0,0,1);
}
ENDCG
}
}
}
Shader "Unlit/Green"
{
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
Stencil
{
Ref 2
Comp GEqual
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return fixed4(0,1,0,1);
}
ENDCG
}
}
}
Shader "Unlit/Blue"
{
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
Stencil
{
Ref 1
Comp Greater
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return fixed4(0,0,1,1);;
}
ENDCG
}
}
}
效果如下:
需要注意的是,模板缓冲区默认模板值为0,可用下边一段模板测试代码测试得出。
Stencil
{
Ref 0
Comp Equal
}
当Ref参考值为0时,球体可被正常渲染,如图示:
当Ref参考值为1时,球体则不被渲染,如图示: