opengl - 如何将图像后处理着色器的结果添加到场景中

标签 opengl glsl shader framebuffer

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

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

  6. 设置正 View

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

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

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

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

最佳答案

具体解决这个问题:

so my question is, how can i merge the depthbuffers of my to framebuffers?

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

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

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

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

关于opengl - 如何将图像后处理着色器的结果添加到场景中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13075824/

相关文章:

c++ - 从 .glsl 文件中读取 OpenGL 着色器语言

opengl - 在 OpenGL 中,GL_RED 和 GL_R 颜色格式有什么区别?

c++ - 当我在顶点着色器中有 "out"时,OpenGL 不绘制

c++ - 用于三角形的 OpenGL 3.3 glDrawArrays

javascript - 只有第一个调用适用于具有相同顶点缓冲区的多个drawElements调用

c++ - 这个 CG 程序我做错了什么吗?

c++ - SDL 从纹理中读取像素

opengl - 为什么有些OpenGL参数取0.0-1.0?

python - 我应该使用哪个 OpenGL 基元来绘制三角剖分?

c - 为什么片段着色器没有附加?