最快的方法来模糊后处理中一点的所有内容

时间:2012-06-19 23:27:27

标签: 3d shader blur render-to-texture

我正在使用Ogre3D和它的合成器。

基本上,我想知道在视口中动态点周围模糊所有内容的最快方法是什么。该点由2D屏幕坐标给出。像素距离该点越远,它应该越模糊。 为了让您了解它应该具有多少模糊,如果模糊点恰好位于屏幕中间,则边缘应该最大程度地模糊。因此像素的模糊系数可以被认为是

MIN(   (normalizedDistanceBetween(pixel,blurringPoint)/0.5),   1.0)

所以我假设正确的方法是首先使用着色器制作完全模糊的场景版本。那部分我已经。

现在,如何将这个模糊的图像与原始场景混合?我看到两种方式:

  1. 将原始和模糊版本输入到合成器着色器,让它计算上述公式的距离和结果,使用结果混合。
  2. 设置一个额外的渲染到纹理传递,它将使用上面的公式来渲染“混合纹理”。这一点的意思是混合纹理可以比屏幕小得多,甚至可能是16x16,结果也没有太大差异。然后,将原始场景,模糊版本和混合纹理输入到最终合成器着色器,这将简单地从每个像素的混合纹理中采样值,并使用它将两个场景版本混合在一起。
  3. 第二种方法有意义吗?它会比第一个有明显的性能提升吗? (甚至几个fps?)或者创建一个额外的RTT传递和纹理是否通过不计算每个输出像素的(相当简单的)距离函数来减轻所有性能?我假设屏幕尺寸是正常的,比如1024x768,即比16x16混合纹理大得多。或者还有其他更简单的方法吗?

1 个答案:

答案 0 :(得分:1)

任何一个版本都可能具有性能优势。除非你做的事情特别低效,否则两种方式都应该相当快。

如果你真的很关心它,你应该实现它们并对它们进行基准测试。


如果您还没有这样做,可以通过以半分辨率生成模糊缓冲区来加快效果。这需要一个好的重采样滤波器,以避免在读取原始场景时出现混叠(我建议至少使用[1,3,3,1]高斯,并且可能更宽,如[1,5,10,10,5,1])

事实上,如果你想要一个特别宽的最大模糊,你可以重复这个过程,生成一个多分辨率图像金字塔。 (一旦你对原版进行了下采样,一切都变得便宜了,因为半分辨率意味着1/4像素)


另一种可能的加速(再次,如果你还没有尝试过):由于你的合成器正在与你的原始图像进行直接的alpha混合,它实际上并不需要对它进行采样。相反,您可以输出Alpha通道,渲染到原始缓冲区,并使用光栅化器功能进行最终合成。