title: Custom Shader not working on Android
body: <p>I ported a Plasma ball shader from <a href="https://www.shadertoy.com/view/MstXzf" rel="nofollow noreferrer">Shadertoy</a> to Unity as Image Effect which is attached to the camera. It works fine on the Editor and Windows standalone build. It does not work on Android devices. <em>It is flashing blue and black images on Android.</em></p>
  
  <p>Here is what it looks like in Unity Editor and Windows Build:</p>
  
  <p><img src="https://i.imgur.com/6Ihy6i0.gif" width="900" height="400"></p>
  
  <p>Here is what it looks like on Android:</p>
  
  <p><img src="https://i.imgur.com/Xice8RC.gif" width="900" height="400"></p>
  
  <p>The ported Shader code:</p>
  
  <pre><code>Shader "Hidden/Plasma Space Ball Image Effect"
  {
      Properties
      {
          iChannel0("iChannel0", 2D) = "white" {}
      //[MaterialToggle] _isToggled("isToggle", Float) = 0
      }
          SubShader
      {
          // No culling or depth
          Cull Off ZWrite Off ZTest Always
  
          Pass
          {
              CGPROGRAM
              #pragma vertex vert
              #pragma fragment frag
  
              #include "UnityCG.cginc"
  
              struct appdata
              {
                  float4 vertex : POSITION;
                  float2 uv : TEXCOORD0;
              };
  
              struct v2f
              {
                  float2 uv : TEXCOORD0;
                  float4 vertex : SV_POSITION;
              };
  
              v2f vert(appdata v)
              {
                  v2f o;
                  o.vertex = UnityObjectToClipPos(v.vertex);
                  o.uv = v.uv;
                  return o;
              }
  
              sampler2D iChannel0;
  
              //Ported from https://www.shadertoy.com/view/MstXzf
  
              float3 hb(float2 pos, float t, float time, float2 rot, float size, sampler2D tex0)
              {
                  float2 newUv = 0.2*(pos / (1.2 - t) + 0.5*time*rot);
                  //float texSample = texture(tex0, newUv).b;
                  float texSample = tex2D(tex0, newUv).b;
                  float uOff = 0.2*(texSample + 0.3*time);     //lsf3RH
                  float2 starUV = newUv + float2(uOff, 0.0);
                  //return float3(0.3, 0.3, 1.0) + 1.3*texture(tex0, starUV).b;
                  return float3(0.3, 0.3, 1.0) + 1.3*tex2D(tex0, starUV).b;
              }
  
              float4 blob(float2 uv, float size, float time, sampler2D tex0)
              {
                  float2 center = float2(0., 0.);
  
                  float2 pos = center - uv;
                  float t = length(pos);
                  float st = size - t;
  
                  float2 rot = 0.005*float2(sin(time / 16.), sin(time / 12.)); //MslGWN
  
                  float alpha = smoothstep(0.0, 0.2*size, st);
  
                  float3 col = hb(pos, t, time, rot, size, tex0);
                  float a1 = smoothstep(-1.4, -1.0, -col.b);
                  col = lerp(col, hb(pos, t, -time, -rot, size, tex0), a1);
  
                  col += 0.8*exp(-12.*abs(t - 0.8*size) / size);
                  float a2 = smoothstep(-1.4, -1.0, -col.b);
  
                  alpha -= a2;
  
                  //float crosshair = float((abs(pos.x) &lt; 0.005 &amp;&amp; abs(pos.y) &lt; 0.15) || (abs(pos.y) &lt; 0.005&amp;&amp;abs(pos.x) &lt; 0.15));
                  //return float4(col, alpha) + crosshair;
  
                  return float4(col, alpha);
              }
  
              float4 main_(float2 uv, float size)
              {
                  return blob(uv, size, _Time.y, iChannel0);
              }
  
  
              fixed4 frag(v2f i) : SV_Target
              {
                  float4 fragColor = 0;
                  float2 fragCoord = i.vertex.xy;
  
                  ///---------------------------------------------------
  
                  float2 uv = fragCoord.xy / _ScreenParams.xy;
                  float2 cr = uv*2. - 1.;
                  cr.x *= _ScreenParams.x / _ScreenParams.y;
  
                  //late addition to elaborate background motion, could be reused later on
                  float2 rot = 0.5*float2(sin(_Time.y / 16.), sin(_Time.y / 12.));
  
                  float4 ball = clamp(main_(cr, sin(_Time.y)*0.05 + 0.5 + 0.5), 0., 1.);
                  //float3 bg = float3(0.7, 0.7, 1.0)*texture(iChannel0, uv + rot + 0.1*ball.rb).b;
                  float3 bg = float3(0.7, 0.7, 1.0)*tex2D(iChannel0, uv + rot + 0.1*ball.rb).b;
  
                  //simulated gl blend
                  fragColor = float4(lerp(bg, ball.rgb, ball.a), 1.0);
                  //fragColor = lerp(fragColor,tex2D(iChannel0, i.uv).rgba,.5);
                  return fragColor;
              }
              ENDCG
          }
      }
  }
  </code></pre>
  
  <hr>
  
  <p>You can find the image that is used for  the <code>iChannel0</code> input slot <a href="https://imgur.com/a/d62rs" rel="nofollow noreferrer">here</a> in the Shader above.</p>
  
  <p>Things I've tried:</p>
  
  <ul>
  <li>Adding the shader to the Graphics Settings so that Unity will include
  it in during build process.</li>
  <li>Disabling Auto Graphics API and trying OpenGLES2 and OpenGLES3.</li>
  <li>Checking the log with Android Studio. No error/warning at-all.</li>
  </ul>
  
  <p>None of these solved the problem and I ran out of things to try. </p>
  
  <p>Software and Device Info if that helps:</p>
  
  <ul>
  <li>Unity 5.6.0f3</li>
  <li>Android 4.4.2</li>
  </ul>
  
  <p>This is used for learning and educational purposes as I am studying GLSL, HLSL, CG/shaderlab shader language. I just want to know why the ported shader is not working as expected on Android devices.</p>
  
  <p><em>Why is it flashing blue and black images on Android?</em></p>