Sign in to follow this  

How to prevent shadows to penetrate walls?

This topic is 4028 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Following problem: Light source -> object -> wall <- viewer With this constellation, the object's shadow penetrates the wall between object and viewer. One should think that the wall that would block the light and the shadow of the object behind the wall is a back face, but disabling face culling didn't cure this. How do I prevent such things from happening?

Share this post


Link to post
Share on other sites
I've been wondering about that also.
Only thing I would suggest is to have the wall be made up of two faces, with their backfaces facing each other. The shadow might not get to the second face.

Share this post


Link to post
Share on other sites
You're looking at it from the wrong angle - you don't need to stop the shadow penetrating the wall, you need to stop the light penetrating the wall in the first place. Then the shadow will be invisible.

Assuming you're using shadow volumes (since you mentioned that in your second post) then having the walls themselves cast shadows should fix it.

Share this post


Link to post
Share on other sites
Yeah, shadow volumes (z-fail). The problem is that there is a light source behind the wall too. So the wall doesn't cast a shadow.

Just imagine two big halls, connected by a doorway. Both halls are lit and contain objects. The shadows of the objects in one hall will be visible in the other hall, because that hall is lit, too.

Share this post


Link to post
Share on other sites
OrangyTang is right. If the wall casts shadows like other objects, shadows won't "penetrate" walls. Just try it ^^ (remember that walls need to have a facing face in both directions for this to work, like blakedev said).

Share this post


Link to post
Share on other sites
Spawn,

maybe you don't understand. The walls would themselves cast shadows into lit areas. Just read what I wrote about the two halls. They are lit independently. In that sense you could say that the light penetrating the walls of hall 1 does not affect hall 2 because it has its own light source. Now if the walls of hall 1 cast a shadow, that shadow will darken hall 2 just as the object shadows from hall 1. What I need is some stencil buffer updating using the shadow volumes of hall 1's walls to make the object shadows from hall 1 disappear. But how?

Share this post


Link to post
Share on other sites
Quote:
Original post by karx11erx
Spawn,

maybe you don't understand. The walls would themselves cast shadows into lit areas. Just read what I wrote about the two halls. They are lit independently. In that sense you could say that the light penetrating the walls of hall 1 does not affect hall 2 because it has its own light source. Now if the walls of hall 1 cast a shadow, that shadow will darken hall 2 just as the object shadows from hall 1. What I need is some stencil buffer updating using the shadow volumes of hall 1's walls to make the object shadows from hall 1 disappear. But how?


don't render the shadows.

render the entire scene with ambient light only, then render one pass / lightsource using the appropriate stencil buffer to exclude the areas covered by that lights shadow volumes.

rendering a black quad over the shadowed areas gives all kinds of problems and doesn't look that great. (its quick though)

Share this post


Link to post
Share on other sites
Simon,

I don't really understand.

I have two shadow render paths: One renders the entire mine bright, then renders all object's shadows into the stencil buffer, then renders a dark quad.

The other renders the mine dark, renders all object's shadows into the stencil buffer, then renders the mine bright where the stencil is 0.

Both paths create shadows penetrating walls.

Thank you for your input, but from what you wrote I don't understand what to change. It's just too general.

Share this post


Link to post
Share on other sites
Quote:
Original post by karx11erx
Simon,

I don't really understand.

I have two shadow render paths: One renders the entire mine bright, then renders all object's shadows into the stencil buffer, then renders a dark quad.

The other renders the mine dark, renders all object's shadows into the stencil buffer, then renders the mine bright where the stencil is 0.

Both paths create shadows penetrating walls.

Thank you for your input, but from what you wrote I don't understand what to change. It's just too general.


basically you have to use the second method BUT,
after the first dark render you have to do this:

for each light:
calculate shadow volumes.
render shadow volumes to stencil buffer
render the scene with that light only, no ambient light and don't render the shadowed parts. Then add the result to the existing one, (additive blending).
clear stencil buffer
repeat for the next light.

basically you have to render the scene n+1 times, where n is the number of lights affecting the scene

a good idea is to limit the number of lights that can affect a specific object (say a character) thus limiting the number of passes needed for it, 2-3 lights on a small object (such as the player) should be enough. pick the lights that has the largest effect.

One thing to remember, multipass solutions are expensive, many older games (Jedi Knight 2 for example) uses a method similar to the one you are using and does suffer from shadows punching trough walls as well.

im pretty sure someone can figure out a way to do nice volymetric shadows in a single pass with some fancy shader magic though.

Share this post


Link to post
Share on other sites
Quote:
Original post by karx11erx
Thanks, Simon. :)

How do I do additive blending?
Do I have to render the shadows for the walls, too?

every light needs to have shadow volumes for all relevant objects, walls included.
however since walls are pretty much static the volumes for those only needs to be updated when/if the light moves

i think it is GL_BlendFunc(GL_SRC_COLOR,GL_ONE); , im not 100% sure though.
just try it and see if it looks right :) , if it doesn't you can try with another blendfunc.

Edit: hmm it could be GL_ONE,GL_ONE aswell, been quite some time since i did this,.. just try and see.

Share this post


Link to post
Share on other sites
Quote:
Original post by karx11erx
Would shadow mapping be a better method here?

This multipass approach might kill performance for me.


Depends a bit on the hardware, shadowmaps are quite slow aswell though, and high resolution shadowmaps eat up vram pretty quickly. (generating dynamic shadowmaps isn't that cheap on low end hardware either).

if you set the number of lights per triangle (or per sub-mesh) to 2 the extra pass is probably cheaper than it is to generate shadowmaps. (the first ambient pass would lay down the z-buffer and the stencil buffer would cut out a bunch of extra pixels aswell, so basically you only push a few extra polygons which is reasonably cheap even on old hardware (such as the GeForce4)

Share this post


Link to post
Share on other sites
Quote:
Original post by karx11erx
Are there other good shadow rendering methods with both good performance and good looks?


not really. its always a trade off.

nvidia has a few documents on developer.nvidia.org regarding both teqniques + advice on optimizations etc.

(multipass rendering isn't as expensive as it sounds as each pass is very limited)

this one might be worth reading.
http://developer.nvidia.com/object/shadow_considerations.html

Share this post


Link to post
Share on other sites
Quote:
Original post by karx11erx
I am having 50+ lights per scene.


assuming your scene consists of multiple meshes or can be divided into multiple meshes you could simply select a smaller group of lights for each mesh based on the lights direction, intensity and position relative to that mesh.

a weak lightsource or a lightsource that is far away don't really contribute much to that particular mesh and can thus be ignored. using 4-5 lights for each mesh or sub-mesh should be enough. (depends a bit on how your lights are placed and the size of your sub-meshes)


here is an example that deals with vertex lighting and opengls built in lighting model (which supports up to GL_MAX_LIGHTS in a scene ,it used to be 8 or so if i remember correctly, hardly matters these days though).
http://www.opengl.org/resources/code/samples/mjktips/VirtualizedLights/multilight.c">


it shows you how to calculate how bright a light appears based on object to light and object to eye vectors , light intensity etc.

you may also want to add some culling methods to exclude lights that can't "see" the target object at all.

you could make the number of active lights / sub-mesh a variable so that it can be easily changed to get a good performance/visual balance. (perhaps even let the user set it so that users with high end hardware can waste a bit extra power on getting things "perfect"). with small enough sub-meshes you really shouldn't need more than 4-5 lights though. (small as in surface area, not number of polygons). subdividing polygons to break a large wall into smaller pieces can be a useful thing in these situations.

Share this post


Link to post
Share on other sites
I might have a simple solution to your shadow-trough-wall problem. Why not use the simple portal and mirror tehnique? Check if the player is in room A, if not don`t render the shadows(or better off don`t render anything). Of course, it would pe weird to walk trough a door and see shadows appearing everywhere, but it`s a start. You could do a simple graph like room 1 can go to room 2 and room 3, so there`s no point in rendering room 4 and 5. Then simply calculate the shadows per room. I`m quite new to openGL, so don`t throw rocks at me in case i said something stupid.

Share this post


Link to post
Share on other sites

This topic is 4028 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this