全向阴影贴图

Posted

技术标签:

【中文标题】全向阴影贴图【英文标题】:Omnidirectional Shadow Mapping 【发布时间】:2011-10-31 15:17:19 【问题描述】:

我已经完成了使用立方体贴图的环境贴图和使用 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 对零(尽管是一个浮点数)。我还测试了textureCube(shadowMap, lightToFrag) 的整个返回值,以确保它是零向量。

关于为什么深度总是为零,我唯一能想到的就是如果纹理没有正确绑定,但我认为我没有忘记任何东西......

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 返回零向量?任何帮助将不胜感激。

【问题讨论】:

也许看看this,有帮助,刚开始接触,所以帮不上你...... 【参考方案1】:

只有较新的硬件支持渲染到深度立方体贴图,并且您必须拥有最新的驱动程序。此外,您必须使用受支持的格式;检查您的卡的规格以确定。但这是最明显的问题。

【讨论】:

感谢您的回复。我的笔记本电脑有一个 ATI Mobility Radeon HD 4200 卡。我在feedback.wildfiregames.com/report/opengl/device/… 发现它支持深度立方体贴图。我更新了我的驱动程序(v 11.11)。我不确定如何准确找出支持哪些深度格式,但我一直在尝试使用与 2d 纹理进行单向阴影映射相同的格式:GL_DEPTH_COMPONENT。我只是快速测试了 16 位和 32 位版本,但没有运气。【参考方案2】:

这可能不会有太大帮助(我也想知道使用立方体贴图一次完成全向阴影的正确方法,我能找到的信息都不足以帮助我)但是......

您确定正确渲染到立方体贴图吗?根据this SO question,您需要一个几何着色器来渲染到立方体贴图。

【讨论】:

感谢您的回复。我不记得我发现提到使用几何着色器的任何资源。我认为这个问题涉及其用于相同目的的应用。我几乎可以肯定我正在正确渲染到立方体贴图,因为当我在 gDEBugger 工具中暂停程序并查看纹理内存时,我可以看到对象的深度立方体贴图。

以上是关于全向阴影贴图的主要内容,如果未能解决你的问题,请参考以下文章

确定级联阴影贴图分割范围

✠OpenGL-8-阴影

OpenGL 阴影贴图

阴影贴图未正确投影

阴影贴图上的高斯模糊(FBO/纹理)

一步步学OpenGL 23 -《阴影贴图1》