【问题标题】:Basic shadow mapping artifacts using OpenGL and GLSL使用 OpenGL 和 GLSL 的基本阴影映射工件
【发布时间】:2014-12-11 15:10:45
【问题描述】:

我编写了一个关于基本阴影映射技术的简单 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;

截图:

如您所见,self-shadowinh 消失了!但是如果我放大到遮挡物和阴影之间的界限,我们可以看到一个没有阴影的区域。这个工件被称为 Peter Panning 工件。

所以这是一个奇怪的情况:为了避免自阴影伪影,我需要修改光照空间中的顶点深度值。但是深度值训练的这种修改会导致 Peter Panning 伪影!

如果我增加偏移值,问题会更糟。

更新

我也尝试添加偏移量。例如:

tmp_shadow_coords.z += 0.0002f;

截图:

自我阴影较少,但没有 Peter Panning 伪影。但不幸的是,立方体的正面出现了一些伪影。正面有阴影溢出。

如果我增加偏移量:

tmp_shadow_coords.z += 0.0003f;

截图:

自阴影伪影完全消失,但正面阴影溢出更严重。

所以我想知道是否可以在没有自阴影伪影和彼得平移伪影的情况下进行渲染?

【问题讨论】:

  • 您可以再次禁用正面剔除,它将修复部分自身阴影(整个背面将处于黑暗中)和小飞侠
  • 在第一遍中,我通过调用 glEnable(GL_CULL_FACE); 启用正面剔除。 glCullFace(GL_FRONT); ...阴影贴图填充...最后(在第二遍之前)我调用 glDisable(GL_CULL_FACE);禁用面部剔除。我在哪里可以再次禁用正面剔除?我不明白,对不起。
  • 我更新了我的帖子。我已经尝试过这样做,但这次立方体的正面出现了其他伪影(如溢出)。请查看我的更新。

标签: opengl glsl shader shadow-mapping


【解决方案1】:

这很好用。浇注面与受料面非常接近的地方有一个小间隙。

在着色器中正确处理的主要事情是如何应用阴影。通过阴影/遮挡值仅缩放添加的直射光、漫反射和镜面反射项(环境项应单独保留)。一个简单的检查是阴影中的表面应该看起来与在禁用阴影的情况下背对光线的表面完全相同。阴影不应该只是让事物变暗(即finalColour *= 1.0-shadowScalefinalColour -= shadow),而是因为没有直射光。当涉及多个灯光时,这一点变得非常重要。

【讨论】:

    猜你喜欢
    • 2015-02-04
    • 2013-12-27
    • 1970-01-01
    • 2015-01-17
    • 2014-01-16
    • 2014-05-17
    • 1970-01-01
    • 1970-01-01
    • 2015-02-23
    相关资源
    最近更新 更多