Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Bug Multiplying color by a Max Alpha breaks shader on Android

Discussion in 'Shaders' started by Sudden62, Sep 29, 2020.

  1. Sudden62

    Sudden62

    Joined:
    May 3, 2017
    Posts:
    11
    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.

    Code (CSharp):
    1. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
    2.  
    3. Shader "Custom/SunRayShader"
    4. {
    5.     Properties
    6.     {
    7.         _MainTex("Texture", 2D) = "white" {}
    8.         _MaxAlpha("MaxAlpha", Float) = 1.0
    9.     }
    10.  
    11.     SubShader
    12.     {
    13.         Tags
    14.         {
    15.             "Queue" = "Transparent"
    16.             "PreviewType" = "Plane"
    17.             "RenderType" = "Transparent"
    18.         }
    19.         Pass
    20.         {
    21.             ZWrite Off
    22.             Blend SrcAlpha OneMinusSrcAlpha
    23.  
    24.             CGPROGRAM
    25.             #pragma vertex vert
    26.             #pragma fragment frag
    27.  
    28.             #include "UnityCG.cginc"
    29.  
    30.             sampler2D _MainTex;
    31.             float1 _MaxAlpha;
    32.  
    33.             struct appdata
    34.             {
    35.                 float4 sprColor : COLOR;
    36.                 float4 vertex : POSITION;
    37.                 float2 uv : TEXCOORD0;
    38.             };
    39.  
    40.             struct v2f
    41.             {
    42.                 float4 sprColor : COLOR;
    43.                 float4 vertex : SV_POSITION;
    44.                 float2 uv : TEXCOORD0;
    45.             };
    46.  
    47.             v2f vert(appdata v)
    48.             {
    49.                 v2f o;
    50.                 o.sprColor = v.sprColor;
    51.                 o.sprColor.a *= _MaxAlpha; // Option 1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    52.                 o.vertex = UnityObjectToClipPos(v.vertex);
    53.                 o.uv = v.uv;
    54.                 return o;
    55.             }
    56.  
    57.             float4 frag(v2f i) : SV_Target
    58.             {
    59.                 float4 color = tex2D(_MainTex, i.uv) * i.sprColor;
    60.                 color.a *= _MaxAlpha; // Option 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    61.                 return color;
    62.             }
    63.             ENDCG
    64.         }
    65.     }
    66. }
    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+.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    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.
     
    Sudden62 likes this.
  3. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    2,983
    This is just information about SRP batcher compatibility.

    What's in the device logs?
     
  4. Sudden62

    Sudden62

    Joined:
    May 3, 2017
    Posts:
    11
    Magic indeed! It works. Thank you.