Sign in to follow this  
wquist

Deferred Shading

Recommended Posts

Hi,

I've been trying to get a deferred renderer working. I have the deferred part working, and I can store all the info in a G-Buffer, etc. However, I'm having some problems with the lighting step. I'm doing this on a mac, so I checked out the WWDC10 deferred shading example. I got lights working, but they seem to be infinite, i.e. no matter how far away the light is, the geometry is still lit. Is there a way to make lights only affect a certain distance around them? Here's the light shader code I'm using:
[code] // Fragment shader
uniform sampler2D normalTex, posTex, colorTex;

uniform vec3 light1Pos;

uniform vec3 light1Color;

uniform vec3 light2Pos;

uniform vec3 light2Color;

uniform vec3 light3Pos;

uniform vec3 light3Color;

uniform vec3 light4Pos;

uniform vec3 light4Color;




void main()

{

vec4 color = texture2D(colorTex, gl_TexCoord[0].xy);



if (color.a < 0.00001)

{

discard;

}



vec2 norm = texture2D(normalTex, gl_TexCoord[0].xy).xy;

vec3 normal = vec3(norm.xy, 0.0);

normal.z = sqrt(1.0 - norm.x * norm.x - norm.y * norm.y);



vec3 position = texture2D(posTex, gl_TexCoord[0].xy).xyz;

vec3 view = normalize(-position);



vec3 l1 = normalize(light1Pos - position);

float atten1 = max(0.0, dot(l1, normal));

vec3 reflectv1 = normalize(reflect(-l1, normal));

float spec1 = max(dot(reflectv1, view), 0.0);



vec3 l2 = normalize(light2Pos - position);

float atten2 = max(0.0, dot(l2, normal));

vec3 reflectv2 = normalize(reflect(-l2, normal));

float spec2 = max(dot(reflectv2, view), 0.0);



vec3 l3 = normalize(light3Pos - position);

float atten3 = max(0.0, dot(l3, normal));

vec3 reflectv3 = normalize(reflect(-l3, normal));

float spec3 = max(dot(reflectv3, view), 0.0);



vec3 l4 = normalize(light4Pos - position);

float atten4 = max(0.0, dot(l4, normal));

vec3 reflectv4 = normalize(reflect(-l4, normal));

float spec4 = max(dot(reflectv4, view), 0.0);



gl_FragColor = color +

(vec4(min(pow(spec1, 32.0) + atten1 * light1Color, 1.0), 1) +

vec4(min(pow(spec2, 32.0) + atten2 * light2Color, 1.0), 1) +

vec4(min(pow(spec3, 32.0) + atten3 * light3Color, 1.0), 1) +

vec4(min(pow(spec4, 32.0) + atten4 * light4Color, 1.0), 1));
}

// Vertex shader
void main()

{

gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;

gl_TexCoord[0] = gl_MultiTexCoord0;
}[/code]

Thanks :)

Share this post


Link to post
Share on other sites
From what I can tell, it looks like you're using point lights without attenuation. I recently converted Catalin Zima's deferred rendering tutorial from XNA to DirectX9:

[url="http://www.catalinzima.com/tutorials/deferred-rendering-in-xna/"]http://www.catalinzi...ndering-in-xna/[/url]

and attenuation for point lights is computed like this (in HLSL):

[color="#4E4E4E"][size="2"]float attenuation = saturate(1.0f - length(lightVector)/lightRadius);[/size][/color]
[color="#4E4E4E"] [/color]
[color="#4E4E4E"] [/color]
[size="2"][color="#4E4E4E"][color=#000000][size=3]EDIT: one optimization used for point lights is to draw a sphere scaled to your light radius, instead of drawing a full screen quad. You can find this info in C. Zima's tutorial.[/size][/color][/color][/size]

Share this post


Link to post
Share on other sites
Thanks - I think that will be very helpful. The HLSL code is quite different than GLSL, though, but I think I get the concept. Also, in the Apple source from my first post, what do the 'atten' variables do if they aren't really calculating attenuation?

Share this post


Link to post
Share on other sites
[quote name='wquist' timestamp='1311189919' post='4838106']
Thanks - I think that will be very helpful. The HLSL code is quite different than GLSL, though, but I think I get the concept. Also, in the Apple source from my first post, what do the 'atten' variables do if they aren't really calculating attenuation?
[/quote]

Those 'atten' variables are calculating the dot product between the surface normal and the light vector. Basically, this calculation makes sure that if a surface faces away from the light, it will be lit less or not lit at all.But for point lights you also need to take into account attenuation due to the point light radius which is what I think you want.

EDIT: the saturate function can be translated to GLSL as: "clamp(value, 0.0, 1.0)"

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this