opengl - 使用 OpenGL/GLSL 的降尺度(下采样)技术实现光晕效果

标签 opengl glsl shader

您好,我正在尝试在我的程序中实现 Bloom 效果。事实上,我已经使用高光 channel 和单独的高斯模糊 channel 实现了该效果。

这是一个例子:

明亮的 channel 纹理:

enter image description here

高斯模糊渲染 channel (此效果有 2 个内部 channel ):

enter image description here

最后是最终 channel (brightPass + BlurPass):

enter image description here

(我想准确地说,我还没有实现 HDR 色调映射)。

但是我发现了英特尔的一篇非常有趣的文章:

https://software.intel.com/en-us/articles/compute-shader-hdr-and-bloom

它说:

“首先执行亮通,其中低于指定阈值的值被滤除。然后将亮通输出缩小一半 4 倍。每个缩小后的亮通输出都使用可分离的高斯滤波器进行模糊处理,然后添加到下一个更高分辨率的亮通输出。”

我明白它是如何工作的,但我不明白如何使用 OpenGL 执行纹理缩小。但是我知道如果我使用 glGenerateMipmap() 函数(在我的 FBO 初始化时)具有 4 个 mipmap 级别,我想我将直接获得具有所需格式的 4 个缩小纹理(1/16、1/8、1/4 和 1)/2) 就像文章中写的那样。

但我的问题是我找不到方法来做到这一点!

是否存在一种方法来绑定(bind)使用 mipmaping 生成的其他纹理并在片段着色器中使用它们?我是否应该使用 4 个独立的 FBO 应用不同的格式(1/16,...)来渲染明亮 channel 4 次?我认为这是一个解决方案,但它的性能可能不正确。我认为明亮 channel 应该使用窗口最大尺寸渲染一次,然后使用内存中已加载的缩小纹理(mipmap),但我不知道如何将它们绑定(bind)并使用到我的着色器中!我真的迷路了。

预先非常感谢您的帮助!

最佳答案

您可以按照 BDL 的建议使用 textureLod,但我认为实际上没有必要这样做。 生成所需的 mipmap 级别后,将根据事件渲染缓冲区的大小自动选择正确的级别。 您提到的文章的主要思想是,它们对不同大小的源执行几个模糊步骤。 生成 mipmap 级别后,您将拥有 4 个 mipmap 级别,分别代表来自亮 channel 的 1/16、1/8、1/4 和 1/2 缩放纹理。 您应该使用相同大小(相应的 1/16、1/8、1/4 和 1/2)的渲染缓冲区来模糊每个缓冲区。 如果您要渲染的渲染缓冲区是明亮 channel 中源纹理的 1/16 比例,则将使用第 4 个 mipmap 级别。因此您无需手动指定 mipmap 级别。

关于opengl - 使用 OpenGL/GLSL 的降尺度(下采样)技术实现光晕效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30282749/

相关文章:

opengl - GLSL 着色器中的恒定浮点值 - 有什么理由使用制服?

glsl - 在片段着色器中绘制矩形

silverlight - HLSL 色调变化算法

c++ - 如何让我的 OpenGL 相机旋转 360 度

c++ - 运行时链接错误 : The procedure entry point glewInit@0 could not be located

opengl - 为什么我不能将 int 成员添加到我的 GLSL 着色器输入/输出 block ?

c++ - 在 OpenGL 中显示立方体的问题

java - 将属性传递到着色器 Libgdx

OpenGL 多 GPU 支持

c++ - OpenGL 视频内存使用