Skip to main content
GameDev.net gamedev.net
🔒 Locked

projective texturing - remove back projection

Started by glJack Sep 9, 2006 at 6:59 PM 6 replies 2.2k views
Original Post
glJack
glJack
My situation is the following: I project a texture onto a sphere using perspective texture projection, and it works fine, but I get this texture projected not only onto the side of the sphere which faces the projector, but onto the back side of the sphere as well. I need only the side I need to remove this back-projection. I think that if I could determine in pixel shader whether current pixel belongs to a poly which faces the projector then I would be able to avoid back-projection just by instructing the shader to project texture on fron-facing polys only. For orthogonaly projected textures this task would be trivial and would be done with a single dot product, but how to be with perspective projections?
wolf
wolf
The book Programming Vertex and Pixel Shaders covers this issue. It is called reverse projection.
Unlike a real projector, the math of projective texture mapping actually produces a dual projection. One along the projector’s view direction, and another in the opposite direction.
The sign of w becomes negative behind the projector, which inverts the texture image in the reverse projection. On ps_2_0 and upwards capable hardware we can check the value of w and if w is negative, ignore the projective texture computation and output black.

...
return Tex.w < 0.0 ? 0.0 : tex2Dproj(ProjTexMapSampler, Tex);
...

Note: How to do this on ps_1_1 hardware: set D3DTTFF_PROJECTED in your texture state texture transformation flags and store the result of the dot-product between the texture projection matrix and the vertex position in a texture coordinate output register. Basically using D3DTTFF_PROJECTED in the texture transformation flags, enables texture coordinates division by the last texture coordinate. Solving the reverse projection issue is usually done with a so call clipper texture on ps_1_1 hardware. You need a 1d texture, that is 2x1 with one black pixel and one white pixel. Set your texture U coordinate addressing to CLAMP. In your pixel shader (or in case of the fixed-funtion pipeline in the texture stages), you now have to modulate your result color by the clipper texture. Basically what we are doing is, everytime your results get negative, the u texture coordinate gets clamped and you use the black pixel from the “clipper” texture in the color modulation, thus correcting the inverse projection.
glJack
glJack
I'm trying to remove not reverse projection, but back-projection. Reverse projection is easy to remove, just like you told me in your post. My problem is that projected texture image appears on the back side of the sphere, wich is in front of the camera, cause the whole sphere is in front of the camera.
JakeOfFury
JakeOfFury
Simply check the sign of the dot product between the vertex normal and the pixel to projector vector, just like you would do during per-pixel lighting.

For projective projective textures (not orthogonal), simply use a point light located at the viewpoint of the projection frustrum.
superpig
superpig
Computing the projector-space normal of each vertex in the vertex shader should suffice. The Z component of the normal will have a different sign for vertices oriented away from the projector - stick that Z component into a texture coordinate register, and then use texkill to clip pixels with negative signs in the pixel shader. (You might need to swap the sign on the component when you write it out - I don't remember which way the math goes right now).

If you need a more general solution to remove projections from occluded surfaces, then that's harder, but the place to start is most likely shadowmapping.
Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse
glJack
glJack
JakeOfFury

Thanx! It worked! I was affraid first that it wouldn't work with different projector's FOV's of but it works just fine

superpig
I tried computing projector space normal, but it didn't work for me. If I check z coord of projector space normal to determine whether this particular poly faces the projector, and this way I got some extra polys being determined as facing the projector, which shouldn't be determined so. (the ones which don't face the projector and have normals almost orthogonal to the v_to_projector vector )

About shadow mapping, I know that it would solve the problem, but what I did had to be solved without using it

Thanx you all for your replies!
wolf
wolf
... oh sorry about this. I think the previous post highlighted dot(P, N) ... so how about using a depth map?
glJack
glJack
wolf
Shadow maps would solve this problem, but in my situation I was limited not to use them.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.