参考链接:
https://blog.csdn.net/u011047171/article/details/46928463
https://blog.csdn.net/JohnBlu/article/details/83539427
模板测试和深度测试很相似:
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 缓冲值)
三.实例(限制渲染区域,效果类似于Scroll View)
1.Stencil2.shader
1 Shader "Custom/Stencil2" 2 { 3 Properties 4 { 5 _MainTex ("Texture", 2D) = "white" {} 6 } 7 SubShader 8 { 9 Tags { "RenderType"="Opaque" "Queue"="Geometry" } 10 11 Pass 12 { 13 Stencil 14 { 15 Ref 1 16 Comp Equal 17 } 18 19 CGPROGRAM 20 #pragma vertex vert 21 #pragma fragment frag 22 23 #include "UnityCG.cginc" 24 25 struct appdata 26 { 27 float4 vertex : POSITION; 28 float2 uv : TEXCOORD0; 29 }; 30 31 struct v2f 32 { 33 float2 uv : TEXCOORD0; 34 float4 vertex : SV_POSITION; 35 }; 36 37 sampler2D _MainTex; 38 float4 _MainTex_ST; 39 40 v2f vert (appdata v) 41 { 42 v2f o; 43 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); 44 o.uv = TRANSFORM_TEX(v.uv, _MainTex); 45 return o; 46 } 47 48 fixed4 frag (v2f i) : SV_Target 49 { 50 fixed4 col = tex2D(_MainTex, i.uv); 51 return col; 52 } 53 ENDCG 54 } 55 } 56 }
这个shader的意思是:
Ref 1:将参考值设置为1
Comp Equal:if (参考值 == 缓冲值) 像素通过 else 像素舍弃
将这个shader赋给一个Capsule,会发现整个Capsule都不见了,说明模板测试没有通过。如果改为Ref 0,会发现Capsule又出来了,说明模板缓冲中的值默认是0。
2.Stencil.shader
1 Shader "Custom/Stencil" 2 { 3 Properties 4 { 5 } 6 SubShader 7 { 8 Tags { "RenderType"="Opaque" "Queue"="Geometry" } 9 10 Pass 11 { 12 ZWrite Off 13 ColorMask 0 14 15 Stencil 16 { 17 Ref 1 18 Comp Always 19 Pass Replace 20 } 21 22 CGPROGRAM 23 #pragma vertex vert 24 #pragma fragment frag 25 26 #include "UnityCG.cginc" 27 28 struct appdata 29 { 30 float4 vertex : POSITION; 31 }; 32 33 struct v2f 34 { 35 float4 vertex : SV_POSITION; 36 }; 37 38 v2f vert (appdata v) 39 { 40 v2f o; 41 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); 42 return o; 43 } 44 45 fixed4 frag (v2f i) : SV_Target 46 { 47 return fixed4(1, 1, 1, 1); 48 } 49 ENDCG 50 } 51 } 52 }
这个shader的意思是:
ColorMask 0:不输出颜色
ZWrite Off:关闭深度写入,防止后面的像素被剔除
Ref 1:设置参考值为1
Comp Always:模板测试始终通过
Pass Replace:将参考值赋值给缓冲值
将这个shader赋给一个Quad,即表示Quad所处区域的模板缓冲值刷新为1。又因为Capsule的参考值为1,因此,只有这两个物体重叠的部分才会有显示,效果如下: