PDA

View Full Version : Shadow Map Problem



apapaxionga
04-06-2011, 08:36 AM
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);////光源坐标,初&# 22987;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,Accessibility*As+diffuse*Ds);

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=shadeFactor*0.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.mt*Lig ht_ViewMatrix.mt*Camera_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;
}

Dark Photon
04-06-2011, 06:02 PM
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.
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:

* Re: GLSL - cube shadows - projecting (http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&amp;Number=294874#Post2948 74)

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.

apapaxionga
04-06-2011, 08:41 PM
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&amp;#65292;and finally it become totally dark.

apapaxionga
04-06-2011, 08:51 PM
the correct shadow after i change VB_WIDHT and VB_HEIGHT
http://b65.photo.store.qq.com/http_imglo...p;a=67&amp;b=65 (http://b65.photo.store.qq.com/http_imgload.cgi?/rurl4_b=0e6d70b023e66e1999e9acf8ce2e310968297726fc b0e457521395dd2bd9b9dd14f0570fc34ede8a736a6b21aee6 82073447c8c47c4016b4f487952578e67e32debe7117e65d10 dddfa2cbfd9809be5a00ac4d88&amp;a=67&amp;b=65)

the incorrect shadow before i change VB_WIDTH and VB_HEIGHT
http://b71.photo.store.qq.com/http_imglo...p;a=66&amp;b=71 (http://b71.photo.store.qq.com/http_imgload.cgi?/rurl4_b=0e6d70b023e66e1999e9acf8ce2e310944d0751c95 d7527cb292dd01d9dea337657a1dd81f8b620b4aa93d843482 a158c822c1657b64c21b3bc0fba54bfa9e54d2a7ba3a0f584b 0b5f4abf72e26a2a1593041349&amp;a=66&amp;b=71)

apapaxionga
04-07-2011, 08:20 AM
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