Multiplying color by a Max Alpha breaks shader on Android

Hello, I’m a novice at writing shaders and am pretty puzzled by the behavior I’m seeing. Basically, I took a sprite rendering shader and added a float property _MaxAlpha, which multiplies the alpha of the output. This is so I could have all particles in a system fade out at the same time. This works in Unity on Windows 10. However, on my android the shader is broken and displays as pink.

I poked and prodded until I found the issue to be the line that multiplies the alpha. You can see option 1 and option 2 below which both cause the same issue. Weirdly, I could multiply the entire color by _MaxAlpha and it would work fine on my phone, but not just the alpha. I also could not multiply the entire color by a float4 like so: (1, 1, 1, _MaxAlpha). Currently I’ve gone to using another shader with a tint property to allow me to lower the alpha. But I’m still really curious why this shader fails on android.

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/SunRayShader"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _MaxAlpha("MaxAlpha", Float) = 1.0
    }

    SubShader
    {
        Tags
        {
            "Queue" = "Transparent"
            "PreviewType" = "Plane"
            "RenderType" = "Transparent"
        }
        Pass
        {
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            sampler2D _MainTex;
            float1 _MaxAlpha;

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

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

            v2f vert(appdata v)
            {
                v2f o;
                o.sprColor = v.sprColor;
                o.sprColor.a *= _MaxAlpha; // Option 1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            float4 frag(v2f i) : SV_Target
            {
                float4 color = tex2D(_MainTex, i.uv) * i.sprColor;
                color.a *= _MaxAlpha; // Option 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                return color;
            }
            ENDCG
        }
    }
}

My project is also utilizing the URP. I noticed in the inspector when I have the alpha multiplication in, it warns “Material property is found in another cbuffer than ‘UnityPerMaterial’ (_MaxAlpha).” Googling yielded no answers on this warning but I think it means it would prefer to convert the shader to URP’s format? Anyway, another shader I made has the same warning but works fine on mobile devices.

I’m using Unity 2019.4.11f1 on Windows 10. My android is a recently updated Galaxy Note 10+.

Using float1 instead of float is a little uncommon. It’s possible that’s causing a problem for some reason. Try removing the 1 from the end of the float and see if it magically fixes it.

1 Like

This is just information about SRP batcher compatibility.

What’s in the device logs?

Magic indeed! It works. Thank you.