【问题标题】:Unity Shader: Overlapping two Layers with the same stencil valueUnity Shader:重叠两个具有相同模板值的图层
【发布时间】:2017-04-01 00:27:38
【问题描述】:

我正在尝试为统一编写一个着色器,它将删除底层对象的所有重叠片段。我为这个问题找到了不同的解决方案,这真的很有帮助。

对我来说,这个链接 (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

你能帮我解决这个问题,而不是在透明盒子上开一个洞吗?穿透选项有问题,如果我有圆形图像,其中有一些透明像素,背景会非常明亮。

非常感谢您的帮助。

【问题讨论】:

    标签: user-interface shader unity5 shaderlab


    【解决方案1】:

    最后我自己解决了这个问题。对于那些有同样问题的人,这里是解决方案。 我创建了两个不同的着色器。我为背景创建了一个,为背景前面的图片创建了一个。

    以下代码用于后台:

        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
            }
        }
    }
    

    现在的层次结构是:背景在底部,然后是文本和图像上方。

    说实话,我不确定它为什么会起作用,我知道这不是最好的答案,但我希望我可以帮助所有遇到相同或几乎相同问题的人。

    【讨论】:

      猜你喜欢
      • 2016-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-12
      • 1970-01-01
      相关资源
      最近更新 更多