Issue with shader in iOS

Hi everyone. I did a simple Unlit Texture shader with a slider where i control the saturation of the texture. In Editor works great, also i’m updating the saturation value from Material.SetFloat and also works.

The problem is when i build to iOS. The shader seems to be doing what it wants.
The effect is to go from the texture color to a gray scale reducing the saturation, as i said in the editor works but in iOS nope.

I am not a shader dev so am i missiing something?

Thanks!

Can you post the shader code?

Sure, here it is.

Shader "Unlit/Saturation"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Saturation ("Saturation", Range(0, 1)) = 1
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _Saturation;

            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 = mul(UNITY_MATRIX_MVP, v.vertex);
                o.uv = v.uv;
                return o;
            }
          
            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                col.rgb = lerp( dot(col.rgb, fixed3(0.22, 0.707, 0.071)), col.rgb , _Saturation );
                return col;
            }
            ENDCG
        }
    }
}

I think it’s because you’re using a dot product, which converts a vector to a single float, in a vector3. Maybe try this:

Shader "Unlit/Saturation"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Saturation ("Saturation", Range(0, 1)) = 1
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _Saturation;
            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 = mul(UNITY_MATRIX_MVP, v.vertex);
                o.uv = v.uv;
                return o;
            }
      
            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                fixed3 desaturate = dot(col.rgb, fixed3(0.22, 0.707, 0.071));
                col.rgb = lerp( desaturate, col.rgb , _Saturation );
                return col;
            }
            ENDCG
        }
    }
}

You are saying that the way a did the dot function is the problem?
Now i cannot test it but the behaviour in iOS is that the object is in gray scale but i can see how the intense of the gray scale changes when it has to change to color again. Its a ping pong from color to gray scale.
But i also had a problem animating the normal map value (the normal scale/depth) in IOS is not animating and also in pc works fine.
Just to check that i used the standar shader set a texture and normal and with a script change the NormalDepth.
I dont know whats going on

Yeah, so by putting a dot product in a vector you confused the compiler into thinking the shader was lerping a float. The end result was the shader lerping between your dot result and the .x value of col (which looks greyscale). This only happened in iOS because different graphics platforms are more strict with their syntax than others, so something that works fine on PC with DirectX will probably not work with Metal on iOS. It can be frustrating, but eventually you start to develop techniques to avoid it (i.e. don’t mix different variable types together in math, clamp colour values with saturate(), etc). It would be great if Unity could better emulate different graphics platforms on desktops to help diagnose problems like this.

Tomorrow i will test it!
Thanks a lot for your time!

I test it and works. Thanks a lot for your answer.
I will show another issue in other post later.