Need help setup light volume for deferred shading

Started by
18 comments, last by B_old 14 years, 8 months ago
Hi guys, So I want to implement deferred shading, since it's very popular now and I think I should know how to do it :D. Anyway, I read around and realize that before doing deferred shading, I need to setup some light volume for my lighting. Ok, so I read the 6800 Leagues and it said: - Render convex bounding geometry: * Spot light = cone * Point light = sphere * Directional light = quad or box I understand that for a point light, I'll draw a sphere that represent its lighting area of effect, and use it to optimize a bunch of stuff. However, that's all I know. I have no idea on how to actually do it. I mean, I can draw a sphere which has origin right at the point light location, but how do I determine the range of the point light and hence calculate the sphere radius ? Right now my pointlight looks something like this:

struct PointLight
{
   D3DXCOLOR ambient;
   D3DXCOLOR diffuse;
   D3DXCOLOR spec;
   float intensity;
   D3DXVECTOR4 posWorld;         // Position in world space
   D3DXVECTOR4 posWorldView;     // Position in view space, since I do lighting calculation in view-space
};

All helps will be greatly appreciated.
Advertisement
You can give your pointlight any range you like. In the shader you can than make it so that the light faints away as it approaches the limits of the range, if you know what I mean. Its usually referred to as attenuation.
Just pick any reasonable range you like for now and go from there.

I am wondering what you do with the ambient color in the point light, though?
Hi,

For the point-light ambient, honestly I teach myself DirectX through books and online tutorials. So I built my lighting system bases on a model where ambient is calculated like this:

ambient = light.ambient * material.ambient;

The above model was built for a directional light, so I guess for point-light I don't need it. Anyway, now for the point light, my HLSL code is like this:

... Calculating diffuse and spec// Scale according to distance from the lightfloat fDistance = distance(g_aPointLight[iLight].posWorldView, ViewPosition);// Final intensity of lightvIntensity += (fDiffuse + fSpecular) * g_aPointLight[iLight].intensity / (fDistance * fDistance);


I'm doing lighting calculation in view-space, and I do have attenuation by just divide the intensity over square of distance from light to the pixel. Now, let say I call fRange is the radius of the sphere that represents my light affecting area, how do I relate it to the lighting calculation ? I tried something like this:

if( fDistance <= fRange ) // I put fRange = 5.0f   vIntensity += (fDiffuse + fSpecular) * g_aPointLight[iLight].intensity / (fDistance * fDistance);


but ofcourse it will give me sharp edge between distance smaller than 5.0f and distance larger than 5.0f. I took a picture:

http://img256.imageshack.us/img256/9544/pointlight.jpg

So any thought on how I should do it ? Thanks.
Hm. Something you could try to see if it works is this:

float3 lightVec = g_aPointLight[iLight].posWorldView - ViewPosition;lightVec /= fRange; float att = max(1.f - dot(lightVec, lightVec), 0.f);	//multiply att with your diffuse and see what you get, no if ()


Regarding the ambient light I would suggest that you have one global value that gets applied exactly once to every surface regardless of the other lights. Otherwise materials suddenly get lighter once you introduce several lights although they might only be influenced by one or less lights.

[Edited by - B_old on August 16, 2009 1:25:45 AM]
Hi,

Thanks for the reply. I follow your suggest but not sure if I get it right:

float3 lightVec = g_aPointLight[iLight].posWorldView - ViewPosition;		lightVec /= 5.0f; // I just choose the range = 5.0f for now		float att = max(1.0f - dot(lightVec, lightVec), 0.0f);		//if(fDistance <= 15.0f)vIntensity += (fDiffuse + fSpecular) * g_aPointLight[iLight].intensity * att / (fDistance * fDistance);


Did I do it right? Because for small range value ( < 10.0f ), the area cover by the light with and without using the "att" formula are relatively close. However, let say I increase the range to 15.0f, now the light without the "att" formula will cover larger area than the light with "att" formula ( I would say the difference is somewhere between 15-20% ). Any thought on this ? Thanks.
Hi,

try this:
vIntensity += (fDiffuse + fSpecular) * g_aPointLight[iLight].intensity * att;

Does it work any better?
Out of curiosity, how is vIntensity calculated further up?
Hey B_old,

Well, that formula wouldn't work better because without dividing the vItensity by (fDistance * fDistance), the light won't fade away at distance far from the point light source. The vItensity is just multiplied by the color from texture map after the calculation.
Hm. The att term just do just what you are describing. It works for me and a few others I assume, as I didn't come up with it. Can you maybe show another screenshot of whats going on?
Hey b_Old,

Don't get me wrong that the formula doesn't work. It works, but like I said, only with small range radius. With larger range radius, the lights start to show differences in the range they cover.

I read on MSDN and see that attenuation is calculated like this:

Att = 1 / (att0 + att1 * d + att2 * d^2)

I guess I don't need att0 and att1, so I just simplify it into:

Att = 1 / ( att2 * d^2 )

with att2 is the attenuation quadratic factor. Now, I need to figure out this att2 factor so that Att will be close to 0.0 (no light) when d gets close to the Range. Also, Att has to be close 1 ( full light ) for those d that close to the light source. Any suggestion ?

[Edited by - b_thangvn on August 16, 2009 2:57:07 PM]
Att = att2 * d^2

att2 is a property of the light that you set.

if you want to compute how big the bounding volume of the light should be, solve for d when Att = 0.01 or some other number small enough that eliminates the hard edge

This topic is closed to new replies.

Advertisement