天天看點

unity3d:UI shader區域mask透明

1.原始圖

2.mask圖可分為24個區域,非編号區域為黑色

3.設定區域值 1<<區域1| 1 <<區域2 這種形式點亮需要的區域,這樣就點亮區域1,區域2

Shader "UI/MaskAreaAlpha" {
  Properties {
    _MainTex("Texture", 2D) = "white" {}
    _Mask("遮罩", 2D) = "white" {}
    _Area("區域",Int) = 0
    
    _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]
      }
      ColorMask[_ColorMask]

      Cull Off
      Lighting Off
      ZWrite Off
      Blend One OneMinusSrcAlpha

      Pass
      {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag

        #include "UnityCG.cginc"
        #include "UnityUI.cginc"
        #pragma multi_compile __ UNITY_UI_ALPHACLIP

        sampler2D _MainTex;
        sampler2D _Mask;
        int _Area; //區域值
        float4 _ClipRect;

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

        struct v2f
        {
          float2 uv : TEXCOORD0;
          float4 color : COLOR;
          float4 vertex : SV_POSITION;
          float4 worldPosition : TEXCOORD1;
        };

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


        int SetAlpha(fixed4 mask)
        {
          int t = (int)round(mask.r*255.0) << 16 | (int)round(mask.g*255.0) << 8 | (int)round(mask.b*255.0);
          int isAplha = step(1, _Area & t);
          return isAplha;
        }
        
        fixed4 frag(v2f i) : SV_Target
        {
          half4 col = tex2D(_MainTex, i.uv) * i.color;
          half4 mask = tex2D(_Mask,i.uv);
          int isAplha = SetAlpha(mask);
          col.a = col.a  * isAplha;
          
          col.a *= UnityGet2DClipping(i.worldPosition.xy, _ClipRect);  
#ifdef UNITY_UI_ALPHACLIP
          clip(col.a - 0.001);
#endif

          return col;
        }
        ENDCG
      }
  }
}      

示例

unity3d:UI shader區域mask透明

當區域值為1,隻與一個區域使能,行為是b是最低位,點亮了藍色區域

unity3d:UI shader區域mask透明

當區域值為16777215,相當于點亮了3個區域

unity3d:UI shader區域mask透明

繼續閱讀