Shader only partially works on device ?

I wrote a pretty simple surface shader for water, two textures, reads UV’s from each and blends them with lerp,
scrolling UV’s in different directions.
I don’t pass in UV’s, I calculate them from a single float param I pass in.
Works great in editor…
However on device… I only see one scrolling texture… not 2 blended textures scrolling… but yet its not failing and doing a fallback render.
What is going on ? Does unity remove bits of shaders ?
Why does it work in unity, but only partially on iPhone 6s

Help appreciated, thanks.

    Properties
    {
      _MainTex ("Texture", 2D) = "white" {}
      _Texture2 ("Texture2", 2D) = "white" {}
      _TextDepth("Depth", 2D) = "white" {}            //use red channel for depth, color tint (move this to alpha of main texture later)
      _TintCol ("Tint Color", Color) = (1,1,1)
      _DeepCol ("Deep Color", Color) = (.5,.6,.8)
      _Tile ("WaterTiling", Range(0,20)) = 12.0
      _ScrollOffset("Dual Water Offset", Range(0,1)) = 0.0            //param passed in from script
    }
   
    SubShader
    {
      Tags { "RenderType" = "Opaque" }
     
      CGPROGRAM
     
      #pragma surface surf Lambert nolightmap
      struct Input
      {
          float2 uv_MainTex;
          //float2 uv_Tex2;
          //float4 color : COLOR;                //vertex color

      };
     
      sampler2D _MainTex;
      sampler2D _Texture2;
      sampler2D _TextDepth;
      float3 _TintCol;
      float3 _DeepCol;
      float _ScrollOffset;
      float _Tile;
               
      void surf (Input IN, inout SurfaceOutput o)
      {       
           float2 uv2Water;   //assume scrolling UV along Y axis
         uv2Water.y = IN.uv_MainTex.y * _Tile * 1.123 + _ScrollOffset;

           //read in 2 textures from sam8 12.0e texture for water blending 50%-50%
         uv2Water.x = IN.uv_MainTex.x * _Tile - _ScrollOffset;

          //float lrp = IN.color.a;
          fixed3 maincol = tex2D(_MainTex, uv2Water);
          uv2Water.x = uv2Water.x + _ScrollOffset + _ScrollOffset;
         fixed3 othercol = tex2D(_Texture2, uv2Water);
         fixed3 depth = tex2D(_TextDepth, IN.uv_MainTex);
         
          //fixed4 blended = lerp( maincol, othercol, IN.color.a);
         fixed3 blended = lerp( maincol, othercol, .5);
          blended.rgb *= lerp( (1,1,1), _DeepCol, depth.r);

          //o.Albedo =    blended.rgb * IN.color.rgb * _TintCol;            //dual texture blended, plus tinted output
         o.Albedo.rgb =    blended.rgb * _TintCol.rgb;            //dual texture blended, plus tinted output
          o.Alpha = 1.0;                //not transparent
      }
     
      ENDCG
    }

Looks okay to me. Which texture is the one that shows up?

EDIT: Are you building for opengl es 2.0, 3.0, metal? If you change the setting does the shader work per chance?

looks like first texture is showing up… or possibly they are both there and blended, but both scrolling together, like it is sampling the same spot twice, and ignoring the code that changes the U after the first sampling.

I’ll try changing the compile settings for metal, good idea… back in 20 mins… (damn slow il2cpp compiling)

turned off metal. but still looks the same. compiling for OGL2
also tried unity graphics emulator levels 1,2,3 all look the same, and work ok. but on iPhone 5S… the texture blending has gone… or maybe the UV sampling has gone

maybe it doesn’t let yu read arbitrary UV’s? maybe there is some optimization going on, that only lets you read progressive texture pixels as fragment shader moves across polygon ?

think I fixed it… problem is re-using uv2Water if I do exactly the same calculations, but in a new variable uv3Water. then it works. There must be a bug in their code, optimizing something, that shouldn’t be, or thinking its the same variable so use same co-ords… or updates things in the wrong order. weird…

confirmed same behavior on a second shader. definitely bug. Don’t re-use a variable with UV’s ro read from same texture more than once… not guaranteed to work. it seems to just read the same pixel again. Use a separate variable, and it works.