存在一个视觉差异,光的视锥范围以外的区域也会被判定为处于阴影之中。这是因为当投影坐标超出光的视锥范围时,其值会比1.0大,此时采样的深度纹理就会超出他默认的范围[0,1]。根据纹理环绕方式,我们将会得到不正确的深度结果,它不是基于真实的来自光源的深度值。

我们希望超出深度范围的坐标,深度值为1.0,这样超出的坐标将永远不在阴影之中(深度值最大为1.0)。我们可以配置一个纹理边界颜色,然后把深度贴图的纹理环绕选项设置为 GL_CLAMP_TO_BORDER。
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
float borderColor[] = {1.0f, 1.0f, 1.0f, 1.0f};
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);

现在如果我们采样深度贴图[0,1]范围以外的区域,纹理函数总会返回一个1.0的深度值,由此得到的阴影值始终为0.0。但是图中还是有一部分是阴影区域,这是因为那部分区域的坐标超出的光的视锥的远平面。通过阴影方向可以看到,这片阴影区域总是出现在光源视锥的远平面外。
当一个点在光源空间的z坐标大于1.0时,表示该点超出了远平面。这种情况下,GL_CLAMP_TO_BORDER环绕方式不起作用,这是因为在进行深度比较时,z>1.0的结果始终为真值。我们可以当投影向量的z坐标大于1.0时,将shadow factor的值强制设置为0.0:
if(projCoords.z > 1.0)
shadow = 0.0;

1103

被折叠的 条评论
为什么被折叠?



