PDA

View Full Version : Sorry,still shadow mapping problem



capedica
05-31-2005, 12:01 AM
Hi,
sorry to ask another question on shadow mapping but i'd like to know if i'm doing all correctly (because nothing goes right).
I'm following this tutorial:
Ampoff (http://www.ampoff.org/modules.php?name=Forums&file=viewtopic&t=15)

The shader code is this:



[VERTEX SHADER]

uniform mat4 tmatrix;
varying vec4 projCoord;

void main()
{
vec3 lightVect, trueNormal;
vec4 realPos = gl_ModelViewMatrix * gl_Vertex;

lightVect = normalize(gl_LightSource[0].position.xyz - realPos.xyz);
trueNormal = gl_NormalMatrix * gl_Normal;

projCoord = tmatrix * realPos;
gl_FrontColor = vec4(dot(lightVect, trueNormal) - 0.1);

gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}

[FRAGMENT SHADER]

uniform sampler2D shadowMap;
uniform sampler2D lightTex;

varying vec4 projCoord;

const vec4 ambient = vec4(0.13), boost = vec4(1.06);

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

vec4 shadowValue = texture2D(shadowMap, projectiveBiased.xy);

// vec4 lightValue = texture2D(lightTex, projectiveBiased.xy);


//if(shadowValue.z < projectiveBiased.z)
// gl_FragColor = ambient;
//else
// gl_FragColor = boost * gl_Color * lightValue + ambient;

if(shadowValue.z < projectiveBiased.z)
gl_FragColor = vec4(0.3,0.3,0.3,1.0);
else
gl_FragColor = vec4(1.0,1.0,1.0,1.0);

}OK, this is what i'm doing:
- i take depth values from light view putting that in a depth texture;
- i calculate tmatrix in this way:



glPushMatrix();
glLoadIdentity();
glMultMatrix(lightProjectionMatrix);
glMultMatrix(lightViewMatrix);
glMultMatrix(InvCameraViewMatrix);
textureMatrix = glGet(GL_MODELVIEW_MATRIX);
glPopMatrix();

- i pass tmatrix and depth texture to shader and draw the scene.

Results are wrong, and when i move camera it seems that texture coordinates are not correctly calculated.
Am i doing something wrong?
Thank you very much.

splat
05-31-2005, 09:23 AM
this line is very wrong:
textureMatrix = glGet(GL_MODELVIEW_MATRIX);

Use glGetFloatv and pass your matrix array as a parameter.

capedica
05-31-2005, 01:38 PM
Sorry, i've forgotten to tell you that i'm using a scripting language built on opengl...

Tom Nuydens
06-01-2005, 10:12 AM
First of all, you may not need to apply the inverse camera matrix to your texture projection matrix. I typically use something like this:


glMatrixMode(GL_TEXTURE);
glLoadIdentity;
glTranslatef(0.5, 0.5, 0.5);
glScalef(0.5, 0.5, 0.5);
// This defines your spotlight cone:
gluPerspective(...);
// This defines the light position and orientation:
gluLookAt(...);Then, in the vertex shader you can compute your shadow map texcoords. What you want is the coordinates of the current vertex in the post-perspective space of the spotlight:


varying vec4 tc_shadow;

void main(void)
{
gl_Position = ftransform();
tc_shadow = gl_TextureMatrix[0] * gl_Vertex;
// Add any other stuff you need...
}This works as long as all vertices are specified in world coordinates. If you have different objects with different transformations applied to them, the easiest thing to do is to split the modelview matrix into "model" and "view" parts and to multiply each vertex with the "model" part in the shader, thus giving you a vertex in world space that you can work with as described above.

Finally, the fragment shader does the depth comparison:


uniform sampler2DShadow t_shadow;
varying vec4 tc_shadow;

void main(void)
{
// This test is to eliminate reverse projection:
if (tc_shadow.z > gl_DepthRange.near)
{
// Substitute any other lighting/texturing work here:
vec4 color = vec4(1.0, 1.0, 1.0, 1.0);
// Do the Z comparison:
vec4 s = shadow2DProj(t_shadow, tc_shadow);
// Output final color:
gl_FragColor = color * s;
}
else
{
// Fragments behind the projector don't count:
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
}Note the use of sampler2DShadow and shadow2DProj(). The depth texture needs to have depth comparisons enabled, or the results of shadow2DProj() will be undefined! Like so:


glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);

capedica
06-02-2005, 08:07 AM
wow, thank you very much, i'm going to try it, your help has been very usefull, bye

capedica
06-02-2005, 11:59 PM
Ok now it functions all correctly but i have one last question, if i want pass texture matrix as uniform i do calculate it? i've tried with this but it doesn't function:



glPushMatrix();
glLoadIdentity();
glMultMatrix(biasMatrix);
glMultMatrix(lightProjectionMatrix);
glMultMatrix(lightViewMatrix);
textureMatrix = glGet(GL_MODELVIEW_MATRIX);
glPopMatrix();
and in the shader instead of gl_TextureMatrix[0]*gl_Vertex i use this matrix passed as uniform.
Is this correct?
Still Thank you

capedica
06-03-2005, 01:41 AM
Resolved, the problem was only to transpose the matrix....and now the final question, is it possible to avoid to enable comparison mode?
i've modified shader in this way:




[FRAGMENT SHADER]

uniform sampler2D shadowMap;
....
.....
vec3 color = texture2D(lightTex, gl_TexCoord[0].xy);
if (projCoord.z > gl_DepthRange.near)
{

float s = texture2DProj(shadowMap, projCoord).r;
if (s==0.0)
gl_FragColor = vec4(color * 0.5,1.0);
else
gl_FragColor = vec4(color,1.0);
}
else
{
gl_FragColor = vec4(color, 1.0);
}but i still need to enable comparison mode, is there a way?
Thank you