PDA

View Full Version : Shadow map problem - works fine without shader



SiW
08-11-2006, 03:02 PM
I'm tearing my hair out with this one. I'm trying to do basic shadow mapping, and if I don't use a shader I get this correct result:


http://www.coolpowers.com/lab/data/noshader.PNG

When I use my shader instead, I get this:

http://www.coolpowers.com/lab/data/shader.PNG

Does this look familiar to anyone? I'm not using FBO/pixelbuffers, just a simple copytex. Here's my texture creation:


glGenTextures( 1, &g_ShadmapID );
glBindTexture( GL_TEXTURE_2D, g_ShadmapID );
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, g_ShadmapSize, g_ShadmapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
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 );Here's how I render the shadow:


// first, we render the scene from the light's point of view
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();

// Orient the view to look from the light to the center of the scene
gluLookAt( g_LightPos[0],g_LightPos[1],g_LightPos[2], 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f );

// save the light's viewmatrix
glGetFloatv(GL_MODELVIEW_MATRIX, g_LightViewMatrix);

glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

// offset the drawing to help stop z-fighting - the values need to be tweaked for
// specific scenes
glPolygonOffset( 4.0f, 8.0f );
glEnable( GL_POLYGON_OFFSET_FILL );

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();

glMatrixMode( GL_PROJECTION );
glLoadIdentity();

// prepare the view - note that the view angle should be 45deg, and the viewport
// is set to the dimensions of the shadow map
gluPerspective( 45.0f, (float)g_ScreenWidth / (float)g_ScreenHeight, 0.1f, 100.0f );
glViewport( 0, 0, g_ShadmapSize, g_ShadmapSize );

// re-orient the view for the light
glMatrixMode( GL_MODELVIEW );
glMultMatrixf( g_LightViewMatrix );

// render the scene itself
glColorMask(0, 0, 0, 0);
RenderWorld();
glColorMask(1, 1, 1, 1);

glDisable( GL_POLYGON_OFFSET_FILL );

// ..and copy it to texture
glBindTexture( GL_TEXTURE_2D, g_ShadmapID );
glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, g_ShadmapSize, g_ShadmapSize );Here's how I render the scene afterwards:


// we're done rendering from the light's viewpoint
// now render to screen
glClearColor( 0.0f, 0.0f, 1.0f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();


// view from camera
gluLookAt( g_CameraPos[0], g_CameraPos[1], g_CameraPos[2], g_CameraTarget[0], g_CameraTarget[1], g_CameraTarget[2], 0.0f, 1.0f, 0.0f );

// position the light
glLightfv( GL_LIGHT0, GL_POSITION, g_LightPos );

// setup GL to generate the correct texture matrix - should not be
// needed when workig with the shader
float x[] = { 1.0f, 0.0f, 0.0f, 0.0f };
float y[] = { 0.0f, 1.0f, 0.0f, 0.0f };
float z[] = { 0.0f, 0.0f, 1.0f, 0.0f };
float w[] = { 0.0f, 0.0f, 0.0f, 1.0f };
glTexGenfv( GL_S, GL_EYE_PLANE, x );
glTexGenfv( GL_T, GL_EYE_PLANE, y );
glTexGenfv( GL_R, GL_EYE_PLANE, z );
glTexGenfv( GL_Q, GL_EYE_PLANE, w );

glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );

glEnable( GL_TEXTURE_GEN_S );
glEnable( GL_TEXTURE_GEN_T );
glEnable( GL_TEXTURE_GEN_R );
glEnable( GL_TEXTURE_GEN_Q );


// add an offset and bias here when setting up the viewport
glMatrixMode( GL_TEXTURE );
glLoadIdentity();
glTranslatef( 0.5f, 0.5f, 0.5f );
glScalef( 0.5f, 0.5f, 0.5f );
gluPerspective( 45.0f, (float)g_ScreenWidth / (float)g_ScreenHeight, 0.1f, 100.0f);
glMultMatrixf( g_LightViewMatrix );
glViewport( 0, 0, g_ScreenWidth, g_ScreenHeight );


// enable the shadowmapping GLSL program
glUseProgramObjectARB( g_prgShadowMap );

// enable and bind the shadow map we rendered above
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, g_ShadmapID );
GLuint uniform = glGetUniformLocationARB( g_prgShadowMap, "shadtex");
glUniform1iARB( uniform, 0 );

// actually render the scene as normal
RenderWorld();
glUseProgramObjectARB( NULL );

// return GL to normal state
glDisable( GL_TEXTURE_2D );
glDisable( GL_TEXTURE_GEN_S );
glDisable( GL_TEXTURE_GEN_T );
glDisable( GL_TEXTURE_GEN_R );
glDisable( GL_TEXTURE_GEN_Q );Here's my shaders:


// vertex
varying vec4 projcoord;
void main()
{
gl_Position = ftransform();
vec4 worldpos = gl_ModelViewMatrix * gl_Vertex;
projcoord = gl_TextureMatrix[0] * gl_Vertex;
vec4 lightdir = gl_LightSource[0].position - worldpos;
vec3 normal = normalize( gl_NormalMatrix * gl_Normal );
float NdotL = dot( normal, normalize(lightdir.xyz) );
gl_FrontColor = gl_Color * NdotL;
}


// fragment
uniform sampler2DShadow shadtex;
varying vec4 projcoord;
void main()
{
vec3 pos = projcoord.xyz/projcoord.q;
float shadval = shadow2DProj(shadtex,projcoord).r;


// only potentially in shadow if within the light's view frustum
if ( projcoord.w > 0.0 &amp;&amp; pos.x >= 0.0 &amp;&amp; pos.x <= 1.0 &amp;&amp; pos.y >= 0.0 &amp;&amp; pos.y <= 1.0 )
gl_FragColor = gl_Color * shadval;
else\n"
gl_FragColor = gl_Color;
}Any help at all would be appreciated, while I still have some hair left.

jra101
08-14-2006, 01:09 PM
To recompute eye linear texture coordinates the same was as the fixed function you need to do this:

vec4 worldpos = gl_ModelViewMatrix * gl_Vertex;
projcoord.s = dot(worldpos, gl_EyePlaneS[0]);
projcoord.t = dot(worldpos, gl_EyePlaneT[0]);
projcoord.p = dot(worldpos, gl_EyePlaneR[0]);
projcoord.q = dot(worldpos, gl_EyePlaneQ[0]);
projcoord = projcoord * gl_TextureMatrix[0];which can be simplified to:

vec4 worldpos = gl_ModelViewMatrix * gl_Vertex;
projcoord = worldpos * gl_TextureMatrix[0];given the values you set for your eye plane.