Shadow Map Problem

i wrote a simple demo of shadow map,but it does not work well, the correct shadow does not show and it seems like the light does not work because the whole scene is dark, when i change the window from the initial size to the full size,the incorrect shadow disappear and the whole scene become darker,i can not figure it out.

void setlight()
{
GLfloat light_diff = {0.8f, 0.8f, 0.8f, 1.0f };

     glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diff);
     glLightfv(GL_LIGHT0, GL_POSITION, Lightpos);////光源坐标,初始Y=5

glPushMatrix();
glTranslatef(Lightpos[0],Lightpos[1],Lightpos[2]);
glColor3f(0,1,0);
auxSolidSphere(0.02f);
glPopMatrix();
glPushMatrix();
glColor4f(0.0f, 1.0f, 0.0f, 0.0f);
glBegin(GL_LINES);
glVertex3f(Lightpos[0], Lightpos[1], Lightpos[2]);
glVertex3f(LookAt[0],LookAt[1],LookAt[2]);
glEnd();
glPopMatrix();
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}

VertexShader:

uniform vec3 LightPosition;
const float As=1.0/1.5;
const float Ds=1.0/3.0;
varying float Accessibility;
varying vec4 ShadowCoord;
varying vec4 Color;
void main()
{
vec4 ecPosition=gl_ModelViewMatrix*gl_Vertex;
vec3 ecPosition3=(vec3(ecPosition))/ecPosition.w;

vec3 VP=LightPosition-ecPosition3;
VP=normalize(VP);
vec3 normal=normalize(gl_NormalMatrix*gl_Normal);
float diffuse=max(0.0,dot(normal,VP));

float costheta=dot(normal,VP);
float Accesibility=costheta*0.5+0.5;

float scale=min(1.0,AccessibilityAs+diffuseDs);

vec4 texCoord=gl_TextureMatrix[0] * gl_ModelViewMatrix * gl_Vertex;
ShadowCoord=texCoord;

Color =vec4(scale*gl_Color.xyz,gl_Color.w);
gl_Position=ftransform();
}

FragmentShader:

uniform sampler2DShadow ShadowMap;

varying vec4 ShadowCoord;
varying vec4 Color;

void main()
{
float shadeFactor=shadow2DProj(ShadowMap,ShadowCoord);
shadeFactor=shadeFactor0.25+0.75;
gl_FragColor=vec4(shadeFactor
Color.xyz,Color.w);
}

void GenShadowMapTexture()
{
glGenTextures(1, &shadowMapTexture);
glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, VB_WIDTH,VB_HEIGHT, 0,
GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

glMatrixMode(GL_PROJECTION);
glLoadMatrixf(Light_ProjectionMatrix.mt);

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf( Light_ViewMatrix.mt);

glViewport(0, 0,VB_WIDTH, VB_HEIGHT);

glCullFace(GL_FRONT);
glShadeModel(GL_FLAT);
glColorMask(0, 0, 0, 0);
glPolygonOffset(8.0f, 4.0f);
glEnable(GL_POLYGON_OFFSET_FILL);

RenderObject();

glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,1024, 1024); 

glCullFace(GL_BACK);
glShadeModel(GL_SMOOTH);
glColorMask(1, 1, 1, 1);
glDisable(GL_POLYGON_OFFSET_FILL);
}

void RenderObject()
{
glColor3f(0.0f, 0.0f, 1.0f);
glPushMatrix();
glTranslatef(-2.0,-1.0,-2.0);
glutSolidTeapot(0.51);
glTranslatef(0,-1,0);
glScalef(3,0,3);
glutSolidCube(1);
glPopMatrix();

}

void CastShadowMap()
{
shader.bind();
shader.SendUniform(“ShadowMap”,0);
shader.SendUniform(“LightPosition”,Lightpos[0],Lightpos[1],Lightpos[2]);

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, shadowMapTexture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);

glMatrixMode(GL_TEXTURE); //Note:MCtoLightMatrix=Light_ProjectionMatrix.mtLight_ViewMatrix.mtCamera_ViewInverse*gl_Vertex
glLoadMatrixf(Light_ProjectionMatrix.mt);
glMultMatrixf(Light_ViewMatrix.mt);
glMultMatrixf(Camera_ViewInverse.mt);

glMatrixMode(GL_MODELVIEW);
RenderObject();
glDisable(GL_TEXTURE_2D);
shader.unbind();

}

int DrawGLScene(GLvoid) // Here’s Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

glPushMatrix();
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)VB_WIDTH/(GLfloat)VB_HEIGHT, 2.0f, 60.0f);
glGetFloatv(GL_MODELVIEW_MATRIX, Light_ProjectionMatrix.mt);        
glLoadIdentity();		
gluLookAt(Lightpos[0],Lightpos[1],Lightpos[2],0,0, 0,  0.0, 1.0, 0.0);
glGetFloatv(GL_MODELVIEW_MATRIX, Light_ViewMatrix.mt);
glPopMatrix();
  
GenShadowMapTexture();
ReSizeGLScene(VB_WIDTH, VB_HEIGHT);	
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
setlight();   		
CastShadowMap();
SwapBuffers(hDC);
return 1;

}

Dude, you gotta give us just a little more to go on. Your just saying, my code’s broke, please fix it.

From your description, the thing that jumps out at me is that you say not only does the shadowing not work right, but the light doesn’t work right either. So, nuke the shadow map lookup/compare and just get your lighting right first.

Quickly scanning your code, I only see one PROJECTION matrix set up (I expect to see 2 – one for the camera and one for the light). You’re using it to draw the scene (presumably from the camera’s perspective. But you’re also saving it off as the light projection matrix. Doesn’t make much sense – from that vantage point you’re not gonna see any shadows even if you are computing and applying them right.

Also, assuming that is the right light PROJECTION matrix, since it’s Perspective not Ortho, presumably you are casting shadows from a point light source. And since your shadow map is 2D, then presumably your point light source has a cone that’s <= 90 degrees. Right so far?

Anyway, walk us through 1) what you’re trying to do, 2) what you’ve investigated so far to debug the problem, and 3) give us a complete GLUT test program that compiles. Dollars to donuts, you’ll figure out your problem as you’re writing up the explanation.

On that note, here is a link to a totally working GLUT test program which casts point light source shadows, courtesy of deadc0de:

It casts omnidirectional shadows from a point light source into a cube shadow map instead of unidirectional shadows from a point light source into a 2D shadow map (as you’re apparently trying to do), but most of this is the same. You just don’t need that face magic at the end.

Thanks a lot fot you reply.
i do not understand clearly about your meaning about the 2 projection you expect to see.i use the method that i save the shadow map from the view of light point,and then transform from camera space into light clip space and compare the shadow map

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, shadowMapTexture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glMatrixMode(GL_TEXTURE);
glLoadMatrixf(biasMatrix.mt);
glMultMatrixf(Light_ProjectionMatrix.mt);
glMultMatrixf(Light_ViewMatrix.mt);
glMultMatrixf(Camera_ViewInverse.mt);

Today it works! when i change the value of the variable VB_WIDTH and VB_HEIGHT to a smaller value ,it works well! The orignal value of VB_WIDTH and VB_HEIGHT is 1024 and 768, when i change it to 512 and 512 it works well.
However, i do not understand why. The place where i use VB_WIDTH and VB_HEIGHT is:

void GenShadowMapTexture()
{

glViewport(0, 0,VB_WIDTH, VB_HEIGHT);


glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,1024, 1024);

}

int DrawGLScene(GLvoid)
{
…;
gluPerspective(45.0f, (GLfloat)VB_WIDTH/(GLfloat)VB_HEIGHT, 2.0f, 60.0f);
…;
}

another question is that :the shadow is correct when the window is at the initial size ,however when i change it to the full size , after a few seconds , the shadow begin to flashing,and finally it become totally dark.

the correct shadow after i change VB_WIDHT and VB_HEIGHT

the incorrect shadow before i change VB_WIDTH and VB_HEIGHT

I work it out! Now the demo runs smoothly.
i change the last parameters of the function like this :
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,VB_WIDTH, VB_HEIGHT); // the width and height of the window

i previously set the last two parameters as 1024 ,1024

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