[fixed]what's the common reason of this shadow map bug?

Started by
6 comments, last by db123 10 years ago

hi, i found a basic shadow map demo in this site:

http://www.opengl.org/discussion_boards/showthread.php/166763-GLSL-Shadow-Map-code-sample

but when i compile it in xcode, it looks like this:

[attachment=20491:QQ20140318-1@2x.png]

what's the common reason of this bug?

or what is the terminology of this bug?

this shader codes:


// Used for shadow lookup
varying vec4 ShadowCoord;



void main()
{


     	ShadowCoord= gl_TextureMatrix[7] * gl_Vertex;
  
		gl_Position = ftransform();

		gl_FrontColor = gl_Color;
}


uniform sampler2D ShadowMap;

varying vec4 ShadowCoord;

void main()
{	
	vec4 shadowCoordinateWdivide = ShadowCoord / ShadowCoord.w ;
	
	// Used to lower moiré pattern and self-shadowing
	shadowCoordinateWdivide.z += 0.0005;
	
	
	float distanceFromLight = texture2D(ShadowMap,shadowCoordinateWdivide.st).z;
	
	
 	float shadow = 1.0;
 	if (ShadowCoord.w > 0.0)
 		shadow = distanceFromLight < shadowCoordinateWdivide.z ? 0.5 : 1.0 ;
  	
	
  	gl_FragColor =	 shadow * gl_Color;
  
}

framebuffer code:


void generateShadowFBO()
{
	int shadowMapWidth = RENDER_WIDTH * SHADOW_MAP_RATIO;
	int shadowMapHeight = RENDER_HEIGHT * SHADOW_MAP_RATIO;
	
	//GLfloat borderColor[4] = {0,0,0,0};
	
	GLenum FBOstatus;
	
	// Try to use a texture depth component
	glGenTextures(1, &depthTextureId);
	glBindTexture(GL_TEXTURE_2D, depthTextureId);
	
	// GL_LINEAR does not make sense for depth texture. However, next tutorial shows usage of GL_LINEAR and PCF
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	
	// Remove artefact on the edges of the shadowmap
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
	
	//glTexParameterfv( GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor );
	
	
	
	// No need to force GL_DEPTH_COMPONENT24, drivers usually give you the max precision if available 
	glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
	glBindTexture(GL_TEXTURE_2D, 0);
	
	// create a framebuffer object
	glGenFramebuffersEXT(1, &fboId);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
	
	// Instruct openGL that we won't bind a color texture with the currently binded FBO
	glDrawBuffer(GL_NONE);
	glReadBuffer(GL_NONE);
	
	// attach the texture to FBO depth attachment point
	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, depthTextureId, 0);
	
	// check FBO status
	FBOstatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
	if(FBOstatus != GL_FRAMEBUFFER_COMPLETE_EXT)
		printf("GL_FRAMEBUFFER_COMPLETE_EXT failed, CANNOT use FBO\n");
	
	// switch back to window-system-provided framebuffer
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}


@Ashaman73, thank you very much.

but when i change that bias value, the result is nothing changed.

there is a zip of the pcf shadow map demo:

[attachment=20492:SMT-pcf.zip]

it looks like this:

[attachment=20493:QQ20140318-2@2x.png]

my computer is macbook pro with retina 13.1

Advertisement

The problem is called shadow-acne, moire effect, self shadowing artifacts etc.

In your code is already the solution:


	// Used to lower moiré pattern and self-shadowing
	shadowCoordinateWdivide.z += 0.000;


Play around with some small values to offset (bais) the shadows.

A quick description:

Shadowmapping is a kind of volume rendering technique, where each shadowmap texel is,more or less, a virtual quarter of a shadow-volume. The issue is, that a surface section is not always clearly inside(shadowed) or outside(lit) of this quater. Sometimes some pixels of the rendered surface are outside and others inside (think of an aliasing problem of rastered graphics, eg the antialiasing of a line), which results in a pattern of shadowed and unshadowed pixels.

There are some workarounds,hacks and tricks to lower the effect, but you will never completly get rid of it.

The problem is called shadow-acne, moire effect, self shadowing artifacts etc.

In your code is already the solution:


	// Used to lower moiré pattern and self-shadowing
	shadowCoordinateWdivide.z += 0.000;


Play around with some small values to offset (bais) the shadows.

A quick description:

Shadowmapping is a kind of volume rendering technique, where each shadowmap texel is,more or less, a virtual quarter of a shadow-volume. The issue is, that a surface section is not always clearly inside(shadowed) or outside(lit) of this quater. Sometimes some pixels of the rendered surface are outside and others inside (think of an aliasing problem of rastered graphics, eg the antialiasing of a line), which results in a pattern of shadowed and unshadowed pixels.

There are some workarounds,hacks and tricks to lower the effect, but you will never completly get rid of it.

i am sorry, that code is comment temporary by myself.

the orignal code is += 0.0005

You could also add a test to your code to see if the surface is facing the light source or not. If the surface isn't facing to the light then it is in shadow. This will remove all the shadow acne from the shadowed side.

In other words, perform shadow mapping only on the surfaces facing the light.

Cheers!

the pcf shadow map demo is not valid on windows too.

[attachment=20506:QQ??20140319081515.png]

The OS is largely irrelevant. Can you tell us what graphics card you have?

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

The OS is largely irrelevant. Can you tell us what graphics card you have?

my windows pc use zotac gtx460.

i found this bugs.

because in the pixel shader,

the variable shadow is not initialized.

biggrin.png

This topic is closed to new replies.

Advertisement