Jump to content
  • Advertisement
Sign in to follow this  
piluve

Deferred,glitch rendering point lights.

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

Hello!

 

The other day I´ve been improving my deferred renderer for the university adding CookTorrance and some other pbr fanciness. I saw a glitch with the point lights. When I´m inside of the point light, the walls on the other side of the room get illuminated (which should be impossible). Lets see a picture.

 

http://i.imgur.com/HExEc5k.jpg

 

The point lights are going around the Sponza atrium and when they reach where the camera stands, I can see the walls on the other side get affected by the light. I´m having a similar problem with the curtains, as they are getting illuminated from behind.

 

I´m rendering the light volume with glCullFace(GL_FRONT);.

 

Any ideas?

As always. thanks!

 

 

 

Share this post


Link to post
Share on other sites
Advertisement

Hey!

 

I tried this:

 

if(distance(light.position,position) > light.range) discard;

 

It works, but it looks like a naive solution :S

Share this post


Link to post
Share on other sites

If you are calculating light intensity as:
intensity = 1 - ( dist(pos, light.pos) / light.range )

 

You'll start getting negative results once dist exceeds 'range', depending on how the rest of your math works out, this can cause artifacts.

You should clamp/saturate the result:
intensity = clamp( 1 - ( dist(pos, light.pos) / light.range ), 0, 1 );

 

Although, the discard solution may be more efficient, as you avoid hitting the framebuffer entirely instead of blending in a zero-strength light.
 

Depending on the precision of your render target, it may be best to do the discard last, and choose a minimum light strength that you know the render target will floor to zero, eg:
if( intensity < 1/255 ) { discard; }

 

You could also take this one step further and take into account the light color as well, since its RGB values are likely less than 1.

vec3 outColor = lightColor.rgb*intensity;

if( max( outColor.r, max( outColor.g, outColor.b ) ) < 1/255 ) { discard; }

Edited by ShaneYCG

Share this post


Link to post
Share on other sites

If you are calculating light intensity as:
intensity = 1 - ( dist(pos, light.pos) / light.range )

 

You'll start getting negative results once dist exceeds 'range', depending on how the rest of your math works out, this can cause artifacts.

You should clamp/saturate the result:
intensity = clamp( 1 - ( dist(pos, light.pos) / light.range ), 0, 1 );

 

Although, the discard solution may be more efficient, as you avoid hitting the framebuffer entirely instead of blending in a zero-strength light.
 

Depending on the precision of your render target, it may be best to do the discard last, and choose a minimum light strength that you know the render target will floor to zero, eg:
if( intensity < 1/255 ) { discard; }

 

You could also take this one step further and take into account the light color as well, since its RGB values are likely less than 1.

vec3 outColor = lightColor.rgb*intensity;

if( max( outColor.r, max( outColor.g, outColor.b ) ) < 1/255 ) { discard; }

 

I will try it an see if I can see any diferences.

Thanks.

Share this post


Link to post
Share on other sites

If you're going for PBR, doing:

intensity = clamp( 1 - ( dist(pos, light.pos) / light.range ), 0, 1 );

is probably not a good idea, the actual attenuation of light in vacuum is proportionate to squared inverse of distance so the better way of calculating intensity is:
i: The intensity of light at 1 meter.

 vec3 l = light.pos - pos;
intensity = i/(dot l,l);

where you probably have calculated l for lighting, and its size as well for normalizing, so optimize the code however you'd like.

This makes the light range quite redundant, however for an early out you might want to use it to discard the fragment which isn't that much of a brilliant idea, since the branching how ever modern the GPU is not a good idea on GPU, moreover you might need even the smallest amount of light reached to a pixel for later use on some post processing effects on HDR rendering. In conclusion I do not suggest any light omitting, but you can do it as below:

i: The intensity of light at 1 meter.

light_range = sqrt(255 * i);

On the shader:

if (length(l)<light_range)
     discard;
Edited by IYP

Share this post


Link to post
Share on other sites

 

If you're going for PBR, doing:

intensity = clamp( 1 - ( dist(pos, light.pos) / light.range ), 0, 1 );

is probably not a good idea, the actual attenuation of light in vacuum is proportionate to squared inverse of distance so the better way of calculating intensity is:
i: The intensity of light at 1 meter.

 vec3 l = light.pos - pos;
intensity = i/(dot l,l);

where you probably have calculated l for lighting, and its size as well for normalizing, so optimize the code however you'd like.

This makes the light range quite redundant, however for an early out you might want to use it to discard the fragment which isn't that much of a brilliant idea, since the branching how ever modern the GPU is not a good idea on GPU, moreover you might need even the smallest amount of light reached to a pixel for later use on some post processing effects on HDR rendering. In conclusion I do not suggest any light omitting, but you can do it as below:

i: The intensity of light at 1 meter.

light_range = sqrt(255 * i);

On the shader:

if (length(l)<light_range)
     discard;

 

Branching can be OK as long as it is mostly coherent within the warp/half warp, and for this they would be mostly coherent except for the edge of the light's effectiveness where both if/else may need to be evaluated. For deferred framebuffer b/w can be a significant bottleneck, so the branch may be worthwhile.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!