• Advertisement
Sign in to follow this  

Point light not lighting entire area inside bounding sphere?

This topic is 2995 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a deferred renderer that draws a 100x100 quadrangle with a normal of (0,1,0). The problem is when I try lighting the surface with a point light, only the area at the front of the point light is lit. Point Light Problem I'm think I have narrowed it down to the pixel shader in my HLSL code:
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
	// Obtain screen position    
	input.ScreenPosition.xy /= input.ScreenPosition.w;
	// Get the textureCoordinates corresponding to the current pixel
	// Convert from [-1, 1] [1, -1] to [0, 0] [1, 1]
	float2 texCoord = 0.5f * (float2(input.ScreenPosition.x, -input.ScreenPosition.y) + 1);
	// Allign texels to pixels (DX9)
	texCoord -= HalfPixel;
	// Get normal data from the normal map
	float4 normalData = tex2D(NormalSampler, texCoord);
	// Transform normal back into [-1, 1] range
	float3 normal = 2.0f * normalData.xyz - 1.0f;
	// Get specular power
	float specularPower = normalData.a * 255;
	// Get the specular intensity (from colourMap)
	float specularIntensity = tex2D(ColourSampler, texCoord).a;
	// Get 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, InvViewProjection);
	position /= position.w;
	// Surface to light vector
	float3 lightVector = LightPosition - position;
	// Compute attenuation based on distance from centre of sphere - linear attenuation
	float attenuation = saturate(1.0f - length(lightVector)/LightRadius);
	// Normalise light vector (can't do this until after length value has been used otherwise length will be incorrect)
	lightVector = normalize(lightVector);
	// Compute diffuse light
	float NdL = max(0, dot(normal, lightVector));
	float3 diffuseLight = NdL * Colour.rgb;
	// Reflection vector of light ray
	float3 reflectionVector = normalize(reflect(-lightVector, normal));
	// Camera to surface vector
	float3 directionToCamera = normalize(CameraPosition - position);
	// Compute specular light
	float specularLight = specularIntensity * pow(saturate(dot(reflectionVector, directionToCamera)), specularPower);
	// Now take into account attenuation and intensity of the light
	return attenuation * LightIntensity * float4(diffuseLight.rgb, specularLight);

If I change the line: // Compute diffuse light float NdL = max(0, dot(normal, lightVector)); to // Compute diffuse light float NdL = 1; then the whole are is lit. Can anyone please tell me what I have done wrong here or why this is happening? Thank you.

Share this post

Link to post
Share on other sites

What is halfPixel?
Perhaps you have it as 0.5f, though it should be 0.5f/width.

It is used to correctly match the texels to pixels in DirectX9.

It is found using:

// Get the sizes of the backbuffer, in order to have matching render targets
int backBufferWidth = graphics_Device.PresentationParameters.BackBufferWidth;
int backBufferHeight = graphics_Device.PresentationParameters.BackBufferHeight;

pixel_Half.X = 0.5f / backBufferWidth;
pixel_Half.Y = 0.5f / backBufferHeight;

When commented out it makes no difference to the problem I am having.

Share this post

Link to post
Share on other sites
Output your 3D position as the colour, screenshot, output your 3D normal as the colour, screenshot. Post. I bet one of them is in the wrong space when you compute the dot product.

Share this post

Link to post
Share on other sites
Um, normals and depth look completely wrong to me.

Output .rgb as your final normal .xyz (.a can just be 1), and output .rgb as your final position .xyz (.a can be just 1 again). Position should have some nice yellow/red/black/green/etc. corresponding to the world axises and normals should have some nice red/green/blue corresponding to the world normals.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement