模板测试

参考网址:https://blog.****.net/u011047171/article/details/46928463模板测试
模板测试发生的时机:
在透明测试之后,深度测试之前。

项目代码:
https://gitee.com/yichichunshui/StencilTest.git

效果图展示:

模板测试

原理如下:
Mask的遮罩shader如下:

Shader "Custom/Mask"
{

	SubShader
	{
		Tags{"RenderType" = "Opaque" "Queue" = "Geometry-1"}
		CGINCLUDE
			struct appdata
			{
				float4 vertex:POSITION;
			};

			struct v2f
			{
				float4 pos:SV_POSITION;
			};

			v2f vert(appdata v)
			{
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				return o;
			}

			half4 frag(v2f i) :SV_Target
			{
				return half4(1,1,0,1);
			}

			ENDCG

			Pass
			{
				ColorMask 0
				ZWrite Off
				Stencil
				{
					Ref 1
					Comp Always
					Pass Replace
				}

				CGPROGRAM
				#pragma vertex vert
				#pragma fragment frag
				ENDCG
			}
	}
}

其渲染队列为Geometry-1,先渲染。将模板缓冲中的值刷为1。
人物的shader代码如下:

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/Role"
{
	Properties
	{
		_MainTex("Base (RGB)", 2D) = "white"{}
	}

	SubShader
	{
		Tags{"Queue"="Geometry" "RenderType"="Opaque"}
		LOD 100
		Pass
		{
			Stencil
			{
				Ref 1
				Comp Equal
			}
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"

			struct appdata_t
			{
				float4 vertex : POSITION;
				float2 texcoord : TEXCOORD0;
			};

			struct v2f
			{
				float4 vertex : SV_POSITION;
				half2 texcoord : TEXCOORD0;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;

			v2f vert(appdata_t v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
				return o;
			}

			fixed4 frag(v2f i) :SV_Target
			{
				fixed4 col = tex2D(_MainTex, i.texcoord);
				return col;
			}
			ENDCG
		}
	}
}

人物的渲染队列为Geometry,后渲染。其shader中的模板测试函数是只有当模板值等于1,并且比较函数是equal,也就是只有当参考值和模板缓冲中的值都等于1的时候,才进行渲染。
ok,当mask渲染之后,其对应区域的模板值都更新为1,而当渲染人物的时候,看看当前像素对应的模板值为1,和模板缓冲中的值进行比较,如果相等,则进行绘制,否则丢弃像素。