Custom UI Shader Becomes Fully Transparent with Mask

Hi,
I’m developing a custom shader to create a gradient effect, but I’m encountering an issue where the shader renders completely transparent when used with a mask.

Here’s the stencil-related code I added:

 Properties
 {
     ...
     _StencilComp ("Stencil Comparison", Float) = 8
     _Stencil ("Stencil ID", Float) = 0
     _StencilOp ("Stencil Operation", Float) = 0
     _StencilWriteMask ("Stencil Write Mask", Float) = 225
     _StencilReadMask ("Stencil Read Mask", Float) = 255
     _ColorMask ("Color Mask", Float) = 15
 }

 SubShader
 {
     Tags
     {
         "Queue"="Transparent"
         "IgnoreProjector"="True"
         "RenderType"="Transparent"
         "PreviewType"="Plane"
         "CanUseSpriteAtlas"="True"
     }

     Cull Off
     Lighting Off
     ZWrite Off
     ZTest [unity_GUIZTestMode]
     Blend SrcAlpha OneMinusSrcAlpha
     
     Pass
     {   
         Stencil
         {
             Ref [_Stencil]
             Comp [_StencilComp]
             Pass [_StencilOp]
             ReadMask [_StencilReadMask]
             WriteMask [_StencilWriteMask]
         }
         
         ColorMask[_ColorMask]
         ...
}

And here’s the full shader script:

Shader "Custom/DynamicGradient"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Angle ("Gradient Angle", Float) = 0.0

        _StencilComp ("Stencil Comparison", Float) = 8
        _Stencil ("Stencil ID", Float) = 0
        _StencilOp ("Stencil Operation", Float) = 0
        _StencilWriteMask ("Stencil Write Mask", Float) = 225
        _StencilReadMask ("Stencil Read Mask", Float) = 255
        _ColorMask ("Color Mask", Float) = 15
    }

    SubShader
    {
        Tags
        {
            "Queue"="Transparent"
            "IgnoreProjector"="True"
            "RenderType"="Transparent"
            "PreviewType"="Plane"
            "CanUseSpriteAtlas"="True"
        }

        Cull Off
        Lighting Off
        ZWrite Off
        ZTest [unity_GUIZTestMode]
        Blend SrcAlpha OneMinusSrcAlpha
        
        Pass
        {   
            Stencil
            {
                Ref [_Stencil]
                Comp [_StencilComp]
                Pass [_StencilOp]
                ReadMask [_StencilReadMask]
                WriteMask [_StencilWriteMask]
            }
            
            ColorMask[_ColorMask]
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            #define DEGREE_2_RADIAN 0.01745329252

            sampler2D _MainTex;
            int _ColorCount;
            fixed4 _Colors[100];
            float _Positions[100];
            float _Angle;

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

            struct v2f
            {
                float2 texcoord : TEXCOORD0;
                float4 vertex : SV_POSITION;
                float2 gradientUV : TEXCOORD1;
            };

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

            fixed4 sampleGradientColor(fixed4 colors[100], float positions[100], int count, float t)
            {
                fixed4 col;

                if (t <= positions[0])
                {
                    col = colors[0];
                }
                else if (t >= positions[count - 1])
                {
                    col = colors[count - 1];
                }
                else
                {
                    for (int j = 0; j < count - 1; j++)
                    {
                        if (t >= positions[j] && t <= positions[j + 1])
                        {
                            float factor = (t - positions[j]) / (positions[j + 1] - positions[j]);
                            col = lerp(colors[j], colors[j + 1], factor);
                            break;
                        }
                    }
                }
                
                return col;
            }

            float2 rotate(fixed2 uv, float rotation)
            {
                float sinX = sin (rotation);
                float cosX = cos (rotation);
                float2x2 rotationMatrix = float2x2( cosX, -sinX, sinX, cosX);
                return mul (uv - fixed2 (0.5, 0.5), rotationMatrix) + fixed2 (0.5, 0.5);
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float rotateUV = rotate (i.texcoord, _Angle * DEGREE_2_RADIAN);
                fixed4 col = sampleGradientColor (_Colors, _Positions, _ColorCount, rotateUV);
                return col;
            }

            ENDCG
        }
    }
}

I tried modifying the code to output a solid color block directly, and the issue still persists, so it doesn’t seem to be related to my gradient function.

Am I missing something? Any insights would be appreciated!

Updates:
For testing, I copied the UI-default.shader and used it as my custom shader.

I noticed that the mask doesn’t work even with the default shader.

Here’s how I tested it:

  1. Created a material using my custom shader (identical to the default shader) and applied it to an image component.
  2. Changed the material’s color—this displayed correctly.
  3. Moved the object under a mask, and the color became fully transparent.

However, masking works fine when I change the image component’s color instead of the material’s color.
Why does this happen?