[UnityShader基础]05.模板测试

参考链接:

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,因此,只有这两个物体重叠的部分才会有显示,效果如下:

原文地址:https://www.cnblogs.com/lyh916/p/10555963.html