使用OpenGL / GLSL进行HDR Bloom效果渲染管道

时间:2015-05-24 01:12:03

标签: opengl glsl shader

我已经使用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

根据第一个网站:

“然后将明亮的通过输出缩小了4倍。每个缩小的亮通输出都用可分离的高斯滤波器模糊,然后加到下一个更高分辨率的亮通输出。最终输出是1/4大小的绽放在色调映射之前,它被上采样并添加到HDR输出。“

这是bloom管道(上面的图片来自NSight NVIDIA Debugger)。

我测试中窗口的分辨率为1024x720(对于此算法的需要,此分辨率将缩小4倍)。

第1步:

光照传递(材质传递+阴影蒙版传递+天空盒传递的混合):

enter image description here

第2步:

将高光信息提取到明亮的通道中(准确地说,生成4个mipmaps纹理(“亮通过输出然后缩小半个4倍” - > 1 / 2,1 / 4,1 / 8和最后1/2)):

enter image description here

第3步:

“每个缩小的明亮通道输出都使用可分离的高斯滤波器模糊,然后添加到下一个更高分辨率的亮通输出。”

我想确切地说,双线性过滤是启用的(GL_LINEAR),上面图片中的pexilization是将纹理大小调整到NSight调试器窗口(1024x720)的结果。

a)决议1 / 16x1 / 16(64x45)

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

enter image description here

b)第1 / 8x1 / 8号决议(128x90)

“1 / 8x1 / 8缩小的明亮传球,加上1 / 16x1 / 16模糊输出”

enter image description here

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

enter image description here

c)决议1 / 4x1 / 4(256x180)

“1 / 4x1 / 4缩小的明亮传球,加上1 / 8x1 / 8模糊输出”

enter image description here

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

enter image description here

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

“1 / 2x1 / 2降尺度明亮传球,再加上1 / 4x1 / 4模糊输出”

enter image description here

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

enter image description here

为了达到所需的mipmap级别,我使用FBO调整大小(但也许在初始化时使用已经调整大小的FBO会更聪明,而不是多次调整相同的大小。你怎么看待这个想法?)。< / p>

第4步:

色调映射渲染过程:

enter image description here

在此之前,我想对我的工作提出外部建议。它是否正确?我不太确定第3步(降尺度和模糊部分)的结果。

我认为模糊效果不是很明显!但是我使用卷积内核35x35(我认为这就足够了)。)。

但是我对一篇关于pdf的文章非常感兴趣。这是bloom管道的演示文稿(演示文稿与我应用的演示文稿完全相同)。

enter image description here

链接:

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之间的模糊出血效果差异很大!在我的演示中,我使用35x35卷积内核,最终结果接近第三张图片。

你怎么解释这种差异?

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

我的程序有问题吗?

非常感谢你的帮助!

1 个答案:

答案 0 :(得分:1)

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

让我们说你有150x150的原始fbo,一个15x15缩减版本的绽放。并且你使用15x15模糊滤镜。

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

你的低分辨率图像看起来不太模糊,因为它们的贡献仍然在明亮部位的35 / 2px行程内,这是错误的。

我希望我设法解释了什么是错的。什么可以准确地改变,可能是视口尺寸模糊低分辨率图像,但我根本无法100%确定。