Sign in to follow this  
BloodLust666

Deferred Lighting 2nd Pass opinion

Recommended Posts

Ok, I have the first pass for Deferred Lighting set up, and I have a basic 2nd pass shader taking the diffuse color, normal, position, and a hard coded directional light. What I'm curious on how others would implement this is how do I iterate through all lights in-game and combine them with the G-buffer? Do I create a completely separate "end-result" buffer to render to, texture a quad with that "end-result" texture and the G-buffer, iterate through all lights and use the G-buffer's contents with the current light and use the end-result texture and add that together each pass? Then lastly render the "end-result" texture to the screen? Once that step, or before, when do I calculate shadows with the shadow maps?

Share this post


Link to post
Share on other sites
Well, here's little overview of what passes I use in my deferred render engine(not all are included, overall there're around 18 passes):

[code]
1. pass: build up G-buffer
2. pass: downscale pass
3. pass: SSAO pass on downscaled pass
4. pass: shadow pass + SSAO result => G-buffer (shadowing value)
5. pass: lighting up to 50 lights based on G-buffer => color-buffer
6. pass: tonemapping for bloom + downscaling
7. pass: blur of bloom
8. pass: final composition = bloom + tonemapped color buffer
[code]

You need several render targets in different sized, but many can be reused. Most passes only use a single fullscreen quad. The lighting pass does the whole lighting in a single pass, just upload all your lights into registers and iterate through them.

Share this post


Link to post
Share on other sites
Quote:
Original post by BloodLust666
Do I create a completely separate "end-result" buffer to render to
Yes.
Quote:
, texture a quad with that "end-result" texture ... and use the end-result texture and add that together each pass?
You don't have to bind the "end-result" texture as an input, you just use additive blending when rendering your lights (so the output of your shader is automatically added to the "end result").
Quote:
Once that step, or before, when do I calculate shadows with the shadow maps?
Yeah, either render the shadow maps as you need them:
 for each light
set render target to shared shadow map
render shadow POV
set render target to "final result"
bind GBuffer and Shadow Map
render lighting
... Or render them all up-front into a lot of shadow textures
...Or you can use "Deferred Shadow Mask Generation" (max 4 shadow casters), like in CryEngine2.

Share this post


Link to post
Share on other sites
Ashaman73: Could you explain how each of those steps are done? Or at least post a reference to how those are done? I'm still really new at this whole deferred shading and any advanced shading techniques so I'm not familiar with most of those techniques.

Hodgman: So I bind to another "end-result" buffer, then use one ambient light, and iterate through all my point and spot lights and use that additive blending you mentioned? Where do I get my color from? The G-Buffer from the diffuse frame?

Share this post


Link to post
Share on other sites
The beginning steps are really these:

Write to GBuffer. You'll need at least position (or depth) and normals, and depending on technique, you may need the albedo (diffuse color ) of the objects.

The next pass is the light accumulation pass. Here you bind your GBuffer data as textures and any shadow data. Then you render the geometry of the light (all can be full screen quads or you can use tighter bounding methods) to additively blend your lights using the GBuffer data to calculate shading and what not. When rendering your lights, you send the parameters of the light like diffuse color for it to use just like you would render any other object. Run through all your lights.

If you don't require any more passes such as post processing, the light accumulation pass can just be on the back buffer (which will be displayed without anything extra). If you do, then you'll have to create a light pass buffer to do all the rendering to. Then you would render a full screen quad to the back buffer and use the light pass data as a texture.

Share this post


Link to post
Share on other sites
I've gotten everything to work up to the light accumulation point. It seems that when I set the blend mode to (one, one), some of my geometry looks as if it is transparent and I can see geometry that is supposed to be behind others. Am I right in using (one, one)? Or is it something else?

Here's my light accumulation shader


varying vec2 texCoord;

// geometry
uniform sampler2D textureDiffuse;
uniform sampler2D textureNormal;
uniform sampler2D texturePosition;

// light
uniform int lightType;
uniform vec3 lightPos;
uniform vec4 lightAmbient;
uniform vec4 lightDiffuse;
uniform float lightConstant;
uniform float lightLinear;
uniform float lightQuadradic;
uniform float lightRadius;

// camera
uniform vec3 cameraPosition;

vec3 lightDir;
vec3 lightDist;

float Idiff = 0.0;
vec4 Iamb;

void main (void)
{
// flip
vec2 flipped = texCoord;
flipped.y = 1.0 - flipped.y;

vec4 color = texture2D(textureDiffuse, flipped );
vec3 normal = normalize(texture2D( textureNormal, flipped ).xyz);
vec3 position = texture2D(texturePosition, flipped ).xyz;
vec3 eyeDir = normalize( - position);

Iamb = lightAmbient * color;

if ( lightType == 1 ) // directional
{
lightDir = normalize(lightPos);
Idiff = max(dot(normal,lightDir),0.0);
}
else if ( lightType == 2 ) // positional
{
lightDist = lightPos - position;
if ( length(lightDist) < lightRadius )
Idiff = lightDiffuse / ( lightConstant + lightLinear*lightDist + lightQuadradic*lightDist*lightDist );
}

gl_FragColor = Idiff*color + Iamb;
}


Maybe my shader is wrong?

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