Search Unity

Pink Custom Shaders in a Windows PC when building for target Android

Discussion in 'Addressables' started by miguel-ferradans-scopely, Apr 9, 2021.

  1. miguel-ferradans-scopely

    miguel-ferradans-scopely

    Joined:
    Nov 3, 2020
    Posts:
    3
    Addressables Version: 1.16.15 / 1.17.15
    Shader code:
    Code (CSharp):
    1. Shader "UI/Overlayed Color1"
    2. {
    3.     Properties
    4.     {
    5.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    6.         _Color ("Tint", Color) = (1,1,1,1)
    7.        
    8.         _StencilComp ("Stencil Comparison", Float) = 8
    9.         _Stencil ("Stencil ID", Float) = 0
    10.         _StencilOp ("Stencil Operation", Float) = 0
    11.         _StencilWriteMask ("Stencil Write Mask", Float) = 255
    12.         _StencilReadMask ("Stencil Read Mask", Float) = 255
    13.  
    14.         _ColorMask ("Color Mask", Float) = 15
    15.  
    16.         [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
    17.     }
    18.  
    19.     SubShader
    20.     {
    21.         Tags
    22.         {
    23.             "Queue"="Transparent"
    24.             "IgnoreProjector"="True"
    25.             "RenderType"="Transparent"
    26.             "PreviewType"="Plane"
    27.             "CanUseSpriteAtlas"="True"
    28.         }
    29.        
    30.         Stencil
    31.         {
    32.             Ref [_Stencil]
    33.             Comp [_StencilComp]
    34.             Pass [_StencilOp]
    35.             ReadMask [_StencilReadMask]
    36.             WriteMask [_StencilWriteMask]
    37.         }
    38.  
    39.         Cull Off
    40.         Lighting Off
    41.         ZWrite Off
    42.         ZTest [unity_GUIZTestMode]
    43.         Blend One OneMinusSrcAlpha
    44.         ColorMask [_ColorMask]
    45.  
    46.         Pass
    47.         {
    48.         CGPROGRAM
    49.             #pragma vertex vert
    50.             #pragma fragment frag
    51.  
    52.             #include "UnityCG.cginc"
    53.             #include "UnityUI.cginc"
    54.  
    55.             #pragma multi_compile __ UNITY_UI_ALPHACLIP
    56.            
    57.             struct appdata_t
    58.             {
    59.                 float4 vertex   : POSITION;
    60.                 float4 color    : COLOR;
    61.                 float2 texcoord : TEXCOORD0;
    62.             };
    63.  
    64.             struct v2f
    65.             {
    66.                 float4 vertex   : SV_POSITION;
    67.                 fixed4 color    : COLOR;
    68.                 half2 texcoord  : TEXCOORD0;
    69.                 float4 worldPosition : TEXCOORD1;
    70.             };
    71.            
    72.             fixed4 _Color;
    73.             fixed4 _TextureSampleAdd;
    74.             float4 _ClipRect;
    75.  
    76.             v2f vert(appdata_t IN)
    77.             {
    78.                 v2f OUT;
    79.                 OUT.worldPosition = IN.vertex;
    80.                 OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
    81.  
    82.                 OUT.texcoord = IN.texcoord;
    83.                
    84.                 #ifdef UNITY_HALF_TEXEL_OFFSET
    85.                 OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
    86.                 #endif
    87.                
    88.                 OUT.color = IN.color * _Color;
    89.                 return OUT;
    90.             }
    91.  
    92.             sampler2D _MainTex;
    93.  
    94.             fixed4 frag(v2f IN) : SV_Target
    95.             {
    96.                 fixed4 c = tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd;
    97.                 float lum = (c.r + c.g + c.b) * 0.6666666;
    98.  
    99.                 fixed3 c1 = IN.color.rgb * lum;
    100.                 fixed3 c2 = lerp(IN.color.rgb, fixed3(1,1,1), lum - 1);
    101.                 float r = step(1, lum);
    102.                 c.a *= IN.color.a * UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
    103.                 c.rgb = (c1 * (1 - r) + c2 * r) * c.a;
    104.  
    105.                 #ifdef UNITY_UI_ALPHACLIP
    106.                 clip (c.a - 0.001);
    107.                 #endif
    108.  
    109.                 return c;
    110.             }
    111.         ENDCG
    112.         }
    113.     }
    114. }
    Steps to reproduce in empty-new project:
    1. Create a Prefab with an UI Image attached, reference a random sprite
    2. Reference a material that uses this custom shader
    3. Add the Prefab as addressable
    4. Switch Platform to Android
    5. Make Addressables build and make sure the Play Mode is set to Use Existing Groups
    6. Load the Prefab from an addressable bundle and instantiate it
    7. Watch how the Prefab is instantiated correctly, the sprite and materials are set correctly in the SpriteRenderer window.
    8. Watch how the Custom Shader is loaded correctly (its not a missing shader), however, all the settings are defaulted, is not fetching the Properties correctly from the custom shader, so it shows as pink.

    This seems just to be an Editor issue, because apparently when building an apk it works fine.

    Any ideas how to work around this issue in Editor or if theres any fix in sight for this ?
    upload_2021-4-9_13-19-49.png
     
  2. davidla_unity

    davidla_unity

    Unity Technologies

    Joined:
    Nov 17, 2016
    Posts:
    763
    Hey, just wanted to chime in. I imagine that warning in your console is something similar to
    There's a bit of documentation about it here https://docs.unity3d.com/Packages/c...gStarted.html#building-for-multiple-platforms but, admittedly, it could be better documented.

    The tl;dr version is that we can't support shaders built for non-Standalone platforms in the Editor because of how the shaders are compiled. Even if we implemented a solution so that playmode didn't have pink (missing) shaders it would be because we force the Editor to look at standalone AssetBundles.

    Sorry that it's disappointing news. I hope this helps though
     
  3. lumanskiy

    lumanskiy

    Joined:
    Oct 23, 2015
    Posts:
    8
    @davidla_unity Can you or someone else at Unity explain, what is the difference between a built-in shader such as UI/Default and a custom shader? Somehow this isn't the issue with "UI/Default" but if someone makes their own copy of it, when loaded from a bundle it turns pink like any other custom shader.

    Also worth mentioning, one could temporarily "fix" the issue by opening a material in playmode and simply re-assigning the shader, but it only works within one playmode session and isn't really convenient.

    It would be extremely useful to be able to get asset-bundled mobile shaders properly work in editor without a ton of hacks.
     
  4. SampsaPlaysome

    SampsaPlaysome

    Joined:
    Oct 20, 2019
    Posts:
    34
    The issue is that the bundle you download contains a compiled version of the shader for Android, but you're running on Windows which can't use that compiled shader. When you run the project in editor, all local shaders are using the Windows compatible compiled shaders as they're available in the asset database.

    Even if it's the same shader, Unity does not know that, because you can basically load any bundle with any shader content. There might be shaders you don't have in your project. It's the same with textures. Even you put the very same texture in a bundle that you have in the asset database, once loaded as asset bundle in editor, it will be a (compressed) copy of the texture and not the one in your asset database.

    I think you can disable shader stripping to include all versions in the bundles, but to me this a bit defeats the purpose of bundles. I recommend making local Android builds to test the Addressables download flow.