2016-11-17 70 views
0

我正在嘗試編寫一個用於統一的着色器,它將刪除底層對象的所有重疊片段。我發現針對這個問題的不同解決方案非常有用。Unity Shader:用相同的模板值重疊兩個圖層

對我來說,這個鏈接(Unity shader highlighting overlaps)是最有用的一個。

但現在我有另一個問題。在圖片中,您可以看到6個通常具有相同大小和透明背景的按鈕。如果其中一個按鈕被選中,則它與其鄰居重疊。

下圖顯示了自定義着色器的外觀。我已經通過在背景中挖一個洞來顯示圖像來解決問題,但現在我想向這些按鈕添加文本;如果我再次做同樣的事情,那麼文字看起來會很尷尬。

Menubutton correct

下面的代碼演示瞭如何通過切割孔進入透明箱解決我的問題:

Shader "Custom/GUI/Mask" { 
    Properties 
    { 
     _Color("Color (white = none)", COLOR) = (1,1,1,1) 
     _MainTex("Texture", 2D) = "white" {} 
     _CutOff("Cut off", Range(-0.001,1)) = 0.1 
    } 
    SubShader 
    { 
     Tags{ "RenderType" = "Transparent" "Queue" = "Geometry" } 
     LOD 100 

     Blend SrcAlpha OneMinusSrcAlpha 
     ZWrite off 

     Pass 
     { 
      Stencil 
      { 
       Ref 0 
       Comp Equal 
       Pass IncrSat 
       Fail IncrSat 
      } 

      CGPROGRAM 
       #pragma vertex vert 
       #pragma fragment frag 

       #include "UnityCG.cginc" 

       uniform sampler2D _MainTex; 
       uniform float4 _MainTex_ST; 
       float4 _Color; 
       float _CutOff; 

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

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

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

       fixed4 frag(v2f i) : SV_Target 
       { 
        float4 color = tex2D(_MainTex, i.uv); 

        color.rgb *= _Color.rgb; 
        color.a *= _Color.a; 

        if (color.a <= _CutOff) 
        { 
         discard; 
        } 
        return color; 
       } 
      ENDCG 
     } 

     Pass 
     { 
      Blend SrcAlpha OneMinusSrcAlpha 
      ZWrite off 

      Stencil 
      { 
       Ref 1 
       Comp Less 
      } 

      CGPROGRAM 
       #pragma vertex vert 
       #pragma fragment frag 

       #include "UnityCG.cginc" 

       float4 _Color; 
       uniform sampler2D _MainTex; 

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

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

       v2f vert(appdata v) 
       { 
        v2f o; 
        o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); 
        o.uv = v.uv; 
        return o; 
       } 

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

     Pass 
     { 
      Blend SrcAlpha OneMinusSrcAlpha 

      Stencil 
      { 
       Ref 2 
       Comp Less 
      } 

      CGPROGRAM 
       #pragma vertex vert 
       #pragma fragment frag 

       #include "UnityCG.cginc" 

       uniform sampler2D _MainTex; 
       float4 _Color; 

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

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

       v2f vert(appdata v) 
       { 
        v2f o; 
        o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); 
        o.uv = v.uv; 
        return o; 
       } 

       fixed4 frag(v2f i) : SV_Target 
       { 
        fixed4 color = tex2D(_MainTex, i.uv); 
        color.a = 0; 
        return color; 
       } 

      ENDCG 
     } 
    } 
} 

此圖爲,它會是什麼樣子沒有自定義着色器從而消除重疊的部分。在這幅圖中,您還可以看到,透明背景的模板值通常爲0,當它重疊時,值將更改爲1.問題是背景上的圖像也具有1的模板值。因此,如果我將刪除模具值爲1的所有對象,我會刪除透明背景上的所有圖像。順便說一下,圖像和背景包含相同的着色器。

Current view

能否請你幫不切割孔進入透明箱我解決這個問題?切入選項有問題,如果我有圓形圖像,其中有一些透明的像素,背景照耀非常明亮。

非常感謝您的幫助。

回答

0

最後我自己解決了這個問題。對於那些有同樣問題的人,這裏是解決方案。 我創建了兩個不同的着色器。我爲背景創建了一個,並在背景前創建了一個。

以下代碼是用於背景:

Shader "Custom/GUI/Background" { 
    Properties 
    { 
     _Color("Color (white = none)", COLOR) = (1,1,1,1) 
     _MainTex("Texture", 2D) = "white" {} 
     _CutOff("Cut off", Range(-0.001,1)) = 0.1 
    } 
    SubShader 
    { 
     Tags{ "RenderType" = "Transparent" "Queue" = "Geometry-100" "LightMode" = "ForwardBase" } 
     LOD 100 

     Blend SrcAlpha OneMinusSrcAlpha 
     ZWrite off 

     Pass 
     { 
      Stencil 
      { 
       Ref 0 
       Comp Equal 
       Pass IncrSat 
       Fail IncrSat 
      } 

      CGPROGRAM 
       #pragma vertex vert 
       #pragma fragment frag 

       #include "UnityCG.cginc" 

       uniform sampler2D _MainTex; 
       uniform float4 _MainTex_ST; 
       float4 _Color; 
       float _CutOff; 

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

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

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

       fixed4 frag(v2f i) : SV_Target 
       { 
        float4 color = tex2D(_MainTex, i.uv); 

        color.rgb *= _Color.rgb; 
        color.a *= _Color.a; 

        return color; 
       } 
      ENDCG 
     } 
    } 
} 

這一個用於圖像:

Shader "Custom/GUI/ImageShader" 
    { 
    Properties 
    { 
     _MainTex("Texture", 2D) = "white" {} 
     _Color("Color (white = none)", COLOR) = (1,1,1,1) 
    } 
    SubShader 
    { 
     Tags { "RenderType" = "Transparent" } 
     LOD 100 

      Blend SrcAlpha OneMinusSrcAlpha 
      ZWrite off 

     Pass 
     { 
      Stencil 
      { 
       Ref 0 
       Comp Equal 
       Pass IncrSat 
       Fail IncrSat 
      } 

     } 

     // picture layer 
     Pass 
     { 
      Stencil 
      { 
       Ref 2 
       Comp Equal 
      } 

      CGPROGRAM 
       #pragma vertex vert 
       #pragma fragment frag 
       // make fog work 
       #pragma multi_compile_fog 

       #include "UnityCG.cginc" 

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

       struct v2f 
       { 
        float2 uv : TEXCOORD0; 
        UNITY_FOG_COORDS(1) 
        float4 vertex : SV_POSITION; 
       }; 

       sampler2D _MainTex; 
       float4 _MainTex_ST; 
       float4 _Color; 

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

       fixed4 frag(v2f i) : SV_Target 
       { 
        // sample the texture 
        fixed4 col = tex2D(_MainTex, i.uv); 
        col.rgb *= _Color.rgb; 
        col.a *= _Color.a; 
        // apply fog 
        UNITY_APPLY_FOG(i.fogCoord, col); 
        return col; 
       } 
      ENDCG 
     } 
    } 
} 

的層次現在爲:背景是在底部,然後文本和上述圖片。

說實話,我不確定它爲什麼在工作,我知道這不是最好的答案,但我希望我能幫助所有的人,他們有相同或幾乎相同的問題。