I’ve run into a problem with my 3D engine while trying to incorporate shadow mapping.
Vert Shader:
<div class=“ubbcode-block”><div class=“ubbcode-header”>Click to reveal… <input type=“button” class=“form-button” value=“Show me!” onclick=“toggle_spoiler(this, ‘Yikes, my eyes!’, ‘Show me!’)” />]<div style=“display: none;”>
varying float heightPass;
varying vec3 n, eyeVec, lightVec;
varying vec3 HalfVector;
varying vec4 shadowTexCoord;
void main()
{
n = normalize(gl_NormalMatrix * gl_Normal);
vec4 vVertex = gl_ModelViewMatrix * gl_Vertex;
eyeVec = -vVertex.xyz;
lightVec = normalize(vec3(gl_LightSource[0].position.xyz));
HalfVector = normalize(gl_LightSource[0].halfVector.xyz);
heightPass = gl_Vertex.y;
gl_ClipVertex=gl_ModelViewMatrix*gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0 * (12); // 6 = tiling factor, makes terrains look better
gl_TexCoord[1] = gl_MultiTexCoord0 * (6);
gl_TexCoord[2] = gl_MultiTexCoord0;
shadowTexCoord = gl_TextureMatrix[7] * gl_Vertex;
gl_Position = ftransform();
gl_FrontColor = gl_Color;
}
[/QUOTE]
Frag Shader:
uniform sampler2D grass; // 1
uniform sampler2D sand; // 2
uniform sampler2D mud; // 3
uniform sampler2D snow; // 4
uniform sampler2D gravel; // 5
uniform sampler2D detail ; // 6
uniform sampler2D shadowMap;//7
varying float heightPass;
varying vec3 n, lightVec, eyeVec;
varying vec2 texCoord;
varying vec4 pos;
varying vec3 HalfVector;
varying vec4 shadowTexCoord;
float texfactor(float h1, float h2)
{
float percent;
percent = (32 - abs(h1 - h2)) / 32;
if(percent < 0.0) percent = 0.0;
else if(percent > 1.0) percent = 1.0;
return percent;
}
float percent[9];
vec4 blendedTerrain(vec4 texel)
{
percent[0] = texfactor(196,heightPass);
percent[1] = texfactor(164,heightPass);
percent[2] = texfactor(128,heightPass);
percent[3] = texfactor(96,heightPass);
percent[4] = texfactor(64,heightPass);
percent[5] = texfactor(32,heightPass);
percent[6] = texfactor(0,heightPass);
percent[7] = texfactor(228,heightPass);
percent[8] = texfactor(256,heightPass);
// Fix the order on these things ?
texel = texture2D(snow,gl_TexCoord[0].st)*percent[0] + // snow starts
texture2D(grass,gl_TexCoord[0].st)*percent[1]+
texture2D(grass,gl_TexCoord[0].st)*percent[2] +
texture2D(grass,gl_TexCoord[0].st)*percent[3] +
texture2D(sand,gl_TexCoord[0].st)*percent[4] +
texture2D(sand,gl_TexCoord[0].st)*percent[5] +
texture2D(mud,gl_TexCoord[0].st)*percent[6] +
texture2D(snow,gl_TexCoord[0].st)*percent[7]+ // higher
texture2D(snow,gl_TexCoord[0].st)*percent[8]; // highest
return texel;
}
void main()
{
//FOG
float density = 0.1;
vec4 fogColor = vec4(0.5,0.5,0.5,1.0);
const float LOG2 = 1.442695;
float z = 1.0 - (gl_FragCoord.z / gl_FragCoord.w)/100; // format: 1.0 - (z/w) / view distance (fog starts here);
float fogFactor = exp2( -density *
density *
z *
z *
LOG2 );
fogFactor = clamp(fogFactor, 0.0, 1.0);
//LIGHT
// Note: need to balance the starting brightness of our textures
vec4 Idif;
vec4 Ispec;
vec4 Iamb = (gl_FrontMaterial.ambient * gl_LightSource[0].ambient);
vec3 N = normalize(n);
vec3 L = normalize(lightVec);
Idif = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse * max(dot(N, L),0.0);
Ispec = gl_FrontMaterial.specular * gl_LightSource[0].specular * pow(max(dot(N,HalfVector),0.0), gl_FrontMaterial.shininess);
vec4 texel;
vec4 texD;
vec3 ct,cf;
float intensity,at,af;
texD = blendedTerrain(texD);
ct = texD.rgb;
at = texD.a ;
vec4 shadowCoordinateWdivide = shadowTexCoord / shadowTexCoord.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 (shadowTexCoord.w > 0.0)
shadow = distanceFromLight < shadowCoordinateWdivide.z ? 0.8 : 1.0 ;
vec4 finalColor = ( Iamb*texD + Idif*texD + Ispec*texD )*shadow;// diffuse + specular;
gl_FragColor = mix(fogColor, finalColor, fogFactor );
//gl_FragColor = finalColor;
}
[/QUOTE]
FBO setup:
bool FrameBufferObject::initialize(int width_, int height_, int format)
{
if(!GLEW_EXT_framebuffer_object)
{
printf("GL_EXT_framebuffer_object not supported");
return false;
}
if(width_ <= 0 || height_ <= 0)
{
printf("Width and height of FBO must be positive");
return false;
}
height = height_;
width = width_;
glGenFramebuffersEXT(1, &frameBufferIndex);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferIndex);
GLuint depth = (format & FBO_DEPTH_16) ? GL_DEPTH_COMPONENT16 :
(format & FBO_DEPTH_24) ? GL_DEPTH_COMPONENT24 :
(format & FBO_DEPTH_32) ? GL_DEPTH_COMPONENT32 : 0;
if(depth)
{
glGenRenderbuffersEXT(1, &depthBufferIndex);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBufferIndex);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, depth, width, height);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, depthBufferIndex);
}
if(format & FBO_STENCIL)
{
glGenRenderbuffersEXT(1, &stencilBufferIndex);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, stencilBufferIndex);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, width, height);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, stencilBufferIndex);
}
bool result = checkFrameBufferStatus();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
return result;
}
[/QUOTE]
shadow texture setup:
void ShadowMap()
{
//Create the shadow map texture
glGenTextures(1, &shadowMapTexture);
glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
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);
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapSize, shadowMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
//glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
fbo = new FrameBufferObject();
bool working = fbo->initialize(shadowMapSize,shadowMapSize,0);
fbo->bind();
// Instruct openGL that we won't bind a color texture with the currently binded FBO
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
fbo->stop();
}
[/QUOTE]
render for shadow:
void FirstPass()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
fbo->bind();
fbo->switchDepthTarget(GL_TEXTURE_2D, shadowMapTexture);
//First pass - from light's point of view
//Use viewport the same size as the shadow map
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(lightProjectionMatrix);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(lightViewMatrix);
glViewport(0, 0, shadowMapSize, shadowMapSize);
//Draw back faces into the shadow map
glCullFace(GL_FRONT);
//Disable color writes, and use flat shading for speed
glShadeModel(GL_FLAT);
// glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
gFrustum.update();
//Renders all actors in the scene
NxU32 nbActors = gScene->getNbActors();
NxActor** actors = gScene->getActors();
while (nbActors--)
{
NxActor* actor = *actors++;
DrawActor(actor, gSelectedActor, true);
}
terr.RenderALLHeightMap(true);
const GLfloat bias[16] = {
0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0};
glMatrixMode(GL_TEXTURE);
glActiveTextureARB(GL_TEXTURE7);
glLoadIdentity();
glLoadMatrixf(bias);
glMultMatrixf(lightProjectionMatrix.entries); // now multiply by the matrices we have retrieved before
glMultMatrixf(lightViewMatrix.entries);
glMatrixMode(GL_MODELVIEW);
fbo->stop();
}
[/QUOTE]
render:
void SecondPass()
{
//2nd pass - Draw from camera's point of view
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Use dim light to represent shadowed areas
glActiveTextureARB(GL_TEXTURE7);
glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
glEnable(GL_TEXTURE_2D);
gFrustum.update();
//Renders all actors in the scene
NxU32 nbActors = gScene->getNbActors();
NxActor** actors = gScene->getActors();
terr.RenderHeightMap(true);
while (nbActors--)
{
NxActor* actor = *actors++;
DrawActor(actor, gSelectedActor, true);
}
}
[/QUOTE]</div>
The problem is that the entire terrain is getting shadowed rather than just the parts being occluded by the falling boxes.
I’m think my problem is somewhere within the FBO itself but i’m not really sure, I’ve been tweaking it for two days but haven’t gotten any other results.
I also read through the tutorial here: shadow map tut
but was unable to find my problem.
Thanks in advance