Fragment shader behaving different on Android and PC

Hi,

I have a shader which I pulled together based on shaders in the wiki/forums, which is doing exactly what I want - rim lit, with control over both rim light colour and main texture colour. It looks great in the unity editor with the build as Android, but switch to PC standalone as the platform and the resulting render goes almost white. When zoomed in you can see some evidence of texture, so it seems likely the part where I attempt to combine the rim and main colour is operating differently between the two platforms? The shader is below, and I also include a screenshot, with both renders. I’ve enjoyed messing around with shaders - this is my first attempt, so I’m most interested in just understanding what I’ve done wrong, what is the difference between the android and PC plaforms that I need to be aware of?

Ian

Shader "Custom/SunShaderFast" {
Properties {
    _MainTex ("Texture", 2D) = "white" { }
    _BumpMap ("BumpMap", 2D) = "white" { }
    _RimLightColor ("Rimlight Color", Color) = (1.0, 1.0, 1.0, 1.0)
    _MainColor ("Main Color", Color) = (0.95, 0.95, 0.0, 1.0)
}
SubShader {
    Pass {
 
	CGPROGRAM
	// Upgrade NOTE: excluded shader from DX11 and Xbox360; has structs without semantics (struct v2f members tangentSpaceLightDir)
	#pragma exclude_renderers d3d11 xbox360
	#pragma vertex vert
	#pragma fragment frag
	 
	#include "UnityCG.cginc"
	 
	sampler2D _MainTex;
	sampler2D _BumpMap;
	float4 _RimLightColor;
	float4 _MainColor;
	
	struct v2f {
	    float4  pos : SV_POSITION;
	    float2  uv : TEXCOORD0;
	    float3  tangentSpaceLightDir;
	};
	 
	float4 _MainTex_ST;
	 
	v2f vert (appdata_tan v)
	{
	    v2f o;
	    o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
	    o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);
	    
	    float3 viewDir = normalize(ObjSpaceViewDir(v.vertex));
	                 float3 binormal = cross( normalize(v.normal), normalize(v.tangent.xyz) );
	               float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
	               
	               o.tangentSpaceLightDir = normalize(mul(rotation, viewDir));
	        
	    
	    return o;
	}


	half4 frag (v2f i) : COLOR
    {
       half3 tangentSpaceNormal = normalize((tex2D(_BumpMap, i.uv).rgb * 2.0) - 1.0);
        
       half4 result = float4(0, 0, 0, 1);

       float rimFactor = dot(tangentSpaceNormal, i.tangentSpaceLightDir);

       result.rgb = (1-rimFactor) * _RimLightColor.rgb;
       result.rgb += tex2D(_MainTex, i.uv).rgb * _MainColor.rgb * rimFactor * 2   ;

       return result;
    }


ENDCG
 
    }
}
Fallback "Unlit"
}

This line…
half3 tangentSpaceNormal = normalize((tex2D(_BumpMap, i.uv).rgb * 2.0) - 1.0);
…will only work if your normal map is set to a regular Texture type, not Normal.

On android, it’s stored as a regular texture anyway - so the code will work, which is why your shader works fine on mobile.
On desktop, it gets stored with swizzled channels and the proper normal map is reconstructed in the shader - so that code won’t work.

Unity has a helper function for this, which will perform the correct action depending on the platform you compile to. As long as your normal map is set to being Normal type.
half3 tangentSpaceNormal = UnpackNormal(tex2D(_BumpMap, i.uv));

Farfarer,

Thanks, that works perfectly, much appreciated.

Ian