使用 OpenGL/GLSL 使用缩小(下采样)技术的 Bloom 效果
Bloom effect using downscaling (downsampling) technique using OpenGL/GLSL
您好,我正在尝试在我的程序中实现 Bloom 效果。事实上,我已经使用高光通道和单独的高斯模糊通道实现了效果。
这是一个例子:
亮通纹理:
高斯模糊渲染通道(此效果有 2 个内部通道):
最后是最终通道(brightPass + BlurPass):
(我想准确地说,我还没有实现 HDR 色调映射)。
但是我从intel找到了一篇很有意思的文章:
https://software.intel.com/en-us/articles/compute-shader-hdr-and-bloom
它说:
"First the bright pass is performed where values below a specified threshold are filtered out. The bright pass output is then downscaled by half 4 times. Each of the downscaled bright pass outputs are blurred with a separable Gaussian filter and then added to the next higher resolution bright pass output."
我了解它的工作原理,但不了解如何使用 OpenGL 执行纹理缩小。但是我知道如果我使用具有 4 个 mipmap 级别的 glGenerateMipmap() 函数(在我的 FBO 初始化时),我想我将直接使用所需格式(1/16、1/8、1/4 和 1)的 4 个缩小纹理/2) 就像文章里写的那样。
但我的问题是我找不到这样做的方法!
是否存在绑定使用 mipmaping 生成的其他纹理并在片段着色器中使用它们的方法?我是否应该使用 4 个应用不同格式(1/16,...)的独立 FBO 渲染明亮通道 4 次。我认为这是一个解决方案,但它可能对性能不正确。我认为明亮通道应该使用 window 最大尺寸渲染一次,然后使用已经加载到内存中的缩小纹理(mipmap),但我不知道如何将它们绑定并使用到我的着色器中!我真的迷路了。
非常感谢您的帮助!
您可以使用
在着色器中访问特定的 mipmap 级别
gvec4 textureLod(gsampler2D sampler, vec2 P, float lod);
方法,其中 lod 指定 mipmap 级别。 (link to documentation).
您可以按照 BDL 的建议使用 textureLod,但我认为没有真正需要这样做。
生成所需的 mipmap 级别后,将根据活动渲染缓冲区的大小自动选择正确的级别。
您提到的文章的主要思想是,他们对不同大小的源执行多个模糊步骤。
生成 mipmap 层级后,您将拥有 4 个 mipmap 层级,分别表示来自 bright pass 的 1/16、1/8、1/4 和 1/2 缩放纹理。
您应该使用相同大小(分别为 1/16、1/8、1/4 和 1/2)的渲染缓冲区来模糊每个缓冲区。
如果您要渲染的渲染缓冲区是来自明亮通道的源纹理的 1/16 比例,那么将使用第 4 个 mipmap 级别。所以你不需要手动指定 mipmap 级别。
您好,我正在尝试在我的程序中实现 Bloom 效果。事实上,我已经使用高光通道和单独的高斯模糊通道实现了效果。
这是一个例子:
亮通纹理:
高斯模糊渲染通道(此效果有 2 个内部通道):
最后是最终通道(brightPass + BlurPass):
(我想准确地说,我还没有实现 HDR 色调映射)。
但是我从intel找到了一篇很有意思的文章:
https://software.intel.com/en-us/articles/compute-shader-hdr-and-bloom
它说:
"First the bright pass is performed where values below a specified threshold are filtered out. The bright pass output is then downscaled by half 4 times. Each of the downscaled bright pass outputs are blurred with a separable Gaussian filter and then added to the next higher resolution bright pass output."
我了解它的工作原理,但不了解如何使用 OpenGL 执行纹理缩小。但是我知道如果我使用具有 4 个 mipmap 级别的 glGenerateMipmap() 函数(在我的 FBO 初始化时),我想我将直接使用所需格式(1/16、1/8、1/4 和 1)的 4 个缩小纹理/2) 就像文章里写的那样。
但我的问题是我找不到这样做的方法!
是否存在绑定使用 mipmaping 生成的其他纹理并在片段着色器中使用它们的方法?我是否应该使用 4 个应用不同格式(1/16,...)的独立 FBO 渲染明亮通道 4 次。我认为这是一个解决方案,但它可能对性能不正确。我认为明亮通道应该使用 window 最大尺寸渲染一次,然后使用已经加载到内存中的缩小纹理(mipmap),但我不知道如何将它们绑定并使用到我的着色器中!我真的迷路了。
非常感谢您的帮助!
您可以使用
在着色器中访问特定的 mipmap 级别gvec4 textureLod(gsampler2D sampler, vec2 P, float lod);
方法,其中 lod 指定 mipmap 级别。 (link to documentation).
您可以按照 BDL 的建议使用 textureLod,但我认为没有真正需要这样做。 生成所需的 mipmap 级别后,将根据活动渲染缓冲区的大小自动选择正确的级别。 您提到的文章的主要思想是,他们对不同大小的源执行多个模糊步骤。 生成 mipmap 层级后,您将拥有 4 个 mipmap 层级,分别表示来自 bright pass 的 1/16、1/8、1/4 和 1/2 缩放纹理。 您应该使用相同大小(分别为 1/16、1/8、1/4 和 1/2)的渲染缓冲区来模糊每个缓冲区。 如果您要渲染的渲染缓冲区是来自明亮通道的源纹理的 1/16 比例,那么将使用第 4 个 mipmap 级别。所以你不需要手动指定 mipmap 级别。