2
votes

I've done environment mapping with cubemaps and shadow mapping in one direction with a 2D texture, but using a cube map for shadow mapping in all directions is giving me a lot of trouble.

I recently found out that the depth value I was getting from textureCube() was always zero. I had assumed this line was working since I was using similar code as with environment maps and shadow mapping for a 2D texture, and also because gDEBugger shows that the shadow map is being copied to memory properly.

Here is part of the shader code for shadow mapping along with my debugging tests...

uniform samplerCube shadowMap;
varying vec3 worldFragPosition, worldLightPos;

...

vec3 lightToFrag;
float shadowMapDepth;
bool inShadow;

inShadow = false; //used to darken color at the end
if (shadowMapEnabled)
{
    lightToFrag = worldFragPosition - worldLightPos;
    shadowMapDepth = textureCube(shadowMap, lightToFrag).r;

    if (shadowMapDepth > .75)
    {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 0.0);
        return;
    }
    else if (shadowMapDepth > .5)
    {
        gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0);
        return;
    }
    else if (shadowMapDepth > .25)
    {
        gl_FragColor = vec4(0.0, 0.0, 1.0, 0.0);
        return;
    }
    else if (shadowMapDepth > 0.0)
    {
        gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0);
        return;
    }
    else if (shadowMapDepth < 0.0)
    {
        gl_FragColor = vec4(1.0, 0.0, 1.0, 0.0);
        return;
    }
    else
    {
        //... shadow mapping code
    }
}

The else is always taken and the scene is rendered using broken shadow mapping code (everything is in shadow currently as the compared depth is zero).

I've tested lightToFrag before to ensure it isn't zero, and have explicitly tested shadowMapDepth against zero (despite being a float). I've also tested the entire return value of textureCube(shadowMap, lightToFrag) to ensure it is the zero vector.

The only thing I can think of as to why the depth is always zero would be if the texture is not binded correctly, but I don't think I'm forgetting anything...

samplerShadowMapLoc = glGetUniformLocation(progId, "shadowMap");
shadowMapEnabledLoc = glGetUniformLocation(progId, "shadowMapEnabled");

    ....

glUniform1i(shadowMapEnabledLoc, true);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_CUBE_MAP, light->getShadowMap()->getShadowMapId());
glUniform1i(samplerShadowMapLoc, 3);

for (unsigned int i=0; i < objects.size(); i++)
    if (objects.at(i)->getID() != light->getParent()->getID()) //don't draw light, it doesn't need shadows
        render(objects.at(i));
glUniform1i(shadowMapEnabledLoc, false);
render(light->getParent());

glUniform1i(shadowMapEnabledLoc, false);

What might cause textureCube to return a zero vector? Any help would be appreciated.

2
Maybe have a look at this, helps, just started to get into it, so can't really help you....niktehpui

2 Answers

1
votes

Only newer hardware supports render-to-depth-cubemap, and you must have the latest drivers. Also, you must be using a supported format; check the specs of your card to be sure. But that's the most obvious possible problem.

0
votes

This probably won't be much help (I too would like to known the right way to do omni shadows in one pass with a cubemap, none of the info I could find was complete enough to help me) but...

Are you sure you're rendering to your cubemap correctly ? According to this SO question, you need a geometry shader to render to a cubemap.