91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Unity中Shader的示例分析

發布時間:2022-01-05 14:42:39 來源:億速云 閱讀:155 作者:小新 欄目:大數據

這篇文章給大家分享的是有關Unity中Shader的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

模板測試概要

言歸正傳,stencil與顏色緩沖區和深度緩沖區類似,模板緩沖區可以為屏幕上的每個像素點保存一個無符號整數值(通常的話是個8位整數)。這個值的具體意義視程序的具體應用而定。在渲染的過程中,可以用這個值與一個預先設定的參考值相比較,根據比較的結果來決定是否更新相應的像素點的顏色值。這個比較的過程被稱為模板測試。模板測試發生在透明度測試(alpha test)之后,深度測試(depth test)之前。如果模板測試通過,則相應的像素點更新,否則不更新。圖形渲染管線中,基于單個像素的測試操作的順序如下圖

Unity中Shader的示例分析

模板測試語法

一般來說,stencil完整語法格式如下:

stencil{  
    Ref referenceValue  
    ReadMask  readMask  
    WriteMask writeMask  
    Comp comparisonFunction  
    Pass stencilOperation  
    Fail stencilOperation  
    ZFail stencilOperation  
}

Ref

Ref referenceValue

Ref用來設定參考值referenceValue,這個值將用來與模板緩沖中的值進行比較。referenceValue是一個取值范圍位0-255的整數。

ReadMask

ReadMask  readMask

ReadMask 從字面意思的理解就是讀遮罩,readMask將和referenceValue以及stencilBufferValue進行按位與(&)操作,readMask取值范圍也是0-255的整數,默認值為255,二進制位11111111,即讀取的時候不對referenceValue和stencilBufferValue產生效果,讀取的還是原始值。

WriteMask

WriteMask writeMask

WriteMask是當寫入模板緩沖時進行掩碼操作(按位與【&】),writeMask取值范圍是0-255的整數,默認值也是255,即當修改stencilBufferValue值時,寫入的仍然是原始值。

Comp

Comp comparisonFunction

Comp是定義參考值(referenceValue)與緩沖值(stencilBufferValue)比較的操作函數,默認值:always

Pass

 Pass stencilOperation  

Pass是定義當模板測試(和深度測試)通過時,則根據(stencilOperation值)對模板緩沖值(stencilBufferValue)進行處理,默認值:keep

Fail

 Fail stencilOperation  

Fail是定義當模板測試(和深度測試)失敗時,則根據(stencilOperation值)對模板緩沖值(stencilBufferValue)進行處理,默認值:keep

ZFail

ZFail是定義當模板測試通過而深度測試失敗時,則根據(stencilOperation值)對模板緩沖值(stencilBufferValue)進行處理,默認值:keep

Comp,Pass,Fail 和ZFail將會應用給背面消隱的幾何體(只渲染前面的幾何體),除非Cull Front被指定,在這種情況下就是正面消隱的幾何體(只渲染背面的幾何體)。你也可以精確的指定雙面的模板狀態通過定義CompFront,PassFront,FailFront,ZFailFront(當模型為front-facing geometry使用)和ComBack,PassBack,FailBack,ZFailBack(當模型為back-facing geometry使用)

模板測試判斷依據

和深度測試一樣,在unity中,每個像素的模板測試也有它自己一套獨立的依據,具體公式如下:

if(referenceValue&readMask comparisonFunction stencilBufferValue&readMask)

通過像素

else

拋棄像素

在這個公式中,主要分comparisonFunction的左邊部分和右邊部分

referenceValue是有Ref來定義的,這個是由程序員來定義的,readMask是模板值讀取掩碼,它和referenceValue進行按位與(&)操作作為公式左邊的結果,默認值為255,即按位與(&)的結果就是referenceValue本身。

stencilBufferValue是對應位置當前模板緩沖區的值,同樣與readMask做按位掩碼與操作,結果做為右邊的部分。

comparisonFunction比較操作通過Comp命令定義,公式左右兩邊的結果將通過它進行判斷,其取值及其意義如下面列表所示。

  
Greater

相當于“>”操作,即僅當左邊>右邊,模板測試通過,渲染像素

GEqual

相當于“>=”操作,即僅當左邊>=右邊,模板測試通過,渲染像素

Less

相當于“<”操作,即僅當左邊<右邊,模板測試通過,渲染像素

LEqual

 

相當于“<=”操作,即僅當左邊<=右邊,模板測試通過,渲染像素

Equal

 

相當于“=”操作,即僅當左邊=右邊,模板測試通過,渲染像素

NotEqual

 

相當于“!=”操作,即僅當左邊!=右邊,模板測試通過,渲染像素

Always不管公式兩邊為何值,模板測試總是通過,渲染像素
Never不敢公式兩邊為何值,模板測試總是失敗 ,像素被拋棄

模板緩沖值的更新

在上一步的模板測試之后,無論模板測試通過與否,都要對模板進行相應的更新。具體到怎么更新,則由程序員自己定義。上面關于模板緩沖語法中,Pass,Fail,ZFail等命令就是根據不同判斷條件對模板緩沖區的值(stencilBufferValue)進行更新的操作,這些命令取值(stencilOperation)的類型及意義如下面列表所示:

  
Keep保留當前緩沖中的內容,即stencilBufferValue不變。
Zero將0寫入緩沖,即stencilBufferValue值變為0。
Replace將參考值寫入緩沖,即將referenceValue賦值給stencilBufferValue。
IncrSatstencilBufferValue加1,如果stencilBufferValue超過255了,那么保留為255,即不大于255。
DecrSatstencilBufferValue減1,如果stencilBufferValue超過為0,那么保留為0,即不小于0。
Invert將當前模板緩沖值(stencilBufferValue)按位取反
IncrWrap當前緩沖的值加1,如果緩沖值超過255了,那么變成0,(然后繼續自增)。
DecrWrap當前緩沖的值減1,如果緩沖值已經為0,那么變成255,(然后繼續自減)  。

在更新模板緩沖值的時候,也有writeMask進行掩碼操作,用來對特定的位進行寫入和屏蔽,默認值為255(11111111),即所有位數全部寫入,不進行屏蔽操作。

舉個如下的例子:

stencil{  
    Ref 2  
    Comp always  
    Pass replace  
}

在上面的代碼中,第一行Ref 2這行將referenceValue定義為2;

第二行中,Comp命令后的參數是always,此時我們不管stencilBufferValue為多少,模板測試都是成功通過的;

而第三行中,Pass replace的意思是,當模板測試通過則將referenceValue替換給stencilBufferValue,此時

stencilBufferValue值為2,因此上面的例子功能相當于將stencilBufferValue刷新為2;

小結

上面說了這么多,主要的重點如下

  • 使用模板緩沖區最重要的兩個值:當前模板緩沖值(stencilBufferValue)和模板參考值(referenceValue)

  • 模板測試主要就是對這個兩個值使用特定的比較操作:Never,Always,Less ,LEqual,Greater,Equal等等。

  • 模板測試之后要對模板緩沖區的值(stencilBufferValue)進行更新操作,更新操作包括:Keep,Zero,Replace,IncrSat,DecrSat,Invert等等。

  • 模板測試之后可以根據結果對模板緩沖區做不同的更新操作,比如模板測試成功操作Pass,模板測試失敗操作Fail,深度測試失敗操作ZFail,還有正對正面和背面精確更新操作PassBack,PassFront,FailBack等等。

實例操作

上面主要是理論知識,下面將通過一個實例大概了解下stencil的簡單應用,使用stencil緩沖用來限制渲染區域,效果如下:

Unity中Shader的示例分析

這個實例需要兩個shader實現,如上面的那個用來限制區域的box所使用的shader中的關鍵代碼:

ColorMask 0  
ZWrite Off  
Stencil{  
    Ref 1  
    Comp Always  
    Pass Replace  
}

上面這段代碼中,ColorMask 0作用是屏蔽顏色的輸出,即不輸出顏色到屏幕。ZWrite Off用來關閉深度寫入,防止深度測試中后面的角色的像素被剔除掉;在stencil中 Ref 1將referenceValue設置成1,Comp Always 保證模板測試始終通過,Pass Replace 操作則將stencilBufferValue刷新為1;即這段代碼的功能是在屏幕上對應模型的位置不輸入任何顏色,而將對應位置的模板緩沖值刷新為1;

接下來需要在角色使用的shader中添加如下關鍵代碼:

Stencil {  
      Ref 1  
      Comp Equal  
}

,

上面這段代碼中,Ref 1將referenceValue設置成1,在接下來的一行代碼中,Comp Equal的意思是,如果referenceValue=stencilBufferValue,則模板測試通過,渲染像素,否則拋棄;在這個例子中,由于屏幕中的像素默認的模板值(stencilBufferValue)為0(我猜的,貌似是正確的哈)而參考值referenceValue為1,,所以正常情況下使用這個shader的模型是不顯示的,但是在使用了第一個shader的box區域,由于stencilBufferValue被刷新為1,所以在這個區域中,角色是能夠顯示的。

本例完整代碼如下:

Shader "Custom/UnlitStencilMaskVF" {  
    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 = mul(UNITY_MATRIX_MVP, 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  
        }  
        
          
    }   
}
Shader "Custom/UnlitStencilVF" {  
    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  
            #pragma multi_compile_fog  
             
            #include "UnityCG.cginc"  
  
            struct appdata_t {  
                float4 vertex : POSITION;  
                float2 texcoord : TEXCOORD0;  
                  
            };  
  
            struct v2f {  
                float4 vertex : SV_POSITION;  
                half2 texcoord : TEXCOORD0;  
              
                UNITY_FOG_COORDS(1)  
            };  
  
            sampler2D _MainTex;  
            float4 _MainTex_ST;  
              
            v2f vert (appdata_t v)  
            {  
                v2f o;  
                o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);  
                o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);  
                                UNITY_TRANSFER_FOG(o,o.vertex);  
                return o;  
            }  
              
            fixed4 frag (v2f i) : SV_Target  
            {  
                fixed4 col = tex2D(_MainTex, i.texcoord);  
                UNITY_APPLY_FOG(i.fogCoord, col);  
                UNITY_OPAQUE_ALPHA(col.a);  
              
                return col;  
            }  
        ENDCG  
    }  
}  
  
}

感謝各位的閱讀!關于“Unity中Shader的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

西吉县| 井研县| 和田市| 平塘县| 湄潭县| 九寨沟县| 岳阳市| 微山县| 乌拉特中旗| 张家口市| 玉林市| 太仓市| 陵川县| 临洮县| 新宁县| 阜平县| 佛山市| 大荔县| 包头市| 钦州市| 从化市| 工布江达县| 汝南县| 荣成市| 鄂托克前旗| 漯河市| 许昌县| 隆安县| 黄平县| 紫金县| 连江县| 康平县| 昌吉市| 卫辉市| 呼和浩特市| 靖宇县| 古蔺县| 吴江市| 酒泉市| 广丰县| 富民县|