Unity Shader 模板测试

模板测试和深度测试很相似:

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 缓冲值)

三、案例


{
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100
        Pass
        {
            Stencil
            {
                Ref 2
                Comp Greater
                Pass replace
            }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            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 fixed4(1,0,0,1);
            }
            ENDCG
        }
    }
}

Shader "Unlit/Green"
{
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100
        Pass
        {
            Stencil
            {
                Ref 2
                Comp GEqual
            }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            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 fixed4(0,1,0,1);
            }
            ENDCG
        }
    }
}

Shader "Unlit/Blue"
{
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100
        Pass
        {
            Stencil 
            {
                Ref 1
                Comp Greater
            }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            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 fixed4(0,0,1,1);;
            }
            ENDCG
        }
    }
}

效果如下:

需要注意的是,模板缓冲区默认模板值为0,可用下边一段模板测试代码测试得出。

            Stencil
            {
                Ref 0
                Comp Equal
            }

当Ref参考值为0时,球体可被正常渲染,如图示:

当Ref参考值为1时,球体则不被渲染,如图示:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一零壹0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值