關于Unity UI-Default Shader

之前寫功能對ui的default shader做了修改,然后遇到一些問題,記錄一下(代碼可以在下載unity自選的built-in shaders 里面找到)

如何去寫自定義shader

想要重寫unity的ui材質必須要包含一些固有的參數類型

1.模板緩沖的一堆參數,對unity的mask生效,(我覺得既然作為ui就要遵守ui的模板,不加沒有問題,但是我看到過使用自定義材質導致的奇怪的問題,都是不注意細節,比如z-Test默認是開啟的,等等)
 Properties
    {
        [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
        _Color ("Tint", Color) = (1,1,1,1)
        _StencilComp ("Stencil Comparison", Float) = 8
        _Stencil ("Stencil ID", Float) = 0
        _StencilOp ("Stencil Operation", Float) = 0
        _StencilWriteMask ("Stencil Write Mask", Float) = 255
        _StencilReadMask ("Stencil Read Mask", Float) = 255

        _ColorMask ("Color Mask", Float) = 15

        [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
    }

    SubShader
    {
        Tags
        {
            "Queue"="Transparent"
            "IgnoreProjector"="True"
            "RenderType"="Transparent"
            "PreviewType"="Plane"
            "CanUseSpriteAtlas"="True"
        }

        Stencil
        {
            Ref [_Stencil]
            Comp [_StencilComp]
            Pass [_StencilOp]
            ReadMask [_StencilReadMask]
            WriteMask [_StencilWriteMask]
        }

        Cull Off
        Lighting Off
        ZWrite Off
        ZTest [unity_GUIZTestMode]
        Blend SrcAlpha OneMinusSrcAlpha
        ColorMask [_ColorMask]

2.默認的shader會有兩個宏
      #pragma multi_compile __ UNITY_UI_CLIP_RECT
      #pragma multi_compile __ UNITY_UI_ALPHACLIP

目的是對unity的rect mask 2d 裁剪生效

     #ifdef UNITY_UI_CLIP_RECT
     color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
     #endif

     #ifdef UNITY_UI_ALPHACLIP
     clip (color.a - 0.001);
     #endif

實現原理其實很簡單

inline float UnityGet2DClipping (in float2 position, in float4 clipRect)
{
    // 判斷當前點是否在矩形中,返回inside.x * inside.y 如果有任意一點不在那么返回值為0
    float2 inside = step(clipRect.xy, position.xy) * step(position.xy, clipRect.zw);
    return inside.x * inside.y;
}

clip對gpu并行化處理影響比較大,所以一般都不勾上這個UNITY_UI_ALPHACLIP宏

所以看你的需求,如果需要rectMask2d的矩形裁剪 ,那么就加上,如果不需要,就刪掉,~宏我覺得是沒必要加上了,沒有必要為你重寫的這個shader增加3個變體,是吧

3.關于gpu instancing

你會發現默認的shader帶了兩個函數接口

       UNITY_SETUP_INSTANCE_ID(v);
       UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);

第一個就是我想解釋一下的gpu instancing,聽起來還蠻高大上的
GPU Instancing是指由GPU和圖形API支持的,用一個Draw Call同時繪制多個Geometry相同的物體的技術。
通過降低dc來降低gpu的開銷
第2個是給vr用的,3dxxxx 所以一般游戲也不需要

比較 dynamic batch和 gpu instancing 區別

降低dc的辦法嘛,各有

dynamic batch:

unity自己合并網格的一種方式,是合并頂點數,vertex buffer合并傳遞一個比較大的頂點數量來解決問題的(沒有法線uv的情況下應該支持900一下頂點數的object),cpu處做的優化,條件:mesh可以不同,但材質必須相同(同一份)。

gpu instancing:

是基于圖形api來實現的,傳遞相同的vertex buffer, mesh必須是相同的,但是一些(比如位置信息,旋轉,顏色等等)是可以通過property block傳遞給gpu去改變的
附上很不錯的教程鏈接供參考

沒有他寫得好 就不多廢話了 = =

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容