Hi, I have a weird problem with point lights in deferred rendering on Android. Exactly the same code works well on PC.
That’s how it looks on Android:
And the light render target:
And for comparison the same pair on PC:
Do you have any guess what’s wrong here? Below is the code for point lights:
float4x4 World;
float4x4 View;
float4x4 Projection;
//color of the light
float3 Color;
//position of the camera, for specular light
float3 cameraPosition;
//this is used to compute the world-position
float4x4 InvertViewProjection;
//this is the position of the light
float3 lightPosition;
//how far does this light reach
float lightRadius;
//control the brightness of the light
float lightIntensity = 1.0f;
// diffuse color, and specularIntensity in the alpha channel
texture colorMap;
// normals, and specularPower in the alpha channel
texture normalMap;
//depth
texture depthMap;
sampler colorSampler = sampler_state
{
Texture = (colorMap);
MagFilter = POINT;
MinFilter = POINT;
Mipfilter = POINT;
AddressU = Clamp;
AddressV = Clamp;
};
sampler depthSampler = sampler_state
{
Texture = (depthMap);
MagFilter = POINT;
MinFilter = POINT;
Mipfilter = POINT;
AddressU = Clamp;
AddressV = Clamp;
};
sampler normalSampler = sampler_state
{
Texture = (normalMap);
MagFilter = LINEAR;
MinFilter = LINEAR;
Mipfilter = LINEAR;
AddressU = Clamp;
AddressV = Clamp;
};
struct VertexShaderInput
{
float3 Position : POSITION0;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float4 ScreenPosition : TEXCOORD0;
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
//processing geometry coordinates
float4 worldPosition = mul(float4(input.Position,1), World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
output.ScreenPosition = output.Position;
return output;
}
float2 halfPixel;
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
//obtain screen position
input.ScreenPosition.xy /= input.ScreenPosition.w;
//obtain textureCoordinates corresponding to the current pixel
//the screen coordinates are in [-1,1]*[1,-1]
//the texture coordinates need to be in [0,1]*[0,1]
float2 texCoord = 0.5f * (float2(input.ScreenPosition.x,-input.ScreenPosition.y) + 1);
//allign texels to pixels
texCoord -=halfPixel;
//get normal data from the normalMap
float4 normalData = tex2D(normalSampler,texCoord);
//tranform normal back into [-1,1] range
float3 normal = 2.0f * normalData.xyz - 1.0f;
//get specular power
float specularPower = normalData.a * 255;
//get specular intensity from the colorMap
float specularIntensity = tex2D(colorSampler, texCoord).a;
//read depth
float depthVal = tex2D(depthSampler,texCoord).r;
//compute screen-space position
float4 position;
position.xy = input.ScreenPosition.xy;
position.z = depthVal;
position.w = 1.0f;
//transform to world space
position = mul(position, InvertViewProjection);
position /= position.w;
//surface-to-light vector
float3 lightVector = lightPosition - (float3)position;
//compute attenuation based on distance - linear attenuation
float attenuation = saturate(1.0f - length(lightVector)/lightRadius);
//normalize light vector
lightVector = normalize(lightVector);
//compute diffuse light
float NdL = max(0,dot(normal,lightVector));
float3 diffuseLight = NdL * Color.rgb;
//reflection vector
float3 reflectionVector = normalize(reflect(-lightVector, normal));
//camera-to-surface vector
float3 directionToCamera = normalize(cameraPosition - (float3)position);
//compute specular light
float specularLight = specularIntensity * pow( saturate(dot(reflectionVector, directionToCamera)), specularPower);
//take into account attenuation and lightIntensity.
return attenuation * lightIntensity * float4(diffuseLight.rgb,specularLight);
}
technique Technique1
{
pass Pass1
{
VertexShader = compile vs_3_0 VertexShaderFunction();
PixelShader = compile ps_3_0 PixelShaderFunction();
}
}




My wild guess basing on how light render target looks is that there may be something wrong with precision. The closer the camera the models are, the less issues are visible. The more distance the worse it looks. Did anyone have any similar issues on Android?

Hopefully you can find what’s wrong here.