Deferred Lighting 2nd Pass opinion
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?
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):
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
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.
Quote:Original post by BloodLust666Yes.
Do I create a completely separate "end-result" buffer to render to
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.
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?
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?
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.
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.
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
Maybe my shader is wrong?
Here's my light accumulation shader
varying vec2 texCoord;// geometryuniform sampler2D textureDiffuse;uniform sampler2D textureNormal;uniform sampler2D texturePosition;// lightuniform int lightType;uniform vec3 lightPos;uniform vec4 lightAmbient;uniform vec4 lightDiffuse;uniform float lightConstant;uniform float lightLinear;uniform float lightQuadradic;uniform float lightRadius;// camerauniform 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?
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement