opengl - 现代无伪影阴影贴图

标签 opengl 3d shadow-mapping

我正在尝试寻找在我的游戏引擎中使用的最佳阴影贴图技术。到目前为止,我已经使用 PCF 实现了标准阴影贴图、级联阴影贴图和方差阴影贴图。然而,它们似乎都没有提供令人满意的结果。

我正在尝试找到适合所有情况的最佳阴影贴图方法。我需要背面正确的几何形状,因此可以使用渲染背面。然而,我也有相当多的低多边形、平滑的法线几何体,即使在绘制背面时也会导致一些非常难看的痤疮。

还有哪些其他技术可以用来获得漂亮的阴影贴图,而不会出现严重的痤疮、彼得平移或轻微出血,而且不会对几何形状(仅背面)造成任何重大限制?

最佳答案

不幸的是,没有通用的方法可以产生无伪影的阴影,但我也许可以给您一些提示。

百分比更接近的过滤不仅是一个很好的起点,而且也是接触硬化阴影的基础(如果您有兴趣,我可以提供有关它的更多信息)。 PCF 基本上比方差阴影映射 (VSM) 或指数阴影映射 (ESM) 等统计算法产生更好的结果,但速度较慢,因为过滤步骤需要 O(n²) 而不是 O(n) 中的可分离滤波器。另一方面,轻微的出血是一种痛苦,并且无法完全消除。

减少甚至消除阴影痤疮的最佳方法是双深度层阴影贴图,它是中点阴影贴图的改进。本文对这两种算法进行了解释:

Weiskopf D.、Ertl T. (2003):“Shadow Mapping Based on Dual Depth Layers”。

该技术需要为每个阴影贴图进行额外的场景渲染(当您使用级联阴影贴图时可能会非常昂贵),但在几乎所有情况下都能产生非常好的结果。当使用现代显卡和几何着色器时,深度剥离可能会以更快的方式实现,从而能够在一次渲染过程中渲染两个深度层。不幸的是,这并不是免费的,而且我还没有使用这种技术的经验。我还没有找到任何可以消除彼得平移和阴影痤疮以及双深度层阴影贴图的技术。

如果您的半影没那么大,您也许能够通过“正常偏移偏差”取得很好的结果,GDC 海报上对此进行了解释:

霍尔伯特·丹尼尔 (2011):“Saying goodbye to shadow acne”。

实现可能有点棘手,但消除了陡坡的最坏情况。请注意,此技术还引入了新的伪影,因为它稍微“移动”了阴影。

总而言之:我投票支持具有双深度层阴影映射的 PCF,并基于拦截器搜索和过滤步骤实现接触强化。其他技术,如指数方差阴影贴图 (EVSM)、总面积方差阴影贴图 (SAVSM) 或屏幕空间技术(mip 映射的屏幕空间阴影贴图)都具有更复杂的实现、光渗色或边缘情况,其中它们只是失败需要后备方法。

对于极高质量和物理精确的阴影,您可以考虑多 View 阴影贴图 (MVSS),它基本上渲染多个阴影贴图并累积它们的光贡献。它们的解释如下:

路易斯·巴沃伊 (2011):“Multi-View Soft Shadows”。

MVSS 非常昂贵,并且只能实时用于场景中的主角或最重要的对象。它在“ bat 侠:阿卡姆之城”中为 bat 侠本人提供。

祝你好运! :-)

关于opengl - 现代无伪影阴影贴图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28789853/

相关文章:

c++ - 空(白色)帧缓冲区 - 阴影贴图

directx - 阴影贴图伪像

OpenGL 3.3 两个 GPU 上具有阴影贴图的 nVidia Optimus 上的两种不同结果

algorithm - 使用计算着色器计算 mipmaps,已经完成了吗?

c - 当您使用负参数调用 glClearColor 时会发生什么?

c++ - glReadPixels 从错误的位置读取

opengl - 如何访问 GLSL 片段着色器纹理中的自动 mipmap 级别?

matlab - MATLAB R2011b 中三角化 3d 曲面的不稳定数据游标行为

c - 棱镜的 3D 空间中两个坐标之间的距离

c# - 基本渲染 3D 透视投影到带摄像头的 2D 屏幕(不带 opengl)