3

我有一个 opengl 上下文,我在其中渲染了几个线框图元。我想在其中一些(不是全部)上应用一些后期处理效果(例如模糊、绽放)。为了实现这一点,我定义了一个带有附加纹理(颜色缓冲区)和渲染缓冲区(深度缓冲区)的屏幕外帧缓冲区。然后,我执行以下操作:

  1. 绑定屏幕外缓冲区
  2. 设置透视图
  3. 绘制我想要模糊的线框图元
  4. 取消绑定屏幕外帧缓冲区并绑定“主”帧缓冲区
  5. 绘制不应进行后处理的更多图元

  6. 设置正交视图

  7. 设置后处理着色器,将屏幕外缓冲区的纹理作为统一参数传递
  8. 绘制全屏四边形

  9. 显示主机缓冲区的内容

问题是,通过将纹理渲染到屏幕外缓冲区并将结果用作 2D 四边形的纹理,我丢失了深度信息,整个场景看起来并不真实。

所以我的问题是,如何将我的深度缓冲区合并到帧缓冲区?或者将模糊或其他片段着色器效果应用于复杂 3D 场景的常用方法是什么?

4

2 回答 2

2

要专门解决这个问题:

所以我的问题是,如何将我的深度缓冲区合并到帧缓冲区?

如果它们是纹理(通过),则没有什么可以阻止您在不同的 FBO 之间共享附件。glFramebufferTexture2D这甚至适用于深度/深度模板缓冲区。afaik 在 GL3 中使用不同大小的附件甚至是有效的。

如果您稍后需要主帧缓冲区(可见窗口)中的深度信息,您可以使用Framebuffer Blitting来复制它。blit 操作非常快。

有很多方法可以处理渲染顺序。个人喜好/灵活性/性能。由于灵活性,我个人尽可能在 FBO 中做尽可能多的事情,并在需要时进行优化。最终的颜色结果也通过 blit 移动到帧缓冲区。

我在某些 linux 驱动程序上以及在某些情况下在 OS X 下共享深度附件(或一般附件)时遇到了问题,并且最终使用 blit 而不是共享深度附件也取得了巨大成功。

于 2012-10-26T00:19:14.520 回答
0

我会使用早期深度测试来实现这一点。这个想法是,您首先将整个场景渲染到深度缓冲区中,即没有颜色写入。接下来进行颜色传递,在此禁用深度写入并使用相同的转换进行深度测试以确保相等。这为您提供了所需的隐藏表面去除。像你已经概述的那样进行颜色传递。现在通过覆盖模糊的图片,它应该看起来没问题(有一些病理情况可能会破坏,但这些可能会使用一些模板缓冲区技巧来修复)。

顺便说一句,您不需要为全屏四边形顶点着色器设置投影。只需通过顶点位置并使用坐标 (-1,-1) (1,-1) (1,1) (-1,1) 作为顶点。

于 2012-10-25T19:52:04.943 回答