木匣子

Web/Game/Programming/Life etc.

Bloom Effect

最近一个月深入学习了一下 OpenGL ES 2.0 和 GLSL,终于把以前一直想尝试的一些效果给理解清楚了。

例如一些塔防/空战游戏中的激光,使用的效果名为 bloom effect 或者叫 glow effect,实现方式是将游戏画面实时高斯模糊,然后以 gl.blendFunc(gl.ONE, gl.ONE) 的混合模式叠加至原图中,达到高光的效果:GPU GEMS - Chapter 21. Real-Time Glow

为此游戏画面不能直接绘制到屏幕上,而是先画至纹理,然后使用该纹理进行高斯模糊,得到另一张纹理,最后将这两个纹理混合画到屏幕上。

这样的话,渲染的工作量就会变得非常大,而且需要更多的显存来存放中间产物。所以有必要对其进行优化。

拜读了 An investigation of fast real-time GPU-based image blur algorithms 这篇文章后,学到了不少的优化技巧:

  1. 高斯模糊实质是一种低通滤波器,图像上的高频信息会丢失,所以处理模糊效果的时候可以将图像缩小,将少工作量。处理完后,再放大回原来的大小使用。
  2. 高斯模糊可分为水平模糊和竖直模糊两个步聚进行,于是对于每个像素,原本需要处理 N*N 次(N为模糊直径),分离后可以减少至 N+N 次。不过需要要多一层中间纹理。

以下是我用 WebGL 实现的一个小 DEMO

对纹理采样进行一点小修改,就可以产生这种像素光效的效果: