Unity5.6如何使用StencilBuffer实现SpriteRenderer的Mask
什么是StencilBuffer
模板缓冲区(StencilBuffer)可以为屏幕上的每个像素点保存一个无符号整数值,在渲染的过程中,可以用这个值与一个预先设定的参考值相比较,根据比较的结果来决定是否更新相应的像素点的颜色值.这个比较的过程被称为模板测试.
主要过程为:将StencilBuffer的值与ReadMask与运算,然后与Ref值进行Comp比较,结果为true时进行Pass操作,否则进行Fail操作,操作值写入StencilBuffer前先与WriteMask与运算.
公式:(Ref & ReadMask) Comp (StencilBufferValue & ReadMask)
问题一:在未使用模板检测时,我们的屏幕到底默认的模板检测缓冲数值是多少?
我们用Unity来测试一下这个问题:
- 先准备两个shader
第一个Shader 叫RedShader 来自官方文档
Shader "Unlit/RedShader"
{
SubShader
{
//RenderType 为 Qpaque代表渲染的物体不透明
//Queue 为 Geometry 代表物体的渲染队列在不透明列队中
Tags {
"RenderType"="Opaque" "Queue"="Geometry"}
Pass
{
Stencil{
Ref 2 //将写入模板测试缓存区中的值
Comp always //比较方式 always代表不会进行Fail操作
Pass replace //通过后所进行的操作,replace代表向模板缓存区中写入引用的值
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
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 half4(1,0,0,1);//最终输出到屏幕的颜色为红色,
}
ENDCG
}
}
}
- 有了第一个Shader,我们看看窗口效果,我们可以看到红色的一片,下一图则是显示StencilBuffer理论上应该显示值
3.接着我们添加第二个Shader GreenShader,修改的只是模板测试的值,其余均没有变化,最终输出颜色变为绿色,可以做比较
Shader "Unlit/GreenShader"
{
SubShader
{
//RenderType 为 Qpaque代表渲染的物体不透明
//Queue 为 Geometry 代表物体的渲染队列在不透明列队中
Tags {
"RenderType"="Opaque" "Queue"="Geometry"}
Pass
{
Stencil{
Ref 2 //这里与RedShader值一样,用于与模板测试缓冲区的值做比较
Comp equal //equal 代表当前的Ref与模板测试缓冲区的值相等时通过模板测试
Pass keep //通过测试通过后