Search Unity

  1. Unity 2020.1 has been released.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Simple Shader does not work on Android device

Discussion in 'Shaders' started by RainbowLab, Aug 21, 2019.

  1. RainbowLab

    RainbowLab

    Joined:
    May 20, 2019
    Posts:
    12
    I wrote this simple shader that allows me to change two specific colors of a sprite:
    Code (CSharp):
    1. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
    2.  
    3. Shader "Unlit/PixelColorSwap"
    4. {
    5.     Properties
    6.     {
    7.         [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
    8.         _Color1in("Color 1 In", Color) = (1,1,1,1)
    9.         _Color1out("Color 1 Out", Color) = (1,1,1,1)
    10.         _Color2in("Color 2 In", Color) = (1,1,1,1)
    11.         _Color2out("Color 2 Out", Color) = (1,1,1,1)
    12.     }
    13.  
    14.         SubShader
    15.         {
    16.             Tags
    17.             {
    18.                 "Queue" = "Transparent"
    19.                 "IgnoreProjector" = "True"
    20.                 "RenderType" = "Transparent"
    21.                 "PreviewType" = "Plane"
    22.                 "CanUseSpriteAtlas" = "True"
    23.             }
    24.  
    25.             Cull Off
    26.             Lighting Off
    27.             ZWrite Off
    28.             ZTest[unity_GUIZTestMode]
    29.             Blend SrcAlpha OneMinusSrcAlpha
    30.  
    31.             Pass
    32.             {
    33.             CGPROGRAM
    34.                 #pragma vertex vert
    35.                 #pragma fragment frag      
    36.  
    37.                 #include "UnityCG.cginc"
    38.                 #include "UnityUI.cginc"
    39.  
    40.                 struct appdata_t
    41.                 {
    42.                     float4 vertex   : POSITION;
    43.                     float4 color    : COLOR;
    44.                     float2 texcoord : TEXCOORD0;
    45.                 };
    46.  
    47.                 struct v2f
    48.                 {
    49.                     float4 vertex   : SV_POSITION;
    50.                     fixed4 color : COLOR;
    51.                     half2 texcoord  : TEXCOORD0;
    52.                     float4 texposition : TEXCOORD1;
    53.                 };
    54.  
    55.                 fixed4 _Color1in;
    56.                 fixed4 _Color1out;
    57.                 fixed4 _Color2in;
    58.                 fixed4 _Color2out;
    59.  
    60.                 bool _UseClipRect;
    61.                 bool _UseAlphaClip;
    62.                 float4 _ClipRect;
    63.  
    64.                 v2f vert(appdata_t IN)
    65.                 {
    66.                     v2f OUT;
    67.                     OUT.texposition = IN.vertex;
    68.                     OUT.vertex = UnityObjectToClipPos(OUT.texposition);
    69.                     OUT.texcoord = IN.texcoord;
    70.  
    71.                     #ifdef UNITY_HALF_TEXEL_OFFSET
    72.                     OUT.vertex.xy += (_ScreenParams.zw - 1.0) * float2(-1, 1);
    73.                     #endif
    74.  
    75.                     OUT.color = IN.color;
    76.  
    77.                     return OUT;
    78.                 }
    79.  
    80.                 sampler2D _MainTex;
    81.  
    82.                 fixed4 frag(v2f IN) : Color
    83.                 {
    84.                     float4 texColor = tex2D(_MainTex, IN.texcoord) * IN.color;
    85.                     texColor = all(texColor == _Color1in) ? _Color1out : texColor;
    86.                     texColor = all(texColor == _Color2in) ? _Color2out : texColor;
    87.  
    88.                     if (_UseClipRect)
    89.                         texColor *= UnityGet2DClipping(IN.texposition.xy, _ClipRect);
    90.  
    91.                     if (_UseAlphaClip)
    92.                         clip(texColor.a);
    93.  
    94.                     return texColor * IN.color;
    95.                 }
    96.             ENDCG
    97.             }
    98.         }
    99. }
    Testing it with the Unity editor works perfectly.
    Creating a .apk and testing it on a PC (unig emulator) works perfectly.
    If instead I install the .apk on an Android device (so far I have tested 4 different ones), the shader does not work at all, and the colors of the sprite are not changed.
    Can anyone tell me why? Unfortunately I haven't been able to find a solution for weeks, and I can't continue to develop my project. :(
     
  2. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    1,531
    Hi!
    (Not on topic)
    Code (CSharp):
    1. half2 texcoord  : TEXCOORD0;
    needs to be float2, otherwise you can have precision issues on larger textures.

    (On topic)
    When you're comparing floating-point values, you can't just use "==". You need to provide some tolerance for rounding that happens after operations, e.g.
    Code (CSharp):
    1. abs(texColor - _Color1in) < 0.005
    . See https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems, for example for a detailed explanation.
     
    RainbowLab likes this.
  3. RainbowLab

    RainbowLab

    Joined:
    May 20, 2019
    Posts:
    12
    Thank you so much!
    I made the corrections and now also seems to work on Android devices!
    Thank you!
     
    aleksandrk likes this.
unityunity