Search Unity

Shader that works on Android and iPhone. Damn You Android!

Discussion in 'Shaders' started by OceanBlue, Apr 9, 2014.

  1. OceanBlue

    OceanBlue

    Joined:
    May 2, 2013
    Posts:
    251
    Hi

    I'm using the following shader (taken bits and pieces from those who have already posted it), to use on my 2d sprites.

    I need to be able to cast shadows and receive shadows. All works well on iPhone (although I get a 'may not perform well' message - but I haven't noticed any performance issues). But on Android it all turns to schnozzle.

    It runs at like 2fps if it's lucky and there are strange lines across the sprites.

    So, wondering if anyone can take a look at this and see what I can do so that I can get the same on Android as it performs on iPhone?

    I have NFI about shaders!

    Thanks :cool:

    Code (csharp):
    1.  
    2. Shader "Custom/Sprite Cast Rec Shadow" {
    3.     Properties
    4.     {
    5.         _MainTex ("Sprite Texture", 2D) = "white" {}
    6.         _Color ("Tint", Color) = (1,1,1,1)
    7.         PixelSnap ("Pixel snap", Float) = 0
    8.         _Cutoff ("Alpha cutoff", Range(0,1)) = 0.3
    9.  
    10.     }
    11.  
    12.     SubShader
    13.     {
    14.         Tags
    15.         {
    16.             "Queue"="AlphaTest" //bad for mobile! (Android anyway)
    17. //          "Queue"="Transparent"
    18.             "IgnoreProjector"="True"
    19.             "RenderType"="Transparent"
    20.             "PreviewType"="Plane"
    21.             "CanUseSpriteAtlas"="True"
    22.            
    23.         }
    24.             LOD 300
    25.  
    26.  
    27.         Cull Off
    28.         Lighting On
    29.         ZWrite On
    30.         Fog { Mode Off }
    31.         Blend SrcAlpha OneMinusSrcAlpha
    32.  
    33.         CGPROGRAM
    34.         #pragma surface surf Lambert alpha vertex:vert  alphatest:_Cutoff fullforwardshadows
    35.         #pragma multi_compile DUMMY PIXELSNAP_ON
    36.  
    37.         sampler2D _MainTex;
    38.         fixed4 _Color;
    39.  
    40.         struct Input
    41.         {
    42.             float2 uv_MainTex;
    43.             fixed4 color;
    44.         };
    45.        
    46.         void vert (inout appdata_full v, out Input o)
    47.         {
    48.             #if defined(PIXELSNAP_ON)  !defined(SHADER_API_FLASH)
    49.             v.vertex = UnityPixelSnap (v.vertex);
    50.             #endif
    51.             v.normal = float3(0,0,-1);
    52.             v.tangent =  float4(1, 0, 0, 1);
    53.            
    54.             UNITY_INITIALIZE_OUTPUT(Input, o);
    55.             o.color = _Color;
    56.         }
    57.  
    58.         void surf (Input IN, inout SurfaceOutput o)
    59.         {
    60.             fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * IN.color;
    61.             o.Albedo = c.rgb;
    62.             o.Alpha = c.a;
    63.         }
    64.         ENDCG
    65.     }
    66.  
    67. Fallback "Transparent/Cutout/Diffuse"
    68. }
    69.  
    70.  
    71.  
     
  2. OceanBlue

    OceanBlue

    Joined:
    May 2, 2013
    Posts:
    251
    No one can help / suggest with this?

    Thank you
     
  3. IanStanbridge

    IanStanbridge

    Joined:
    Aug 26, 2013
    Posts:
    334
    You would need to convert the shader from using Alphatest to something like Alphablend. Alphatest is not officially supported on mobile and is very bad for performance even on iphone. It's likely that your iphone is emulating the command and taking the performance hit while your android device might be instead choosing to use the fallback shader which is a different shader and accounts for the difference in look and performance or just has a driver that is worse at emulating Alphatest. The issue isn't about android vs ios but just down to what graphics chip and graphics driver your device has. If you have an android device with a powervr chip in it like your iphone , it would look identical to the iphone for example. Regardless it is a bad idea to use that shader on mobile because you are doing something that isn't build into mobile hardware and bad for performance hence the warning from unity.

    First of all comment out the fallback shader to make sure that both devices are actually trying to run that shader code rather than just jumping to the fallback with an error. If it is using the fallback after you comment it out then the device will either crash the application or display nothing when you comment it out. If it is using the Fallback then it means you should just use the mobile varient of that shader built into unity anyway.

    Next try commenting out the Queue = alphatest command to see if the shader can run without using that queue anyway. |f you get compiler errors you will then need to perhaps change that queue to alphablend and then change any of the other commands to their alpha blend equivalents.

    The shader code you have their is designed for a desktop device that can use alphatest. Alphatest is a technique that can look at the alpha transparency of a texture map and draw nothing if it detects no alpha. Mobile devices can't do this instead you have to make sure that you are blending all the overlaping texture maps together based on their alpha.