我编写了一个关于基本阴影贴图技术的简单OpenGL测试应用程序。
除了封堵器背面的工件外,我删除了大部分工件。这个背面与人工制品有关,因为在第一次渲染过程中(阴影深度图填充),我启用正面剔除。因此,我有自我阴影的z-fighting文物。
为了解决这个问题,它在几个教程中说明了光空间中顶点位置的深度需要偏移一个非常小的偏移,如0.0005f。
这是我的问题的截图(为了可见性,我增加了盒子的环境光值)。这里没有深度偏移:
正如你所看到的,有一种强烈的自我遮蔽。
这是我在片段着色器中使用的一段代码:
if (ShadowCoords.w > 0.0f)
{
vec4 tmp_shadow_coords = ShadowCoords;
tmp_shadow_coords.z -= 0.0000f; //DEPTH OFFSET DISABLE HERE
shadowFactor = textureProj(ShadowMap, tmp_shadow_coords);
}
现在让我们看看当使用等于0.0002f的偏移时会发生什么:
tmp_shadow_coords.z -= 0.0002f;
截图:
正如您所看到的,自阴影减少了。现在让我们尝试使用等于0.0003f的偏移:
tmp_shadow_coords.z -= 0.0003f;
screeshot:
正如你所看到的,自我暗影已经消失了!但如果我缩小遮挡物和阴影之间的界限,我们可以看到一个没有阴影的区域。这个神器被称为Peter Panning神器。
所以这是一个奇怪的情况:为了避免自阴影伪像我需要修改光空间中的顶点深度值。但深度值训练的这种修改导致了彼得·潘宁神器!
如果我增加偏移值,问题会更严重。
更新
我也尝试过添加偏移量。例如:
tmp_shadow_coords.z += 0.0002f;
截图:
没有自我阴影,但没有彼得潘宁神器。但不幸的是,在立方体的正面看起来有些文物。正面有阴影溢出。
如果我增加偏移量:
tmp_shadow_coords.z += 0.0003f;
截图:
自阴影完全消失,但正面的阴影溢出更糟。
所以我想知道是否有可能没有自阴影神器而没有Peter Panning神器的渲染?
答案 0 :(得分:2)
这非常有效。铸件表面非常靠近接收表面有一个小间隙。
在着色器中找到正确的主要方法是如何应用阴影。通过阴影/遮挡值(环境术语应该单独留下)来缩放添加的直接光,漫反射和镜面反射术语。一个简单的检查是,阴影中的表面看起来应该与远离光线的表面完全相同,并且禁用阴影。阴影不应该只是使事物变暗(即finalColour *= 1.0-shadowScale
或finalColour -= shadow
),而是它们没有直射光。当涉及多个灯时,这变得非常重要。