Shadow map problem - works fine without shader

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:

When I use my shader instead, I get this:

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 && pos.x >= 0.0 && pos.x <= 1.0 && pos.y >= 0.0 && pos.y <= 1.0 )
		gl_FragColor = gl_Color * shadval;
	else
"
		gl_FragColor = gl_Color;
}

Any help at all would be appreciated, while I still have some hair left.

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.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.