4.測(cè)試之模板測(cè)試

模板是啥?
模板就是模板,做鞋墊子的時(shí)候,需要用一個(gè)模子(鞋樣子)照著剪樣子。
著色中模板是怎么來(lái)的?
shader 內(nèi)自定義的,如果該shader內(nèi)寫了模板信息,那么該materail對(duì)應(yīng)的紋理或者說(shuō)Mesh上的各個(gè)像素點(diǎn),就組成了模板。

通俗的說(shuō)一下:
默認(rèn)是沒有模板信息的,當(dāng)

先介紹一下,Stencil的相關(guān)參數(shù)

Stencil
{
    Ref 1//Reference Value,程序自己設(shè)定的值,表示該像素(姑且這么說(shuō))的模板值
    ReadMask 255 //程序也可以設(shè)定,但是該值大部分時(shí)候采用默認(rèn)就好,默認(rèn)是255
    WriteMask 255 //同上
    Comp Always //Comparison Function //這個(gè)是重點(diǎn),模板最核心的代碼,用于決定是不是通過(guò)模板測(cè)試,如果不寫,默認(rèn)Always
    Pass Replace //通過(guò)了如何操作,默認(rèn)是Keep
    Fail Keep //未通過(guò)模板測(cè)試如何操作,默認(rèn)Keep
    ZFail Replace //模板測(cè)試通過(guò),深度沒有通過(guò),如何操作
}

先說(shuō)Ref
程序自己設(shè)定的參考值,或者說(shuō)給當(dāng)前操作的像素點(diǎn),設(shè)置的模板值,取0-255(使用的時(shí)候用二進(jìn)制,后面會(huì)說(shuō))
ReadMask
“An 8 bit mask as an 0–255 integer, used when comparing the reference value with the contents of the buffer (referenceValue & readMask) comparisonFunction (stencilBufferValue & readMask). Default: 255.”
這是官方解釋,其實(shí)直接使用默認(rèn)值就行,也就是不用寫該參數(shù)。具體的看后面的關(guān)鍵字解釋。
WriteMask
也采用默認(rèn)值255 就好。
Comp Operate
Compare顧名思義就是比較,模板值的比較,那么比較的前后值如何得來(lái)的呢,假設(shè)比較的左值為lv,右值為rv.
那么 lv = Ref&ReadMask, rv = stencilBufferValue&ReadMask
Ref是我們前面自己設(shè)定的,這幾個(gè)參數(shù)均采用二進(jìn)制樣式,\color{red}{ReadMask默認(rèn)255那么二進(jìn)制是11111111與任何Red進(jìn)行"與"操作,都會(huì)保留Ref值,所以ReadMask大部分時(shí)候用默認(rèn)值}
stencilBufferValue是現(xiàn)在緩沖區(qū)里面已經(jīng)存的,該像素位置的模板值。用自己的模板值與已存的進(jìn)行比較。
lv 與 rv比較,無(wú)非就是大于,小于,等于。。。

image.png

那么,通過(guò)測(cè)試的將如何操作,未通過(guò)如何操作,模板通過(guò)深度未通過(guò),如何操作呢?
就是剩下的三個(gè)字段,后面跟著的操作。


image.png

做個(gè)Demo:


image.png

如圖所示,前中后三個(gè)圖片,中間的擋住 了后面的,我們想要的效果是通過(guò)前面的圖片區(qū)域能夠看到后面那個(gè)斧頭,最終效果如下:


image.png

三個(gè)圖片分別對(duì)應(yīng)了三個(gè)模板測(cè)試,先說(shuō)front的模板測(cè)試代碼

            stencil
            {
                Ref 2
                Comp Always
                Pass Replace
            }

Mid的模板測(cè)試代碼

            stencil
            {
                Ref 2
                Comp NotEqual
                Pass Replace
            }

Back的模板測(cè)試代碼

            stencil
            {
                Ref 2
                Comp Always
                Pass Replace
            }

ok,現(xiàn)在開始分析,整個(gè)渲染過(guò)程
第一步,渲染順序:front->mid->back,這是因?yàn)椴煌该魑矬w,從前往后渲染,被遮擋的可以不用計(jì)算。


image.png

假定,分辨率是10*10
front的rect 是(4,4,2,2)
mid的rect 是(3,4,4,4)
back的rect是(4,4,2,2)
那么在渲染front之前,整個(gè)模板圖如下:


image.png

每個(gè)像素的模板值是255
,現(xiàn)在先進(jìn)行front的模板測(cè)試,結(jié)果如下
image.png

front設(shè)定的Ref是2,同時(shí)Comp參數(shù)為Always永遠(yuǎn)通過(guò)并會(huì)寫入StencilBuff內(nèi)。

現(xiàn)在對(duì)mid進(jìn)行深度測(cè)試,結(jié)果如下:


image.png

中間四個(gè)黃色的像素,是mid 沒有通過(guò)模板測(cè)試,mid的Comp 是NotEqual,所以Mid測(cè)試通過(guò)的像素點(diǎn)是左側(cè)的兩個(gè)紅色,右側(cè)的兩個(gè)紅色,中間四個(gè)黃色,mid的被剔除了,目前該像素點(diǎn)上緩存的顏色值是front的。

現(xiàn)在對(duì)back進(jìn)行模板測(cè)試,結(jié)果如下:

image.png

中間四個(gè)像素點(diǎn),back測(cè)試通過(guò)?,F(xiàn)在中間四個(gè)黃色像素點(diǎn)的顏色值緩存的仍然是 front的。

附上,front的著色器:

Shader "Stencil/stencil_front"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100
        //關(guān)閉深度寫入,是因?yàn)榉乐筬ront 遮擋了 back的像素點(diǎn)
        ZWrite Off
        Pass
        {
            stencil
            {
                Ref 2
                Comp Always
                Pass Replace
            }


            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

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

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容