Skip to main content

Shaders look different on Android devices only

This issue is most likely caused by WebGL precision issues.

The use of functions like normalize, length, distance, dot in your shader might return inaccurate results on Android devices if provided parameters are defined as half or fixed.

Possible solution:

  • The issue can be fixed by using float instead.
EXAMPLE

Here is an example of a pseudo-shader that will behave differently on Android devices with large values of _LightDirection = (400, 200, -200, 1):

Shader "Core/Hyper Lighting"
{
Properties
{
_LightDirection ("Light Direction", Vector) = (400, 200, -200, 1)
}

SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 200

//Blend SrcAlpha OneMinusSrcAlpha
Pass
{

CGPROGRAM

// Define name of vertex shader
#pragma vertex vert
// Define name of fragment shader
#pragma fragment frag
#include "UnityCG.cginc"
half4 _LightDirection;

// This is the vertex shader
v2f vert(appdata v)
{
...
}

// This is the fragment shader
half3 frag(v2f i) : COLOR
{
half3 normalized = normalize(half3(_LightDirection.x, _LightDirection.y, _LightDirection.z));
return normalized;
}

ENDCG
}
}
}

The following is the fixed version:

float4 _LightDirection;

// This is the vertex shader
v2f vert(appdata v)
{
...
}

// This is the fragment shader
half3 frag(v2f i) : COLOR
{
float3 normalized = normalize(float3(_LightDirection.x, _LightDirection.y, _LightDirection.z));
return normalized;
}