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?
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’.
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).
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”…?
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.
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?
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.
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.
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.