PDA

View Full Version : multi pass rendering with shadow mapping



_arts_
08-27-2011, 03:58 AM
Hello,

I am facing some issues with rendering multiple shadow maps.

All the shadow maps are rendered in two passes (one from light view and another one for both lit and shaded threw shaders).

Each shadow pass is rendered fine separately for each light. The problem arises when I have more than one light.

I can't use blending in adding mode (GL_ONE, GL_ONE). Since fragments are added, if the pass for the first light makes a lit fragment, it simply can't be darker in the other pass, this turns out.
So, I thought about using blending with multiplying colors (GL_DST_COLOR, GL_SRC_COLOR). But this didn't solve the problem either (maybe because this blending mode makes the resulted fragment to be 2*src*dst... so is twice litted).

I know there are deffered rendering methods, but for now I'd like to stay with multi-pass forward rendering.

Any hints ?

Thanks in advance.

BionicBytes
08-27-2011, 06:50 AM
I can't use blending in adding mode (GL_ONE, GL_ONE). Since fragments are added, if the pass for the first light makes a lit fragment, it simply can't be darker in the other pass, this turns out.

it's been a while since i've even had to think about forward lighting and shadowmapping. Here goes anyway.
OK, pass #1 is to calculate all the shadow maps in turn for each light (this is not necessarily the best or optimal way, but it makes explaining and thinking a bit easier).
Pass #2 is to 'apply' shadow map and lighting to the affected geometry.
Let's discuss your problem area - pass #2 - applying the shadow maps for all lights.
Let's suppose with light #1 the geometry is to be lit red (1,0,0,0) without shadow (1,1,1,1) - that means you'll render the geometry to the framebuffer and the output fragment colour will be (1,0,0,0) * (1,1,1,1) or simply red.
Now, for the next light (yellow) is also fully lit, the output fragment will be (1,1,0,0) * (1,1,1,1) or yellow; this fragment needs to be addidtvely blended onto the previous results of the light pass #1. You can either use blending (GL_ONE,GL_ONE) or use a custom shader to read the previous frame buffer whilst you write to another and ping-pong between the two.
Now a third green light may be in shadow (0,1,0,0) * (0,0,0,0) = (0,0,0,0). There is no problem in add blending this onto the current scene framebuffer just like before.
You are probably over thinking it and assume that just because a light creates a shadowed region it should darken the effects of another light which is adding light to the same area. That is not necessarily true, think of a powerful spot light illuminating an area. Now a secondary light from a different direction casts a shadow onto the spotlight lit area - what should we observe? Shadow? Light? The answer would be light, after all a shadow is simply the absene of any light contribution for any given region.

Therefore, after this long winded explaination, the answer to your question is to simply add blend each light's shadowmap/light shader.

_arts_
08-27-2011, 08:06 AM
This totally makes sense and this is what I was first thinking about it. But since my results went "wrong", I started to wonder about this.

Thanks for this.