如何在OpenGL中绘制一个镜像反射的物体?

4
据我了解,在OpenGL中镜像的实现是先绘制场景,然后翻转整个场景并重新绘制,只让它在镜子里可见,从而创建一个完美翻转的镜像。但我发现问题在于,当这样做时,只有在之前渲染过的镜子后面才能看到其他镜子。因此,如果我先渲染镜子1再渲染镜子2,镜子1就无法看到镜子2,但是镜子2可以看到镜子1。那么,如何有效地实现一个不会出现这种情况的镜子镜像呢?
2个回答

4

在IT技术中,有两种常见的渲染反射方式,即使用多个/递归反射...

  1. 将场景渲染到纹理中,并将该纹理应用到镜面表面。

    优点是可以使用前一帧其他镜子的镜面纹理。虽然会引入一些小延迟,但当您想要透过多个镜子看时,它不会影响性能。如果这是一个问题,您可以在主相机渲染之前重新渲染反射纹理几次。

    如果镜子不是完全平面的,例如水面上的涟漪,则也可以使用此方法。实际上,还可以使用立方体贴图来支持近似任意反射。

    enter image description here

  2. 使用门户渲染,就像您说的那样,使用模板缓冲区来掩盖镜面表面,将场景沿着镜子平面翻转并重新渲染。

    镜面渲染只是门户渲染的一种特殊情况。这可以递归地完成,但是随着深度缓冲区的正确管理,它变得相当复杂。您还需要一个空间数据结构来存储场景,以便不必进行完全重新渲染,只需渲染通过镜子可见的部分(否则速度会非常慢)。如果您选择这条路,请慢慢来,并包括大量的视觉调试,使用简单且直观的测试场景。

    enter image description here

    (有很多关于单反射模板缓冲区的页面,但这不是您需要的,所以我不会列出一些)


1
最简单的方法是使用模板缓冲区。请查看此页面
基本思路如下:
- 渲染镜子的表面并标记为1。 - 重新渲染整个场景,由镜子表面反射(可以使用矩阵完成),只在模板缓冲区为1的地方绘制(有效地仅绘制镜子表面)。 - 使用不同的值重复,或清除模板缓冲区以用于其他镜子。如果您想要镜子反射其他镜子,则需要绘制其他镜子表面,在模板缓冲区中标记为2,但仅在已经是1的地方进行绘制。
如果您有镜子反射镜子,则必须执行所有可能的组合(首先渲染镜子1,然后渲染镜子2在镜子1的反射中,然后在原始场景中渲染镜子2,然后在镜子2的反射中渲染镜子1的反射,依此类推…)。
使用此算法无法进行无限的镜子反射(仅限有限次数)。只有光线跟踪才能实现这一点。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接