Jump to content
  • Advertisement
Sign in to follow this  
enigmagame

Deferred Shading: point light and bounding volume

This topic is 2596 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'm implementing a simple deferred shading demo in DirectX11, taking inspiration from some know papers and this tutorial made for XNA.
Below you can see three screanshot of the demo, taken in three different modes, and the problem that I've is on the third mode:
1) Standard rendering
2) Deferred rendering, for each light a full screen pass is made. In this mode I obtains a frame rate more slow than standard rendering.

mgdexample1020110507235.th.png

3) Deferred rendering, for each light I define a bounding volume (sphere), and I computes the illumination only on the geometry that is in this volume. But the result is horrible.

mgdexample1020110507235.th.png

So the question is: where is the problem? What I'm doing is wrong?
Thanks.

Share this post


Link to post
Share on other sites
Advertisement
You'll need to apply an attenuation to the lighting that takes into consideration the size of the bounding sphere.
So the lighting won't appear to be "clipped", it will gradually fade out.

Share this post


Link to post
Share on other sites

You'll need to apply an attenuation to the lighting that takes into consideration the size of the bounding sphere.
So the lighting won't appear to be "clipped", it will gradually fade out.


I'm doing that but the result is the same, this is a piece of the PS (a very similar code is present on the tutorial that I've linked):



// Attenuation
float fAtten = 1.0 / dot(Attenuation, float3(1, lightDist, lightDist * lightDist));


// Diffuse
output += max(0, (lightColor * dot(float4(normal, 1.f), lightDir) * fAtten));

// Specular
output += max(0, (lightColor * specularIntensity * pow(dot(float4(normal, 1.f), halfAngle), specularPower) * fAtten));

float volumeAttenuation = saturate(1.0f - lightDist / lightRadius);

return output * volumeAttenuation;

Share this post


Link to post
Share on other sites




// Attenuation
float fAtten = 1.0 / dot(Attenuation, float3(1, lightDist, lightDist * lightDist));


// Diffuse
output += max(0, (lightColor * dot(float4(normal, 1.f), lightDir) * fAtten));

// Specular
output += max(0, (lightColor * specularIntensity * pow(dot(float4(normal, 1.f), halfAngle), specularPower) * fAtten));

float volumeAttenuation = saturate(1.0f - lightDist / lightRadius);

return output * volumeAttenuation;



I can only guess that your lightRadius value is too large, though this shouldn't be the case. Have you tried scaling it to see the effect it has?

Share this post


Link to post
Share on other sites

I can only guess that your lightRadius value is too large, though this shouldn't be the case. Have you tried scaling it to see the effect it has?


I'll show you two example:
- This with a lightRadius of 0.5f
mgdexample1020110508004.th.png]

- This with a lightRadius of 50.f
mgdexample1020110508004.th.png


Maybe there's also a blending problem?

Share this post


Link to post
Share on other sites

[quote name='MajorTom' timestamp='1304808032' post='4807831']
I can only guess that your lightRadius value is too large, though this shouldn't be the case. Have you tried scaling it to see the effect it has?


I'll show you two example:
- This with a lightRadius of 0.5f
mgdexample1020110508004.th.png]

- This with a lightRadius of 50.f
mgdexample1020110508004.th.png


Maybe there's also a blending problem?
[/quote]

It doesn't appear to be a blending problem. Try scaling the value in the shader i.e lightRadius*0.1f. Rather than scaling the geometry.
This might tell us if there's an issue with the attenuation code. It does seem a little odd though.

Are you applying the ambient lighting term for each light source? This would cause sharp edges also, as it's a constant value.
This should either be a single fullscreen pass or the colour used when clearing the render target. Just an idea.

Share this post


Link to post
Share on other sites
I've tried to use the same PS code presented in the tutorial that I've linked in the first post, this is the code:



float4 PS(VS_OUTPUT input) : SV_TARGET0
{
//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);
//get normal data from the normalMap
float4 normalData = normalTexture.Sample(pointSampler, 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 = colorTexture.Sample(linearSampler, texCoord).a;
//read depth
float depthVal = depthTexture.Sample(pointSampler, 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 - 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 - 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);
}



and this is a result with a radius of 15.f:

mgdexample1020110508105.th.png

I think that this code have some problems, and the attenuation is not correct. Some suggestions?
Thanks.

Edit: If you watch the screenshot you can see that the columns at the bottom have the same light intensity applied.

Share this post


Link to post
Share on other sites
Attenuation is supposed to have 3-components rather than 1 like you do it.

float fAtten = 1.0/dot(LightAttenuation, float4(1, fLightDist, fLightDist*fLightDist,0));

Thats how I'm doing it, and I get nice results. You have to try around a bit, but basically you set LightAtenuation in your application as a 4-component-vector, and set the 4th component to 0. But playing around with the other components will give you the effect that you want. Have a read here: MSDN

Share this post


Link to post
Share on other sites

Attenuation is supposed to have 3-components rather than 1 like you do it.

float fAtten = 1.0/dot(LightAttenuation, float4(1, fLightDist, fLightDist*fLightDist,0));

Thats how I'm doing it, and I get nice results. You have to try around a bit, but basically you set LightAtenuation in your application as a 4-component-vector, and set the 4th component to 0. But playing around with the other components will give you the effect that you want. Have a read here: MSDN


Yes, it's true. Infact in my past code I've used the formula that you've posted.
With this the attenuation works fine (as you can see in the screenshot), but I've the same cutting edge effect. How can I solve that? I must tune the attenuation parameters?

mgdexample1020110508113.th.png

Share this post


Link to post
Share on other sites
What is the relationship between [font=CourierNew, monospace][size=2]lightDist[/font] and the size of the sphere exactly?

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!