PDA

View Full Version : texture2DProj



bobGL
10-04-2007, 01:24 AM
Ok Im a bit stuck... Im using texture2DProj to project on texture on my scene and... My question is:

How can I get rid of the fragment that are outside the viewport of the light. I got the following shader:


// Vertex
varying vec4 projCoord;

void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
vec4 pos = gl_ModelViewMatrix * gl_Vertex;
projCoord = gl_TextureMatrix[0] * pos;
}

// Fragment
uniform sampler2D texunit0;
varying vec4 projCoord;

void main()
{

gl_FragColor = texture2DProj( texunit0, projCoord );
}I read that if .q > 0 then the fragment pass... I tried but it's not working any idea?

Y-tension
10-04-2007, 04:41 AM
I can think of a few ways:

Discard a fragment based on its s and t coordinate(if outside 0...1 range discard).

Use clamp to border, a border with 0 alpha and blend it away.

If anything else comes to mind I'll post it.

bobGL
10-04-2007, 04:52 AM
I tried... but nope... The thing is... When I put the camera simulating the light position everything look fine... the problem is all the pixels that are NOT inside the "light" viewport cause problems when I render from the camera position...

How can I get rid of the pixels outside the light viewport?!

I've been trying to cut theses frags with:

if( projCoord.t > ???

and

if( projCoord.q > ???

but no success it seems that it will always have some artifacts left....

yooyo
10-04-2007, 07:06 AM
uniform sampler2D shadowMap ;

varying vec4 projCoord;

void main()
{
vec3 suv = (projCoord.xyz / projCoord.q);
suv = (suv + 1.0) * 0.5;

vec4 shVal = texture2D(shadowMap, suv.xy);

if(shVal.z < suv.z) gl_FragColor = vec4(0.0);
else gl_FragColor = shVal;
}Or try to use sampler2DShadow & shadow2DProj if you are doing shadow mapping.

Komat
10-04-2007, 01:42 PM
You always need to discard (or set to black) fragments with negative value of Q coordinate. The removal of remaining bad fragments can be done by combination of black border around the edge of the projected texture and clamping texture mode (e.g. GL_CLAMP_TO_EDGE) as mentioned by Y-tension. Alternatively you can use test in shader to discard fragment if any component of (projCoord.st / projCoord.q) is outside of the <0,1> range.

There is one catch if you use the texture based method. Do not use mipmaps for that texture. The projection causes big differences between texture coordinates on fragments which are near the light plane. This causes selection of smaller mipmap levels and unless those levels are black around theirs edges, the light will become visible outside of its view.

bobGL
10-04-2007, 03:51 PM
Ok got it... that was all about the clamp to edge... errr anyway tks guys!, and for the record, the following shader work like charm after that, if you still want to have the back projection take out the IF statement:


varying vec4 projCoord;

void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
vec4 pos = gl_ModelViewMatrix * gl_Vertex;
projCoord = gl_TextureMatrix[0] * pos;
}


uniform sampler2D tex0;
varying vec4 projCoord;


void main()
{
if( projCoord.q > 0.0 )
{ gl_FragColor = texture2DProj( tex0, projCoord ); }
else
{ discard; }
}