Jump to content
  • Advertisement
Sign in to follow this  
chni

Need help with shadow mapping (GLSL, Visual Studio)

This topic is 3609 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I implemented shadow mapping vertex and fragment shaders according to the Orange Book. Cplusplus sample code isn't provided by the book, so I tried to guess it. The results look very strange (see http://www.bilderhoster.at/jpqdj1228050205.html , a tiny cube in front of a big cube, the "shadow" is dark grey, upper right corner: depth view from light source). I tried several changes in the code, but they didn't help/made it even worse. I would appreciate if somebody who already implemented this could show me the differences between his/her and my code. Any comments are welcome. VERTEX SHADER
//
// Vertex shader for shadow mapping
//
// Author: Randi Rost, Philip Rideout
//
// Copyright (c) 2003-2006: 3Dlabs, Inc.
//
// See 3Dlabs-License.txt for license information
//

attribute float Accessibility;
varying vec4  ShadowCoord;
  
// Ambient and diffuse scale factors.
const float As = 1.0 / 1.5;
const float Ds = 1.0 / 3.0;
//const float Ds = 1.0;

void main()
{
    vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
    vec3 ecPosition3 = (vec3(ecPosition)) / ecPosition.w;
    vec3 VP = vec3(gl_LightSource[0].position) - ecPosition3;
    VP = normalize(VP);
    vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
    float diffuse = max(0.0, dot(normal, VP));

    float scale = min(1.0, Accessibility * As + diffuse * Ds);

    vec4 texCoord = gl_TextureMatrix[/*1*/0] * gl_Vertex;
    ShadowCoord   = texCoord / texCoord.w;

    gl_FrontColor  = vec4(scale * gl_Color.rgb, gl_Color.a);
    gl_Position    = ftransform();
}
FRAGMENT SHADER
//
// Fragment shader for shadow mapping
//
// Author: Philip Rideout
//
// Copyright (c) 2003-2006: 3Dlabs, Inc.
//
// See 3Dlabs-License.txt for license information
//

uniform sampler2DShadow ShadowMap;
uniform float Epsilon;

varying vec4 ShadowCoord;

float lookup(float x, float y)
{
    float depth = shadow2DProj(ShadowMap,
                      ShadowCoord + vec4(x, y, 0, 0) * Epsilon).x;
    return depth != 1.0 ? 0.75 : 1.0;
}
 
void main()
{
    float shadeFactor = lookup(0.0, 0.0);
    gl_FragColor = vec4(shadeFactor * gl_Color.rgb, gl_Color.a);
    //gl_FragColor = gl_Color;
}
WINDOW RESIZE CODE FOR GLUT
void changeSize(int w, int h) {

	if(h == 0)
		h = 1;
	
	width = w;
	height = h;
	
	float ratio = 1.0* w / h;

	glMatrixMode(GL_MODELVIEW);
	
	// prepare matrix for shadow map
	glPushMatrix();
	{
		glLoadIdentity();
		glViewport(0, 0, SHMAP_DEPTH_SIZE, SHMAP_DEPTH_SIZE);
		gluPerspective(45,1,1,1000);
		gluLookAt(4., 0., 4.,   0., 0., 0.,   0., 1., 0.);
		
		glGetMatrix(GL_MODELVIEW_MATRIX, &lightViewMatrix);
		
		glLoadIdentity();
		glTranslatef(.5f, .5f, .5f);
		glScalef(.5f, .5f, .5f);
		glMultMatrix(lightViewMatrix);
		glGetMatrix(GL_MODELVIEW_MATRIX, &normalizedLightViewMatrix);
		
	}
	glPopMatrix();

}
RENDER CODE FOR GLUT
void renderScene(void) {

	glUseProgram(0);
	
	glClear(GL_DEPTH_BUFFER_BIT);
	
	float ratio = 1.0* width / height;
	
	
	// generate the shadow map
	
	glLightfv(GL_LIGHT0, GL_POSITION, lpos);
	
	glMatrixMode(GL_PROJECTION);
	glViewport(0, 0, SHMAP_DEPTH_SIZE, SHMAP_DEPTH_SIZE);
	glLoadMatrix(lightViewMatrix);
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
	glColorMask(0, 0, 0, 0);
//	glPolygonOffset(2.5f, 10.f);
//	glEnable(GL_POLYGON_OFFSET_FILL);
	
	drawTeapot(); // currently draws tiny and big cube
	
//	glDisable(GL_POLYGON_OFFSET_FILL);
	
	glActiveTexture(GL_TEXTURE0);
	glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0,
			SHMAP_DEPTH_SIZE, SHMAP_DEPTH_SIZE, 0);
	glFinish();
	glColorMask(1, 1, 1, 1);
	
	glDisable(GL_TEXTURE_2D);
	
	
	glUseProgram(p);
	U1i("ShadowMap", 0); // sets the uniform ShadowMap to 0
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glMatrixMode(GL_TEXTURE);
	glActiveTexture(GL_TEXTURE0);
	glLoadMatrix(normalizedLightViewMatrix);
	
	// Reset the coordinate system before modifying
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	
	// Set the viewport to be the entire window
	glViewport(0, 0, width, height);

	// Set the correct perspective.
	gluPerspective(45,ratio,1,1000);
	glMatrixMode(GL_MODELVIEW);
	
	glLoadIdentity();

	gluLookAt(0., 0., 5.,   0., 0., 0.,   0., 1., 0.);
	
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	
	drawTeapot(); // currently draws tiny and big cube
	
	glDisable(GL_LIGHTING);
	
	
	glUseProgram(0);
	
	// draw depth texture
#ifdef DEBUG_SHADOW
	glLoadIdentity();
	gluLookAt(0.0,0.0,5.0, 
		      0.0,0.0,-1.0,
			  0.0f,1.0f,0.0f);
	glDisable(GL_DEPTH_TEST);
	glRasterPos2f(1.8, 1);
	glColor3f(1.f, 1.f, 1.f);
	glActiveTexture(GL_TEXTURE0);
	glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT, depthBuffer);
	glActiveTexture(GL_TEXTURE0);
	glPixelZoom(256.f / (float) SHMAP_DEPTH_SIZE, 256.f / (float) SHMAP_DEPTH_SIZE);
	glDrawPixels(SHMAP_DEPTH_SIZE, SHMAP_DEPTH_SIZE, GL_LUMINANCE, GL_FLOAT, depthBuffer);
	glPixelZoom(1.0, 1.0);
	glEnable(GL_DEPTH_TEST);
#endif
	
	if(auxtimeDelay(threshold, delay))
	{
		rotation += -0.1f;
		if(rotation > 360.f) rotation -= 360.f;
	}

	glutSwapBuffers();
	
	usleep(1000);
}

Share this post


Link to post
Share on other sites
Advertisement
It looks like the shadow is inside the cube instead of behind.

Maybe you should use a greated precision DEPTH_BUFFER or try to play with glPolygonOffset(), to offset back the depthshadow test.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!