kidoOooOoooOOom

ゲーム開発やってます

UnityのUI-Default.shader 内のUNITY_UI_ALPHACLIP について

Unity 5.3 に含まれる UI-Default.shader でまだ理解できてなかったところを1つずつ消化していく。
UNITY_UI_ALPHACLIP関連について。

Properties
    {
        (省略)
        [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
    }
    SubShader
    {
 (省略)
        Pass
        {
        CGPROGRAM
            #pragma multi_compile __ UNITY_UI_ALPHACLIP
   (省略)

            fixed4 frag(v2f IN) : SV_Target
            {
                half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;

                color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);

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

                return color;
            }

いくつか省略。まず最初の Properitesで定義している

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

トグルでON/OFF できるproperty 。ONの場合は UNITY_UI_ALPHACLIP 変数に 1 が入る。
[Toggle] _UseUIAlphaClip と書いた場合は _USEUIALPHACLIP_ON 変数に1が入る挙動らしい。
Unity - Scripting API: MaterialPropertyDrawer

#pragma multi_compile __ UNITY_UI_ALPHACLIP

multi_compile についての Unity manual を見てもよく分からなかった。
Unity - マニュアル: 複数のシェーダープログラムのバリアントを作る

こちらのページが分かりやすい。
qiita.com
#ifdef で分岐する/しない パターンのことをシェーダーのバリアントとして実現している感じ。
__ が UNITY_UI_ALPHACLIP =0 のときのバリアント、UNITY_UI_ALPHACLIPがUNITY_UI_ALPHACLIP=1のときのバリアント。

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

fragment shader内のここで、UNITY_UI_ALPHACLIP=1の場合のバリアントで HLSLのclip()を実行している。
clipは渡された値が0未満だったらそのピクセルを破棄する処理。つまり、アルファが0.001未満だったら描画しない(完全に透明扱い)
clip (DirectX HLSL)