2

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.

CCSeth
  • 21
  • 2
  • Maybe have a look at [this](http://http.developer.nvidia.com/GPUGems/gpugems_ch12.html), helps, just started to get into it, so can't really help you.... – niktehpui Oct 31 '11 at 15:26

2 Answers2

1

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.

vpostman
  • 101
  • 1
  • 4
  • Thanks for the reply. My laptop has an ATI Mobility Radeon HD 4200 card. I was able to find out at http://feedback.wildfiregames.com/report/opengl/device/Mobility%20Radeon%20HD%204200 that it supports depth cubemaps. I updated my drivers (v 11.11). I'm not sure how to find out exactly which depth formats are supported, but I've been trying with the same one I had used for single direction shadow mapping with a 2d texture: GL_DEPTH_COMPONENT. I just gave the 16 and 32 bit versions a quick test, but no luck. – CCSeth Nov 19 '11 at 00:40
0

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.

Community
  • 1
  • 1
Nicolas Lefebvre
  • 4,247
  • 1
  • 25
  • 29
  • Thanks for the reply. I can't recall any of the resources I found mentioning the use a geometry shader. I think that question concerns its application for the same purpose. I'm almost positive I'm rendering to the cubemap correctly since when I pause the program in the gDEBugger tool and look at the texture memory, I can see the depth cubemap of the objects. – CCSeth Nov 19 '11 at 00:53