Hello,
I tried making shadow mapping for some torus. I stored the depth test result into a texture. Because, I need compute rotation for torus, and floor is no need do this. I used two shader snippets for torus shadow and floor shadow. But I found two problems. One is I can’t make shadow for floor, only can make shadow for torus. The other problem is I find my shadow effect is not fine. Some shadow looks like formed by many isolated dark points. I attached my code below. Thanks!
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
setlight();
GenShadowMap();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(Camera_ProjectionMatrix.mt);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(Camera_ViewMatrix.mt);
glTranslatef(translate_x, translate_y, translate_z);
glRotatef(rotate_x, 1.0, 0.0, 0.0);
glRotatef(rotate_y, 0.0, 1.0, 0.0);
glGetFloatv(GL_MODELVIEW_MATRIX, Camera_ViewInverse.mt);
Camera_ViewInverse = Camera_ViewInverse.GetmvMatrixInverse();
CastShadowMap();
glutSwapBuffers();
}
void GenShadowMap()
{
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glShadeModel(GL_FLAT);
glPolygonOffset(2.0f, 4.0f);
glEnable(GL_POLYGON_OFFSET_FILL);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, depthFBO);
glDrawBuffer(GL_DEPTH_ATTACHMENT_EXT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawObjects();//////////////////////////1
drawFloor();////////////////////////////1
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glShadeModel(GL_SMOOTH);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDisable(GL_POLYGON_OFFSET_FILL);
}
void setlight()
{
GLfloat Lf[4];
GLfloat Lc[4];
/* Use a white light. */
Lc[0] = 1.0;
Lc[1] = 1.0;
Lc[2] = 1.0;
Lc[3] = 1.0;
glLightfv(GL_LIGHT0, GL_DIFFUSE, &Lc[0]);
glLightfv(GL_LIGHT0, GL_SPECULAR, &Lc[0]);
glEnable(GL_LIGHT0);
ambientLight(1);
Lf[0] = L[0];
Lf[1] = L[1];
Lf[2] = L[2];
Lf[3] = L[3];
glLightfv(GL_LIGHT0, GL_POSITION, &Lf[0]);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(Light_ProjectionMatrix.mt);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(Light_ViewMatrix.mt);
glDisable(GL_LIGHTING);
glPushMatrix();
/* Draw light source position as a Red dot. */
glColor3f(1,0,0);
glBegin(GL_POINTS);
glVertex3dv(L);
glEnd();
glPopMatrix();
glEnable(GL_LIGHTING);
}
void CastShadowMap()
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, shadowmapid);
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);
glPushAttrib(GL_TEXTURE_BIT);
glActiveTextureARB(GL_TEXTURE7);
glLoadIdentity();
glLoadMatrixf(Light_ProjectionMatrix.mt);
glMultMatrixf(Light_ViewMatrix.mt);
glMultMatrixf(Camera_ViewInverse.mt);
glMatrixMode(GL_MODELVIEW);
RenderObjects();
glBindTexture(GL_TEXTURE_2D,0);
glDisable(GL_TEXTURE_2D);
glPopAttrib();
}
void init(void)
{
checkGLExtensions();
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_TEXTURE_2D);
SetFrameBufferObject(wWidth, wHeight);
glGenTextures(1,&floorTex);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPerspective(65.0, (double)wWidth / (double)wHeight, 0.001, 1000.0);
glGetFloatv(GL_PROJECTION_MATRIX, Camera_ProjectionMatrix.mt);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
gluLookAt(.0, .0, 100.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glGetFloatv(GL_MODELVIEW_MATRIX, Camera_ViewMatrix.mt);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPerspective(45.0f, (double)wWidth / (double)wHeight, 0.001, 1000.0);
glGetFloatv(GL_PROJECTION_MATRIX, Light_ProjectionMatrix.mt);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
gluLookAt( L[0], L[1], L[2],
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
glGetFloatv(GL_MODELVIEW_MATRIX, Light_ViewMatrix.mt);
glPopMatrix();
glPointSize(16.0);
if (useTextures)
{
makeFloorTexture();
}
}
shadowmap1.vert
varying vec4 shadowTexcoord;
varying vec4 diffuse;
void main()
{
vec4 centerOfMass;
vec2 texCrd;
…
rotatedPos.xyz = rotatedPos.xyz + centerOfMass.xyz;
gl_Position = gl_ModelViewProjectionMatrix * rotatedPos;
vec4 Vpos = gl_ModelViewMatrix * rotatedPos;
vec3 pos = Vpos.xyz / Vpos.w;
vec3 lightdir = normalize( vec3(gl_LightSource[0].position) - pos);
norm = normalize(gl_NormalMatrix * gl_Normal);
float NdotL = max(0.0, dot(lightdir, norm));
diffuse = gl_LightSource[0].diffuse * NdotL;
vec4 texcoord = gl_TextureMatrix[7] * gl_ModelViewMatrix * rotatedPos;
shadowTexcoord = texcoord / texcoord.w;
shadowTexcoord = 0.5 * shadowTexcoord +0.5;
gl_FrontColor = gl_Color;
}
shadowmap1.frag
uniform sampler2DShadow shadowmap;
varying vec3 norm;
varying vec4 shadowTexcoord;
varying vec4 diffuse;
void main()
{
const float epsilon = 0.5;
float factor = 1.0;
float depth = shadow2DProj(shadowmap, shadowTexcoord).r + epsilon;
depth = clamp(depth, 0.0, 1.0);
if(depth != 1.0)factor = 0.25;
if(shadowTexcoord.x >= 0.0 && shadowTexcoord.y >= 0.0
&& shadowTexcoord.x <= 1.0 && shadowTexcoord.y <= 1.0 )
{
gl_FragColor = vec4(gl_Color.rgb* diffuse.rgb * factor, 1.0);
}
else
{
gl_FragColor = vec4(gl_Color.rgb* diffuse.rgb, 1.0);
}
}
shadowmap2.vert
varying vec3 norm;
varying vec4 shadowTexcoord;
varying vec4 diffuse;
void main()
{
vec4 Vpos = gl_ModelViewMatrix * gl_Vertex;
vec3 pos = Vpos.xyz / Vpos.w;
vec3 lightdir = normalize( vec3(gl_LightSource[0].position) - pos);
norm = normalize(gl_NormalMatrix * gl_Normal);
float NdotL = max(0.0, dot(lightdir, norm));
diffuse = gl_LightSource[0].diffuse * NdotL;
vec4 texcoord = gl_TextureMatrix[7] * gl_ModelViewMatrix * gl_Vertex;
shadowTexcoord = texcoord / texcoord.w;
shadowTexcoord = 0.5 * shadowTexcoord +0.5;
gl_FrontColor = gl_Color;
}
shadowmap2.frag
uniform sampler2DShadow shadowmap;
varying vec3 norm;
varying vec4 shadowTexcoord;
varying vec4 diffuse;
void main()
{
const float epsilon = 0.5;
float factor = 1.0;
float depth = shadow2DProj(shadowmap, shadowTexcoord).r + epsilon;
depth = clamp(depth, 0.0, 1.0);
if(depth != 1.0)factor = 0.25;
if(shadowTexcoord.x >= 0.0 && shadowTexcoord.y >= 0.0
&& shadowTexcoord.x <= 1.0 && shadowTexcoord.y <= 1.0 )
{
gl_FragColor = vec4(gl_Color.rgb* diffuse.rgb * factor, 1.0);
}
else
{
gl_FragColor = vec4(gl_Color.rgb* diffuse.rgb, 1.0);
}
}