我已经使用立方体贴图完成环境贴图,并使用 2D 纹理在一个方向上进行阴影贴图,但是使用立方体贴图在所有方向上进行阴影贴图给我带来了很多麻烦。
我最近发现我从 textureCube()
获得的深度值始终为零。我假设这条线是有效的,因为我使用的代码与 2D 纹理的环境贴图和阴影贴图相似,而且 gDEBugger 显示阴影贴图正在正确复制到内存中。
这是阴影映射的部分着色器代码以及我的调试测试...
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
}
}
始终采用 else
并使用损坏的阴影映射代码渲染场景(当前所有内容都在阴影中,因为比较的深度为零)。
我之前测试过 lightToFrag
以确保它不为零,并且明确测试过 shadowMapDepth
是否为零(尽管是 float )。我还测试了 textureCube(shadowMap, lightToFrag)
的整个返回值以确保它是零 vector 。
关于为什么深度始终为零,我唯一能想到的是纹理绑定(bind)不正确,但我认为我没有忘记任何事情......
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);
什么可能导致 textureCube 返回零 vector ?任何帮助将不胜感激。
最佳答案
只有较新的硬件支持渲染到深度立方体贴图,并且您必须拥有最新的驱动程序。此外,您必须使用受支持的格式;检查您的卡的规范以确保。但这是最明显的可能问题。
关于c++ - 全向阴影贴图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7955678/