使用 OpenGL/GLSL 的 HDR Bloom 效果渲染管线

HDR Bloom effect rendering pipeline using OpenGL/GLSL

我已经使用 OpenGL 和 GLSL 集成了 bloom HDR 渲染...至少我认为!我不太确定结果。

我遵循了英特尔网站上的教程:

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

关于高斯模糊效果,我严格遵循以下网站上有关性能的所有建议:

https://software.intel.com/en-us/blogs/2014/07/15/an-investigation-of-fast-real-time-gpu-based-image-blur-algorithms

根据第一个网站:

"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. The final output is a ¼ size bloom which is up sampled and added to the HDR output before tone mapping."

这里是 bloom 流水线(上图取自 NSight NVIDIA Debugger)。

我测试的window的分辨率是1024x720(为了这个算法的需要这个分辨率会缩小4倍)

第 1 步:

Lighting pass(material pass + shadow mask pass + skybox pass 的混合):

第 2 步:

将高光信息提取到明亮通道中(准确地说,生成了 4 个 mipmap 纹理("The bright pass output is then downscaled by half 4 times" -> 1/2、1/4、1/8,最后是 1/2)):

第 3 步:

"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."

我想准确地说,双线性过滤已启用 (GL_LINEAR),上面图片上的 pexilization 是在 NSight 调试器上调整纹理大小的结果 window (1024x720 ).

a) 分辨率 1/16x1/16 (64x45)

“1/16x1/16 模糊输出”

b) 分辨率 1/8x1/8 (128x90)

“1/8x1/8 缩小的明亮通道,结合 1/16x1/16 模糊输出”

“1/8x1/8 模糊输出”

c) 分辨率 1/4x1/4 (256x180)

“1/4x1/4 缩小的明亮通道,结合 1/8x1/8 模糊输出”

" 1/4x1/4 模糊输出"

d) 分辨率 1/2x1/2 (512x360)

“1/2x1/2 缩小的明亮通道,结合 1/4x1/4 模糊输出”

“1/2x1/2 模糊输出”

为了达到所需级别的 mipmap,我使用 FBO 调整大小(但使用在初始化时已经调整大小的单独 FBO 比多次调整同一个 FBO 可能更聪明。您如何看待这个想法?) .

第 4 步:

色调映射渲染通道:

到此为止,我想听听外部对我工作的建议。对不对?我不太确定结果,尤其是第 3 步(缩小和模糊部分)的结果。

我觉得虚化效果不是很明显!但是我使用了 35x35 的卷积核(我认为这就足够了:))。

但我真的对 pdf 上的一篇文章很感兴趣。这是布隆管道的介绍(介绍与我应用的完全相同)。

Link:

https://www.google.fr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CCMQFjAA&url=https%3A%2F%2Ftransporter-game.googlecode.com%2Ffiles%2FRealtimeHDRImageBasedLighting.pdf&ei=buBhVcLmA8jaUYiSgLgK&usg=AFQjCNFfbP9L7iEiGT6gQNW6dB2JFVcTmA&bvm=bv.93990622,d.d24

从图上可以看出模糊出血效果比我的强多了!你认为作者使用了几个卷积核(更高分辨率)吗?

首先我不明白的是高斯模糊算法如何使第三张图片上出现不同于白色(灰度值)的其他颜色。我非常仔细地(高变焦)观察明亮的图片(第二张),所有像素似乎都接近白色或白色(灰度)。有一件事是肯定的:明亮的纹理上没有蓝色或橙色像素。那么我们如何解释从图 2 到图 3 的这种转变呢?这对我来说很奇怪。

第二个不明白的是图3、4、5、6的blur bleeding effect差别很大!在我的演示中我使用了35x35的卷积核,最后的结果接近这里的第三张图

你如何解释这样的差异?

PS:请注意,我使用 GL_HALF_FLOAT 和 GL_RGBA16F 像素内部格式来初始化 bloom 渲染通道纹理(所有其他渲染通道都初始化为 GL_RGBA和 GL_FLOAT 数据类型)。

我的程序有问题吗?

非常感谢您的帮助!

模糊的小分辨率纹理看起来不够模糊。我认为过滤器的宽度(不是样本数量,而是样本之间的距离)或帧缓冲区大小存在问题。

假设您有 150x150 的原始 fbo,一个 15x15 的 bloom 缩小版本。并且您使用 15x15 模糊滤镜。

模糊的高分辨率版本会影响明亮部分周围的 7px 描边。 但是在模糊低分辨率图像时,内核的宽度实际上会影响整个图像区域。在低分辨率下,7px 笔划意味着 - 整个图像区域。因此,模糊低分辨率版本中的所有像素都会对最终合成图像产生一些影响。因此,高分辨率模糊图像会对明亮部分周围的 7px 笔划产生模糊,而低分辨率模糊图像会对整个图像区域产生相当大的差异。

你的低分辨率图像看起来模糊得不太好,因为它们的贡献仍然保持在明亮部分周围的 35/2 像素描边范围内,这是错误的。

我希望我能解释清楚哪里出了问题。具体要更改什么,可能是视口大小同时模糊低分辨率图像,但我不能 100% 确定。