Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm starting out with GLSL and I've implemented simple deferred shading that outputs G-buffer with positions, normals and albedo.

I've also written a simple point light shader.

Now I draw a sphere for the point light and output goes into a lighting buffer.

The problem is, how do I combine the results of lighting buffer when drawing multiple lights?

E.g. when I'm drawing the second light to the lightbuffer using the point light shader, how do I add first light to the second light in the lighting buffer. I mean, you can't read from and write to the same output buffer?

share|improve this question

3 Answers 3

up vote 12 down vote accepted

Additive blending, i.e. glBlendFunc(GL_ONE, GL_ONE) and glEnable(GL_BLEND).

share|improve this answer
does depth testing have to be disabled for this? –  woojoo666 2 days ago
@woojoo666 No. In fact it should be enabled with the depth test set to less-equal, so that surfaces that precisely match the previous pass will go through. If the depth test is off, then surfaces will incorrectly accumulate light from whatever's behind them. :) –  Nathan Reed yesterday
hmm, it seems like thats exactly whats happening though. turning blending on makes front faces blend with back faces, even though I kept depth testing enabled. do I need to do something with the depth mask as well? –  woojoo666 16 hours ago
did a bit more testing, seems like draw order matters (drawing front-to-back makes depth-testing work correctly and blend only happens if faces are equiplanar, back-to-front makes everything blend together). Is there a way to do this without sorting everything? –  woojoo666 7 hours ago
I found a possible solution...I do a first pass with blending disabled, drawing all objects as black with no light source, and after that I turn additive blending on and render the contributions of each light source (kind of like how for transparency, transparent objects have to be drawn at the end, after opaque objects) –  woojoo666 6 hours ago

For my deferred renderer, I aggregate all the lights into one light render target using the information from the g-buffer and then sample that render target for light intensity while creating my final backbuffer image.

So basically, I run all my game geometry through my geometry pass to build the g-buffers. From there I feed the g-buffers to my light pass shader. Each light is ran through the pass using a full screen quad. This way my pixel shader can calculate the light intensity for all the visible surfaces from the g-buffer and then add them to the light render target. You simply just add the light intensity for each light to the light buffer but make sure you clamp the intensity from 0 to 1.

All you would need to do to handle different types of lights (point, spotlight, parallel) is to make the light pass more robust by possibly using a constant buffer to designate which lighting procedures to execute.

share|improve this answer
Yeah, and the question is - how do you add to the light render target? Using alpha blending as Nathan Reed suggested? Because as far as i know you can't read from and write to the same output buffer (which is the light buffer in this case). –  JBeurer Mar 13 '12 at 0:07
Oops, yeah. I let the output merger handle that with additive blending. When sampling for the final image is when you want to clamp the value to one which works for me as the maximum possible light intensity a surface can receive. From there you can just scale your lights as needed. –  KlashnikovKid Mar 13 '12 at 19:59
How do you handle cases where a light is behind a wall and should not light up things on the other side of the wall? –  PsychoDad Apr 11 '13 at 19:18

There is likely a better answer than this, but I know, if in your shader you repeat the code needed to do a second light, you can then process two lights on a single object instead of one. It does require droubling up a lot of code for the second light and seams a little redundant, but I know it does work. However, I do believe, as someone will hopefully point out for you, there might be a more elegant solution.

share|improve this answer
No, that doesn't work that way. I draw a sphere for each point light. Unless the second point light lies withing the sphere of influence of the first light, the second light simply wont be drawn. Your method would work if I draw a fullscreen quad for all the pointlights, however, that is not the correct approach because fullscreen quads are used for global ilumination. Say I have 16 small point lights, that would force me to go through them for each pixel even if the pixel is not lit by it. And usually I'd say each pixel is lit by a one or two lights. And what if i have 100 lights? NO –  JBeurer Mar 12 '12 at 23:58
The main reason I stated this, is if you are using only two or a few lights, it can help. Especially if you are rending many object, using a blend means you need to redraw the scene for each light, so if you have a a lot of shapes, say one million, or ten million or a billion, each draw costs a lot more to do. Doing it in the shader causes issues if you want lots of lights, but blend causes issues if you want lots of shapes. If you have lots of both, you need to find a middle ground, but usually you have a few lights and lots of objects in games. –  Kreutzwj Mar 15 '12 at 22:27
Nope, deferred shading doesn't work that way. I have to draw the scene only once and store relevant information in G-Buffer. Then a sphere of influence for each light and blend it with the light buffer. And finally combining light buffer with colorbuffer I get the final shaded color buffer. The amount of lighting computations doesn't depend on scene complexity. That is the main advantage of deferred shading in the first place. –  JBeurer Mar 15 '12 at 22:56
Ah, that make a lot more sense and would considerable better. –  Kreutzwj Mar 15 '12 at 23:07

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.