Need help setup light volume for deferred shading

Started by
18 comments, last by B_old 14 years, 8 months ago
Hey Dragon,

Sorry, I mess up with the formula. The right one is :

Att = 1 / ( attFactor * d^2 )

Regarding your suggestion, what I want to do is to limit the light range into some pre-define radius, not calculate the light range. Let say right now I have a light with range = 15.0f . Now, I want to calculate the Att so that when I multiply it with the overall light intensity, the light range can be limited to any range that I set, let say 5.0f.

I'm thinking of reducing the intensity of the light source with regards to the pre-defined Range, but haven't figure out a formula yet.
Advertisement
The formula is exactly the formula you have for attenuation:

Att = 1 / ( attFactor * d^2 )

If you want the light to have Att of 0.01 at d = 5, then solve for attFactor:

0.01 = 1 / ( attFactor * 5^2 )

0.01 = 1 / ( x * 5^2 )

0.01 = 1 / 25x

0.25x = 1

x = 1 / 0.25

x = 4
Hi Dragon,

Stupid me you are right! I got that formula before and it worked great with Range = 5.0f. However, when I tested Range = 10.0f, the light with Att covered more area than the light without it did. Let me show you some screen shot ( btw do you know how I can load the pictures straight in here instead of posting a link? ):

First is the light without att:

http://img199.imageshack.us/img199/1939/pointlightwithoutatt.jpg

Second is the light with att:

http://img190.imageshack.us/img190/1482/pointlightwithatt.jpg


Notice how the light with att covers some pillars that the light without att doesn't. I figure this is because of the 1% (0.01) of the light intensity falloff at d = 10.0f.

So now I think I will try to scale the light intensity with regards to the light range, since that would be more physically correct. Again, I calculate the overall lighting like this:

vIntensity = (spec + diffuse) * pointLight.intensity * att; ( with att = 1 / ( factor * d^2 )

Now how should I relate pointLight.intensity and some pre-define Range? All help is greatly appreciated.
sorry, I don't understand what you mean by "with att" and "without att", and can't easily see the difference between the images that you're trying to point out
Hi Dragon,

My bad, let me try it again. I think I used the wrong words here. Ok, from the beginning, I calculate my overall light light this:

float attenuation = 1 / ( d^2 );            // My old formulaif( fDistance <= Range )   // This is just to see the range that the light is supposed to cover   light += (spec + diffuse) * pointLight.intensity * att;


Then, later, using your formula, the lighting calculation become this:

float factor      = 100.0f / ( Range^2 );   // This is your formulafloat attenuation = 1 / ( factor * d^2 );  light += (spec + diffuse) * pointLight.intensity * att;


Now, it works great with Range = 5.0f. But when I test it with Range = 10.0f, I notice that the light with your formula covers more area than the light with my old formula. I added some ambient light so it's easier for you to see:

First is light with my old formula:

http://img9.imageshack.us/img9/1661/lightpointwithoutusingf.jpg

Second is the light with your formula:

http://img27.imageshack.us/img27/5451/lightpointusingformula.jpg

I can see them clearly on my screen, but maybe your screen is darker than mine. Please let me know if that's the case, I will increase the light intensity more so you can see.

Notice how the light with your formula cover some pillar (you can tell by look at the specular light), while light with my formula doesn't. Like I said, I figure this is because of the 1% (0.01) of the light intensity falloff at d = 10.0f.

So I think I will try to scale the light intensity with regards to the light range, since that would be more physically correct. Now I'm working on a formula to relate them. Any thoughts on this? Thanks.
Sorry, what's the problem? The first image you show has a noticeable bad artifact (the hard line where the light stops abruptly) whereas the 2nd looks correct.

One method is to calculate the range based on the light intensity and falloff, but you asked for how to modify the falloff based on a constant range.

Both approaches are probably useful for an artist. Also useful is specifying a combination of a linear falloff and a quadratic one, for more artistic control. Calculating the range based on this or keeping the range constant and affecting the falloff are probably both useful in that situation, too.

It all depends on who's doing the lighting and what they feel is the most natural and productive way to specify lighting.

Remember that games can be art, you don't have to always strictly follow real-world rules. Sometimes real life isn't aesthetically pleasing, too. If it looks cool, you're good.
Hey Dragon,

I think you're right. I shouldn't spend the whole day trying to figure out the correct formula, just to realize it didn't look good in my application. I will just use formula from b_Old with some twist. Thanks for all the posters who reply.

So I'll read on more about the next step in deferred shading regards the light volume. I remember for a point light I will draw a sphere which represent the light volume. Is it possible to have a .X sphere with radius = 1.0f and then just scale it according to pre-defined Range ? I know how to create a .X sphere but I don't know how to scale it in DirectX. Any suggestion? Thanks.
Yes, that is possible. In theory a mesh of a sphere with radius 1 will probably not cover the exactly same space as a perfect sphere with radius 1. This probably won't be noticeable though if you use attenuation, depending on the tessellation of the sphere.
And scaling it is very easy. You pass a world matrix to the shader now before you draw your sphere, right? Just scale it to whatever size you need.
Hi,

Ok so I got the scaling for the sphere. Now, I read from a thread that for each light you should do this:

l-pass, for each light do:
- if camera lies outside the light volume
- render front faces of the light volume and mask them out in the stencil buffer;
- render back faces of the light volume comparing to stencil
- if camera lies inside the light volume
- render back faces of the light volume (ignore stenciling)

I don't quite get the process. How do I mask out front face of the light volume in stencil ? What does it mean to "render back faces of the light volume comparing to stencil" ? Is it the right way to do it ? Thanks.

I was actually hoping that someone else would answer this question for you, as I haven't thought about the stencil optimization a lot yet. But I believe I can you some hints.

First for the case inside the light volume:
You render the lightvolume, but instead of culling back-faces as most of the time you cull the front-faces. (Otherwise you would not see anything as you are inside the lightvolume.) You also set the depth-comparison to Greater-Equal.
That way the volume (and thus the light) will only get drawn in areas that are closer to you than the edge of the light volume which can save some time compared to just drawing a fullscreen quad.

The case where you are outside the light volume:
You render lightvolume with backface culling and depth-comparsion to Less-Equal. That way you get occlusion culling in case the light is behind a wall or something. While drawing you don't do the lighting yet but only write a certain value to the stencil buffer.
Now you do the same as for the first case. But you also check for the stencil value you just wrote for the buffer. That way you have both optimizations.

I am not entirely sure about the latter case, as I don't do the second stencil part yet. But I believe it works something like that.

What I wonder is, whether it is OK to increase the stencil value and in the first pass and then decrease in the second pass and assume that all the stencil values are exactly the same as before (no more, no less).

EDIT: I just realized you wanted to know what about stencil operations specifically. You have to have a stencil buffer and enable stencil operations. Than you can specify which stencil value to set if a pixel is drawn (or not) and which stencil value it has to be compared to before it is drawn. There surely is some tutorial around that can explain this better than me.

This topic is closed to new replies.

Advertisement