mob-sakai / SoftMaskForUGUI

Enhance Unity UI (uGUI) with advanced soft-masking features to create more visually appealing effects!
https://github.com/mob-sakai/SoftMaskForUGUI
MIT License
1.91k stars 257 forks source link

[v1] Soft mask with custom shader not working on Android #167

Closed angelsalascalvo closed 13 hours ago

angelsalascalvo commented 4 weeks ago

Describe the bug I have created a custom shader capable of overlay a sprite on an image, this shader is working perfectly in both the editor and Android. However when I created a duplicate of this to work with softmask (following these steps) in the android compilation does not work... It shows me the typical pink box.

It is possible that the error is due to the fact that the shader adaptation process for softmask was not carried out correctly but I was unable to discover the origin. Thanks

Screenshots screen

To Reproduce These are the 2 corresponding shaders

Original (works on android)

Shader "Custom/UIOverlay"
{
    Properties
    {
        _OverlayTex("Overlay Texture", 2D) = "white" {}
        _OverlayColor("Overlay Color", Color) = (1,1,1,1) 
        _Scale("Overlay Scale", Float) = 1
        _XSpeed("Overlay Horizontal Speed", Float) = 1
        _VSpeed("Overlay Vertical Speed", Float) = 1
        _FillColor("Fill Color", Color) = (0,0,0,0)

        [HideInInspector] _RendererColor("RendererColor", Color) = (1,1,1,1)
        [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
        [HideInInspector][PerRendererData] _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]

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 2.0

            #include "UnityCG.cginc"
            #include "UnityUI.cginc"

            #ifdef UNITY_INSTANCING_ENABLED
                UNITY_INSTANCING_BUFFER_START(PerDrawImage)
                UNITY_DEFINE_INSTANCED_PROP(fixed4, unity_ImageRendererColorArray)
                UNITY_INSTANCING_BUFFER_END(PerDrawImage)

                #define _RendererColor  UNITY_ACCESS_INSTANCED_PROP(PerDrawImage, unity_ImageRendererColorArray)
            #endif

            CBUFFER_START(UnityPerDrawImage)

            #ifndef UNITY_INSTANCING_ENABLED
                fixed4 _RendererColor;
            #endif

            CBUFFER_END

            #pragma multi_compile_local _ UNITY_UI_CLIP_RECT
            #pragma multi_compile_local _ UNITY_UI_ALPHACLIP

            struct appdata_t
            {
                float4 vertex   : POSITION;
                float4 color    : COLOR;
                float2 texcoord : TEXCOORD0;
                float4 screenPos : TEXCOORD1;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct v2f
            {
                float4 vertex   : SV_POSITION;
                fixed4 color    : COLOR;
                float2 texcoord  : TEXCOORD0;
                float4 screenPos : TEXCOORD1;
                UNITY_VERTEX_OUTPUT_STEREO
            };

            sampler2D _MainTex;
            fixed4 _Color;
            fixed4 _TextureSampleAdd;
            float4 _ClipRect;
            float4 _MainTex_ST;

            v2f vert(appdata_t IN)
            {
                v2f OUT;

                UNITY_SETUP_INSTANCE_ID(IN);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);

                OUT.vertex = UnityObjectToClipPos(IN.vertex);
                OUT.texcoord = IN.texcoord;
                OUT.screenPos = ComputeScreenPos(OUT.vertex);
                OUT.color = IN.color * _Color * _RendererColor;
                                return OUT;
            }

            sampler2D _OverlayTex;
            sampler2D _AlphaTex;
            float _VSpeed;
            float _XSpeed;
            fixed4 _OverlayColor;
            fixed4 _FillColor;
            float _Scale;

            fixed4 SampleSpriteTexture(float2 uv)
            {
                fixed4 color = tex2D(_MainTex, uv);

                #if ETC1_EXTERNAL_ALPHA
                    fixed4 alpha = tex2D(_AlphaTex, uv);
                    color.a = lerp(color.a, alpha.r, _EnableExternalAlpha);
                #endif

                return color;
            }

            fixed4 frag(v2f IN) : SV_Target
            {

                fixed4 c = SampleSpriteTexture(IN.texcoord) * IN.color;
                                float2 textureCoordinate;

                textureCoordinate = IN.screenPos.xy / IN.screenPos.w;
                float aspect = _ScreenParams.x / _ScreenParams.y; 
                textureCoordinate.x = textureCoordinate.x * aspect;

                fixed4 fx = tex2D(_OverlayTex, _Scale*textureCoordinate+float2(_Time.x* _XSpeed,_Time.x* _VSpeed));
                c.rgb *= c.a;

                fx = lerp(_OverlayColor, _FillColor,fx.r);
                c.rgb = lerp(fx.rgb,c.rgb,1-fx.a)*c.a;

                return c;
            }
        ENDCG
        }
    }
}

Modification for softmak (Does not work on android)

Shader "Hidden/Custom/UIOverlay (SoftMaskable)"
{
    Properties
    {
        _OverlayTex("Overlay Texture", 2D) = "white" {}
        _OverlayColor("Overlay Color", Color) = (1,1,1,1) 
        _Scale("Overlay Scale", Float) = 1
        _XSpeed("Overlay Horizontal Speed", Float) = 1
        _VSpeed("Overlay Vertical Speed", Float) = 1
        _FillColor("Fill Color", Color) = (0,0,0,0)

        [HideInInspector] _RendererColor("RendererColor", Color) = (1,1,1,1)
        [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
        [HideInInspector][PerRendererData] _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]

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 2.0

            #include "UnityCG.cginc"
            #include "UnityUI.cginc"

            #ifdef UNITY_INSTANCING_ENABLED
                UNITY_INSTANCING_BUFFER_START(PerDrawImage)
                UNITY_DEFINE_INSTANCED_PROP(fixed4, unity_ImageRendererColorArray)
                UNITY_INSTANCING_BUFFER_END(PerDrawImage)

                #define _RendererColor  UNITY_ACCESS_INSTANCED_PROP(PerDrawImage, unity_ImageRendererColorArray)
            #endif

            CBUFFER_START(UnityPerDrawImage)

            #ifndef UNITY_INSTANCING_ENABLED
                fixed4 _RendererColor;
            #endif

            CBUFFER_END

            #pragma multi_compile_local _ UNITY_UI_CLIP_RECT
            #pragma multi_compile_local _ UNITY_UI_ALPHACLIP

            #include "Packages/com.coffee.softmask-for-ugui/Shaders/SoftMask.cginc"
            #pragma shader_feature __ SOFTMASK_EDITOR

            struct appdata_t
            {
                float4 vertex   : POSITION;
                float4 color    : COLOR;
                float2 texcoord : TEXCOORD0;
                float4 screenPos : TEXCOORD1;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct v2f
            {
                float4 vertex   : SV_POSITION;
                fixed4 color    : COLOR;
                float2 texcoord  : TEXCOORD0;
                float4 screenPos : TEXCOORD1;
                float4 worldPosition : TEXCOORD2;
                UNITY_VERTEX_OUTPUT_STEREO
            };

            sampler2D _MainTex;
            fixed4 _Color;
            fixed4 _TextureSampleAdd;
            float4 _ClipRect;
            float4 _MainTex_ST;

            v2f vert(appdata_t IN)
            {
                v2f OUT;

                UNITY_SETUP_INSTANCE_ID(IN);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);

                                OUT.worldPosition = IN.vertex;
                OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
                OUT.texcoord = IN.texcoord;
                OUT.screenPos = ComputeScreenPos(OUT.vertex);
                OUT.color = IN.color * _Color * _RendererColor;
                                return OUT;
            }

            sampler2D _OverlayTex;
            sampler2D _AlphaTex;
            float _VSpeed;
            float _XSpeed;
            fixed4 _OverlayColor;
            fixed4 _FillColor;
            float _Scale;

            fixed4 SampleSpriteTexture(float2 uv)
            {
                fixed4 color = tex2D(_MainTex, uv);

                #if ETC1_EXTERNAL_ALPHA
                    fixed4 alpha = tex2D(_AlphaTex, uv);
                    color.a = lerp(color.a, alpha.r, _EnableExternalAlpha);
                #endif

                return color;
            }

            fixed4 frag(v2f IN) : SV_Target
            {

                fixed4 c = SampleSpriteTexture(IN.texcoord) * IN.color;
                                float2 textureCoordinate;

                textureCoordinate = IN.screenPos.xy / IN.screenPos.w;
                float aspect = _ScreenParams.x / _ScreenParams.y; 
                textureCoordinate.x = textureCoordinate.x * aspect;

                fixed4 fx = tex2D(_OverlayTex, _Scale*textureCoordinate+float2(_Time.x* _XSpeed,_Time.x* _VSpeed));
                c.rgb *= c.a;

                fx = lerp(_OverlayColor, _FillColor, fx.r);
                c.rgb = lerp(fx.rgb,c.rgb,1-fx.a)*c.a;
                                c.a *= SoftMask(IN.vertex, IN.worldPosition);

                return c;
            }
        ENDCG
        }
    }
}
mob-sakai commented 13 hours ago

Please try v2: https://github.com/mob-sakai/SoftMaskForUGUI/releases/tag/v2.0.0