我编写了一个关于基本阴影映射技术的简单 OpenGL 测试应用程序。
我已经移除了大多数伪影,除了封堵器背面的伪影。这个背面受到伪影的影响,因为在第一个渲染通道(阴影深度图填充)期间,我启用了正面剔除。因此,我有自阴影 z 战斗伪影。
为了解决这种问题,它在几个教程中说,光照空间中顶点位置的深度需要偏移一个非常小的偏移量,如 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;
截图:
如您所见,self-shadowinh 消失了!但是如果我放大到遮挡物和阴影之间的界限,我们可以看到一个没有阴影的区域。这个工件被称为 Peter Panning 工件。
所以这是一个奇怪的情况:为了避免自阴影伪影,我需要修改光照空间中的顶点深度值。但是深度值训练的这种修改会导致 Peter Panning 伪影!
如果我增加偏移值,问题会更糟。
更新
我还尝试添加偏移量。例如:
tmp_shadow_coords.z += 0.0002f;
截屏:
自我阴影较少,但没有 Peter Panning 伪影。但不幸的是,立方体的正面出现了一些伪影。正面的阴影溢出。
如果我增加偏移量:
tmp_shadow_coords.z += 0.0003f;
截屏:
自阴影伪影已经完全消失,但正面的阴影溢出更糟。
所以我想知道是否有可能在没有自阴影伪影和彼得平移伪影的情况下进行渲染?