I’m currently toying around with projected textures as shadows and I have some problems with it. What I do is, that I render the blocker object from the lights POV to a black and white texture (black object on white background). Then I set up glTexGen to generate texture coordinates for the shadow and then I render my reciever object. This seems to work fine, but there are some issues I’d like a little help with.
The first problem is, that when I use glTexGen, the shadow is projected on all surfaces, i.e. also the ones behind the light that shouldn’t really be getting the shadow. A possible solution to this would be to check wether the reciever object is behind the light and if so, turn off glTexGen for that specific object. But this doesn’t seem very effecient to me and besides, what if the object is only partially behind the lights plane? Isn’t there some better way to do this?
The second problem lies in rendering the shadow texture itself. When doing this, I need to figure out how large a FOV I need to just fit the entire blocker object into the texture image. The reason for this is, that I want to maximize the size of the blocker in the image to avoid aliasing artifacts and shadow leakage.
So I calculate a FOV and pass it to gluPerspective, but somehov it does not seem to be large enough. I use a bounding sphere to determine the approximate size of the blocker object, and when I render the lights view frustum on the screen, it seems that the sphere should fit inside the frustum, but when I view the shadow image I don’t get all of the blocker object in the image and thus I get a lot of shadow leakage. Does anyone have a suggestion on why this happens? Is there some better way to set up the lights frustum than using gluPerspective?
Any assistance with either of these problems is appreciated and if some of it sounds too cryptic, I will be happy to try and ellaborate on any of it.
So thanks in advance
I’ll kind of quote Cass’s paper on this.
You get the back-projection because of the math of projective texture mapping so what you can do is use a 1D texture to eliminate color contribution when the q texture coordinate of the projective texture becomes negative. I think that should do it. I havn’t actually done this before yet so this is all comming from what I think should happen.
Thanks for replying. I’ve read that paper by Cass too, but I don’t know how to implement that code wise. How do I check for the q coordinate? Since texture coord. generation happens automatically, I would think that it is something I need to set up beforehand, or am I wrong here? Does anybody know or have an idea how to do this?
Hmm, well I’m not sure how to implement that code wise either. I have been meaning to do a projective texture sample but never gotten around to it yet. Now I really want to. I’ll look into this more and see what I can come up with.
I too currently use the ‘clipper’ texture map for shadow mapping on fixed function pipelines in my current project. You use the same texgen matrix you used to project your texture, only for the clip texture unit:
- Make sure your texture wrap mode for the s coordinate is GL_CLAMP or GL_CLAMP_TO_EDGE
- Set texture matrix to identity and translate it by 0.5, 0, 0.
- Set s coordinate texture gen to EYE_LINEAR, and use the z row of your texgen matrix as the eye plane.
What this will do is generate texture coords based on the distance of the vertex to your light source. When a vertex is behind the light source it will generate a negative coordinate, clamped to 0.
You might want to take a look at my “perpixel shotlights” demo. It uses a 1D texture to get rid of backprojection.
Edit: Forgot the link, http://humus2.campus.luth.se/~humus/?page=3D
[This message has been edited by Humus (edited 11-14-2002).]
Right now, I am working on a GeForce 2 so I only have two texture units available to me. The first one holds the recievers texture and the second one holds the shadow texture. What would then be the best way to implement the 1D texture on such a card? How about one pass for the reciever texture and then another pass with unit 0 holding the shadow texture and unit 1 holding the 1D texture. Would that make sense? This will cost me another rendering pass, so it might be an expensive solution overall, but it would get rid of the back projection.
If you can’t use a 1d texture, try modulating your projected texture by an overbright GL spotlight. Place the spotlight at the projector, give it a 90 degree SPOT_CUTOFF and face it in the direction of the objects to receive the projected texture.
on the gf2 you have register combiners wich can do the mux operation, a comparison of a value against >= .5, wich is 0 in unsigned math… dunno how far that actually can help, still… don’t forget that