PDA

View Full Version : Shadow Mapping - merging textures



CarlBateman
12-21-2011, 02:39 AM
ok, (moving on from my previous post) I'm adding shadows to a OpenGL 2.1 (without shaders) project using the Shadow Mapping method outlined in Paul's Projects (http://www.paulsprojects.net/tutorials/smt/smt.html).

All well and good, but I have several problems, in particular, with multiple light sources and multi-directional light, I can't work out how generate and merge multiple textures/frame buffers. Any pointers?

Thanks in advance.

Carl

Alfonse Reinheart
12-21-2011, 09:37 AM
Why are you trying to merge multiple shadow maps?

Having multiple shadow maps works just the same as one. You just do the same thing, multiple times.

Dark Photon
12-24-2011, 08:30 AM
...and multi-directional light
I assume you mean an omnidirectional point light source.

Cube shadow maps are often used for these. Check the archives for details and code.

CarlBateman
01-02-2012, 03:54 AM
Apologies for the delay, I was ill over Christmas and had limited computer access. Anyway...

Why are you trying to merge multiple shadow maps?I'm trying to simulate multiple light sources.


Having multiple shadow maps works just the same as one. You just do the same thing, multiple times. I was hoping for a bit detail than that. Don't I need to do some accumulation, at least?


I assume you mean an omnidirectional point light source.
Yes, I probably do. Not 100% on the terminology.


Cube shadow maps are often used for these. Check the archives for details and code. I'll look into that. Thanks.

Carl

remdul
01-03-2012, 12:55 AM
What Alfonse means is that you should loop through the light sources in your GLSL shader when drawing the shadow receiver. Compute the lighting (N dot L etc) and sample the per-light source shadow depth map.
Each light source contribution (including shadowing) should be computed independent of another. You can't merge depth textures like you can combine baked lightmaps or non-depth shadow mapping because the shadow sampling depends on the projection of each light source. If the projection differs, there's no way to merge them in any meaningful way (there is also deferred shading/forward rendering, but not sure this is what you're after).

As for omni-directional shadow maps, I believe depth-shadow cubemaps are more widely supported now. You might also want to check out 'dual paraboloid shadow mapping'.

_arts_
01-03-2012, 01:30 AM
I was hoping for a bit detail than that. Don't I need to do some accumulation, at least?

Use additive blending between each light pass. For example, this pseudo-code does this:



glEnable (GL_BLEND);
glBlendFunc (GL_ONE, GL_ONE);

for_each (light){
// render the scene using the light 'light' and the shadow-map 'light->shadow_map'
render_scene (light, light->shadow_map);
}

glDisable (GL_BLEND);


This works whether you use shaders or not, and you can also use more than 8 lights, with a little trick with the light (ie always use GL_LIGHT0).

CarlBateman
02-07-2012, 09:23 AM
OK, after Christmas and a bout of 'flu' I've finally been able to take a crack at this.

So far, I've added:
2 shadow map textures
2 lightpositions
2 light view matrices
but I can't get them to blend correctly.

I've split the process into 3 functions:
1st pass - Draw from light's point of view into shadow map texture
2nd pass - Draw from camera's point of view with a dim light
3rd pass - Draw with bright light applying shadow calculations

And, I've wrapped
glEnable (GL_BLEND);
glBlendFunc (GL_ONE, GL_ONE);
:
glDisable (GL_BLEND);
around various call combinations.

The best result is shown below (I've edited the screen grab to make the shadows darker, they're almost too light to see otherwise) when I wrap the 3rd pass. Only one set of shadows is visible, except the small dark patch to the right where they overlap. So I'm guessing that I'm at least "facing in the right direction"...?

http://i.imgur.com/aZB9U.png

Pseudo code is something like this:

Draw from light1's point of view into shadow_map_texture1 using light_view_matrix1
Draw from light2's point of view into shadow_map_texture2 using light_view_matrix2

Draw from camera's point of view with a dim light at lightpos1
Draw from camera's point of view with a dim light at lightpos2

glEnable (GL_BLEND);
glBlendFunc (GL_ONE, GL_ONE);
Draw with bright light applying shadow calculations (shadow_map_texture1)
Draw with bright light applying shadow calculations (shadow_map_texture2)
glDisable (GL_BLEND);
Should the shadow map textures be blended? Should the results of the third pass be blended?

Probably all a bit too vague, but any help would be most appreciated.

Regards,

Carl

CarlBateman
02-08-2012, 09:45 AM
Use additive blending between each light pass. For example, this pseudo-code does this:



glEnable (GL_BLEND);
glBlendFunc (GL_ONE, GL_ONE);

for_each (light){
// render the scene using the light 'light' and the shadow-map 'light->shadow_map'
render_scene (light, light->shadow_map);
}

glDisable (GL_BLEND);

This works whether you use shaders or not, and you can also use more than 8 lights, with a little trick with the light (ie always use GL_LIGHT0).
I've been playing around with this. Won't each blend pass make the resulting image lighter? (This is what my experimentation points to.) Or am I missing something?

BionicBytes
02-08-2012, 12:21 PM
I've been playing around with this. Won't each blend pass make the resulting image lighter? (This is what my experimentation points to.) Or am I missing something?
No. Only where lights overlap will the image become brighter.
Saturation can occur but that why tone mapping exists.

CarlBateman
02-10-2012, 02:49 AM
Am I right in thinking that ambient lighting will be summed each pass and so should only be rendered once?

BionicBytes
02-10-2012, 03:02 AM
Are you using fixed function lighting? If you are you are on a hiding to nothing. The lighting model is really hanicapped at best. In real life there is only 1 'global ambient' that we detect in a typical situation, so in your rendering you should try and simplify things to achieve that too. Each glLight has it's own ambient term, so it's really up to you how you want to combine these. If the ambient terms are set and you are using fixed function, then yes ambient is included along with diffuse and specular. You define the contributions of these with the various light parameters - so set them to black if you don't want them on the other lights.

CarlBateman
02-12-2012, 12:11 PM
Yes, I am using fixed function lighting.

Still, I seem to have it working now, although admittedly I'm not quite sure why.
http://i.imgur.com/oHYdE.png
Ta da!

There was an errant glDisable(GL_LIGHTING), which certainly didn't help. :(

And, during the final pass I set ambient to black. Further experimentation points to the green channel saturating. :confused:

I'm just glad to have it working, I nerd-sniped myself with this little beauty several months ago. Now I can get back to some "real" work. :D

Many thanks to all who provided help, pointers and suggestions.

CarlBateman
03-10-2012, 01:59 AM
FYI Two other snafu's...
Materials were ambient rather than diffuse so the render was overly bright.
I was clearing the depth buffer before it was enabled leading to pixel artifacts and apparent z-fighting. D'oh.