Jump to content
  • Advertisement
Sign in to follow this  

[Solved]Deferred Rendering - Point lights only half shaded?

This topic is 2137 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

Hey everyone,


Still working on my deferred renderer and have everything working for my point lights except it seems that only half of the point lights are being properly lit.  Hopefully the attached image will show the problem I'm facing.


Now the first thing that I can think of is that it maybe my normals are getting corrupted between when I draw my scene and when I do the lighting calculations?  The reason I think this is because I have to convert the normals from the [-1, 1] range to the [0, 1] range before I render them to my normal render target (in the "scene" shader) and then back into the [-1, 1] range when I perform my lighting calculations in the light shader.


I did some searching and it looks like I have the same issue as http://www.gamedev.net/topic/627587-solved-pointlight-renders-as-halfsphere/ but that thread was never updated with what the actual solution/problem was.


I've looked at my shader code and my render target format for my normals yesterday and this evening and haven't been able to figure it out and was hoping someone could lend a second set of eyes over some of my code.

Normal Render Target Creation Parameters:

ID3D11Texture2D* text;
desc.MipLevels = 1; 
desc.ArraySize = 1;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
desc.Format = DXGI_FORMAT_R8G8B8A8_SNORM;
desc.Width = width;
desc.Height = height;
"Scene" Shader:

// Vertex shader code that outputs the normal in world space
output.Normal = normalMap.SampleLevel(samplerStateLinear, output.UVCoords, 0.0f).xyz;
output.Normal = mul(output.Normal, World);

// Pixel shader code that transforms the normals to [0, 1] domain and then stores in the render target
// transform the normal domain
output.Normal = input.Normal;
output.Normal = 0.5f * (normalize(output.Normal) + 1.0f);
Light Pixel Shader:

float4 PSMain(VS_OUTPUT input) : SV_Target
	input.ScreenPosition.xy /= input.ScreenPosition.w;
	float2 texCoord = 0.5f * (float2(input.ScreenPosition.x, -input.ScreenPosition.y) + 1);

        // read normal data from normal RT
	float4 normalData = normaltex.Sample(samplerStateLinear, texCoord);
        // map back to [-1, 1] range and normalize
	float3 normal = 2.0f * normalData.xyz - 1.0f;
	normal = normalize(normal);

	float depthVal = depthtex.Sample(samplerStateLinear, texCoord).r;

	float4 position;
	position.xy = input.ScreenPosition.xy;
	position.z = depthVal;
	position.w = 1.0f;

	position = mul(position, InvViewProjection);
	position /= position.w;

	float3 lightVector = lightPosition.xyz - position;
	float attenuation = saturate(1.0f - length(lightVector)/lightRadius.x);

        // calculate the dot product of surface normal and light vec
	lightVector = normalize(lightVector);
	float dp = dot(lightVector, normal);

	float3 diffuseLighting = lightColor.xyz * dp;

	return float4(diffuseLighting, 1.0f) * attenuation * lightIntensity;

Thank you for any help/thoughts you might have.

Share this post

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

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!