模板测试
参考网址: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,和模板缓冲中的值进行比较,如果相等,则进行绘制,否则丢弃像素。