Unity基础--ShaderLab:Stencil

本文深入探讨了模板缓存(stencilbuffer)的概念及其在像素着色前作为掩码的作用。详细解析了其语法结构,包括Ref、ReadMask、WriteMask、Comp、Pass、Fail和ZFail等功能,并通过三个具体示例展示了如何在着色器中应用模板缓存,实现像素级的精细控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

模板缓存(stencil buffer)

模板缓存通常作为用来作为每个像素的掩码来觉得是否丢弃该像素的数据。
模板缓冲区通常是每像素8位整数。该值可以被写入、递增或递减。随后的绘制调用可以根据该值进行测试,以确定在运行像素着色器之前是否应该丢弃像素。

语法

  • Ref
    Ref referenceValue:要比较的值和/或者要写入缓冲区的值。

  • ReadMask
    ReadMask readMask:8bit 的掩码范围是0-255的整形。用于将参考值与缓冲区的内容进行比较 (referenceValue & readMask) comparisonFunction (stencilBufferValue & readMask)。默认255。

  • WriteMask
    WriteMask writeMask:作为0-255整数的8位掩码,在写入缓冲区时使用。注意,与其他写掩码一样,它指定哪些模板缓冲区位将受到写的影响(即WriteMask 0表示没有位受到影响,也不会写入0)。默认值:255。

  • Comp
    Comp comparisonFunction:用于将参考值与缓冲区的当前内容进行比较的函数。默认值:always。

  • Pass
    Pass stencilOperation:如果模板测试(和深度测试)通过,该如何处理缓冲区的内容。默认值:keep。

  • Fail
    == Fail stencilOperation==:如果模板测试失败,该如何处理缓冲区的内容。默认值:keep。

  • ZFail
    ZFail stencilOperation:如果模板测试通过,但深度测试失败,该如何处理缓冲区的内容。默认值:keep。

Comp、Pass、Fail和ZFail将应用于几何图形的front-face。如果Cull Front指定了,则是几何图形的back-face。您还可以通过定义CompFront、PassFront、FailFront、ZFailFront(用于前面的几何图形)和CompBack、PassBack、FailBack、ZFailBack(用于后面的几何图形)来显式指定双面模具状态。

例子

第一个示例着色器将在深度测试通过的地方写入值“2”。模板测试设置为总是通过

Shader "Red" {
    SubShader {
        Tags { "RenderType"="Opaque" "Queue"="Geometry"}
        Pass {
            Stencil {
                Ref 2
                Comp always
                Pass replace
            }
        
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            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,0,0,1);
            }
            ENDCG
        }
    } 
}

第二个着色器将只传递第一个(红色)着色器传递的像素,因为它正在检查与值“2”是否相等。它还将在缓冲区中任何Z测试失败的地方递减该值。

Shader "Green" {
    SubShader {
        Tags { "RenderType"="Opaque" "Queue"="Geometry+1"}
        Pass {
            Stencil {
                Ref 2
                Comp equal
                Pass keep 
                ZFail decrWrap
            }
        
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            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(0,1,0,1);
            }
            ENDCG
        }
    } 
}

第三个着色器只会在模板值为“1”的地方传递,所以只有红色和绿色球体交点的像素—也就是说,模板被红色着色器设置为“2”,被绿色着色器减少为“1”

Shader "Blue" {
    SubShader {
        Tags { "RenderType"="Opaque" "Queue"="Geometry+2"}
        Pass {
            Stencil {
                Ref 1
                Comp equal
            }
        
            CGPROGRAM
            #include "UnityCG.cginc"
            #pragma vertex vert
            #pragma fragment frag
            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(0,0,1,1);
            }
            ENDCG
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值