Reputation: 169
I'm having trouble rendering cube shadow map. Negative and positive seem to be reversed and I can't figure out why. Tried to reverse targets and directions, but I get event weirder output.
Code:
// init
glGenTextures(1, &mShadowCubeTex);
glBindTexture(GL_TEXTURE_CUBE_MAP, mShadowCubeTex);
for(int i = 0; i < 6; i++)
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT24, SHADOW_WIDTH, SHADOW_WIDTH, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
/* + filters + wrapping */
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glGenFramebuffers(1, &mShadowFbo);
glBindFramebuffer(GL_FRAMEBUFFER, mShadowFbo);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_COMPONENT, mShadowCubeTex, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// render
static const struct {
GLenum eTarget;
vec3 vDirection;
vec3 vUp;
} oPointLightConfigs[6] = {
{ GL_TEXTURE_CUBE_MAP_POSITIVE_X, vec3( 1.0f, 0.0, 0.0f), vec3(0.0f, 1.0f, 0.0f) },
{ GL_TEXTURE_CUBE_MAP_NEGATIVE_X, vec3(-1.0f, 0.0, 0.0f), vec3(0.0f, 1.0f, 0.0f) },
{ GL_TEXTURE_CUBE_MAP_POSITIVE_Y, vec3( 0.0f, 1.0, 0.0f), vec3(0.0f, 0.0f,-1.0f) },
{ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, vec3( 0.0f,-1.0, 0.0f), vec3(0.0f, 0.0f, 1.0f) },
{ GL_TEXTURE_CUBE_MAP_POSITIVE_Z, vec3( 0.0f, 0.0, 1.0f), vec3(0.0f, 1.0f, 0.0f) },
{ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, vec3( 0.0f, 0.0,-1.0f), vec3(0.0f, 1.0f, 0.0f) }
};
// shadow pass
for(int i = 0; i < 6; i++)
{
glBindFramebuffer(target, mShadowFbo);
glViewport(0, 0, SHADOW_WIDTH, SHADOW_WIDTH);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, oPointLightConfigs[i].eTarget, mShadowCubeTex, 0);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glCullFace(GL_FRONT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for(CModel* pModel : mModels)
{
if(pModel->hasOption(NO_SHADOW_CAST))
{
mNullProgram->use(); // no color output
mat4 M = pModel->getModelMatrix();
mat4 V = lookAt(pPointLight->getPosition(), oPointLightConfigs[i].vDirection, oPointLightConfigs[i].vUp);
mat4 P = mCamera->getProjectionMatrix();
pNullProgram->set("MVP", P * V * M);
pModel->draw();
}
}
}
// color pass
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDrawBuffer(GL_BACK);
glReadBuffer(GL_BACK);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
pLightProgram->use();
glActiveTexture(GL_TEXTURE6);
glBindTexture(GL_TEXTURE_2D, mShadowCubeTex);
pLightProgram->set("V", mCamera->getViewMatrix());
pLightProgram->set("P", mCamera->getProjectionMatrix());
/* set program light uniforms */
for(CModel* pModel : mModels)
{
pLightProgram->set("M", pModel->getModelMatrix());
pModel->draw()
}
// lighting fragment shader
float computeShadowFactor(in samplerCube sShadowMap, in vec3 vL) {
/* vL = vLightPosition - vVertexPosition */
vec3 vLAbs = abs(vL);
float fNear = 0.1;
float fFar = 1000.0;
float fDepth = max(vLAbs.x, max(vLAbs.y, vLAbs.z));
fDepth = ((fFar + fNear) / (fFar - fNear)) - ((2.0 * fFar * fNear) / (fFar - fNear)) / fDepth;
fDepth = (fDepth + 1.0) * 0.5;
float fShadow = texture(sShadowMap, -vL).r; /* -vL = vVertexPosition - vLightPosition */
if(fDepth > fShadow)
return 0.0;
return 1.0;
}
Output:
Update:
I added + oPointLightConfigs[i].vDirection to...
V = lookat(pPointLight->mPosition, pPointLight->mPosition + oPointLightConfigs[i].vDirection, oPointLightConfigs[i].vUp);
Output:
At least now I get one shadow(instead of 6). But it's somehow reversed and the Y axis has no shadow. When the shadow passes from one cubemap face to another it get interrupted. Any hints?
Upvotes: 1
Views: 347
Reputation: 169
These problems were caused by inverted Y's on cubemaps.
I used:
{ GL_TEXTURE_CUBE_MAP_POSITIVE_Y, math::vec3( 0.0f,-1.0, 0.0f), math::vec3(0.0f, 0.0f, 1.0f) },
{ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, math::vec3( 0.0f, 1.0, 0.0f), math::vec3(0.0f, 0.0f, 1.0f) },
for setting up the shadow cubemap and:
vL.y *= -1.0;
inside computeShadowFactor() before sampling the shadow cubemap texture.
Note: My +Z axis goes into the monitor - left hand coordinate system.
Upvotes: 2