It has been a while that I wonder how to make shadow projections using the stencil buffer that cannot be seen if they shouldn’t. I decided to start this thread in order to find out any solution.
A more explanation: shadows are projected well, but if there is any occluding meshes between the vision and the shadowed object, the shadow is still visible. This simply comes from the fact that I disable depth test during the shadow rendering.
I’ve also tried to let the depth test during this process: shadows effectively disappear if they do not have to be seen. However, they are not well: sometimes they are well drawn, sometimes not at all, and for the other times they are partially drawn, depending on how you’re looking at them. And when on motion, the result is simply very bad and cannot be used for any ‘good’ program.
I actually do not use any portals, occlusion queries or whatever else to manage the view. And I’d like not to use them for shadowing. But I wonder how far it is possible.
Finally, is there other means to do shadows, like shadow mapping or shadow volume; can they avoid this problem ? (I’ve simply never tried out them).
noone for that one ? Ok. maybe this is a dumb question then.
I think it’s a little unclear exactly what you’re doing. Are you doing proper stencil shadows as described in:
or something else?
No, I simply project my meshes onto a plane. This is what is called shadow projection. And I draw the shadow onto this plane. I use the stencil buffer for all that to work.
The situation I stippled is normal just because I disable the depth test during my shadow rendering. This seems an obligation if we don’t want to corrupt the shadow drawing (so it can look nice).
Here is simply how I do it:
Say P is the plane that will receive the shadow.
Say M is the model that will cast the shadow on P.
Say L is the light source.
I first calculate the matrix N for the shadow projection using P equation and L position.
I then draw P with some stencil stuffs.
Then I transform into N by matrix multiplication.
I disable depth test so that the shadow are correctly drawn (because I draw it onto the plane so the depth test returns the same value for both the plane and the shadow).
Then I can render M into the stencil.
I enable depth test.
Finally, out of stencil I can draw M.
There are other things I do like disable light and such, but I simplify here with what’s necessary only.
I first wanted not to use any occlusion test to avoid my problem. But I now wonder if it’s possible.
Shadow volumes seems more complicated, I didn’t have seen them yet. So robust shadow volumes are simply out of context for me.
Ok, now I see what you’re doing. I suggest the following:
- Clear the stencil buffer to zero
- Render the scene as usual.
- Call glEnable(GL_STENCIL_TEST).
- Call glDepthFunc(GL_EQUAL).
- Call glStencilFunc(GL_ALWAYS, 0x1, 0x1).
- Call glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE).
- Draw your ground plane.
- Call glStencilFunc(GL_EQUAL, 0x1, 0x1).
- Call glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP).
- Call glDepthFunc(GL_ALWAYS).
- Render the shadows
- Call glDisable(GL_STENCIL_TEST).
I think this should work, haven’t had time to try it though.
Another simple solution that can sometimes work is to draw the shadows with depth testing enabled but using a small bias to lift them from the ground plane.
Thanks for your suggestion. I’ll have a look at it as soon as possible.
I’m not sure your other solution could make good results. bias will provoke bad drawings depending on where it is drawn. Maybe simply translate it with a very little height over the ground can give more homogeneous results.
Stricly respecting what you said renders bad. With modification, I didn’t reached to have something well neither.
How can I thank you ? The first time I simply bad implemented what you said.
Even if I don’t have the same looks for my shadow, compared to before (if a region has several shadows projected on it, it’s darker than other regions)and this provokes very ‘unsoft’ shadows, I think I can do them look better.
You’re great !