Unity

Unity泛光(Bloom)的实现方式

泛光是由于人眼晶状体散射产生的视觉效果,用于产生如梦似幻,朦朦胧胧的感觉。Unity中自带的图像效果中,有两种实现方式,Bloom 和 BloomOptimized,单就泛光来说,两者差不多。不过前者兼顾了HDR和Flare比较复杂,而后者只是单纯的Bloom,下面就BloomOptimized简单分析一下。

同颜色校正一样,Bloom也通过重写OnRenderImage方法,来进行图像处理。首先,对原图像进行DownSample

这里传入Shader的几个参数分别是:
blurSize:模糊尺寸,用于后面模糊算法的直径。
threshold:泛光阈值,颜色亮度超过这个阈值的像素才进行泛光处理。
intensity:泛光强度。

这里的rt是一张原图1/4大小的RenderTexture,通过RenderTexutre.GetTemporary获得,Unity内部维护了一个RenderTexture池,这样获取其实拿到的是一个早已经申请好的RenderTexture,省去了临时申请的开销,而且内部针对特定平台也做了一些优化。如果在一帧中需要中间的RenderTexture,最好使用这个方式来获取临时RenderTexture,但是不用的时候,需要手动释放。RenderTexture.ReleaseTemporary。

还有就是要确保源图像和目标图像,都采用双线性过滤,这是降采样和模糊需要的优先条件。

降采样使用的Shader代码如下:

 

其实这段代码的采样并不是很规整,就是取了目标点周围四个点的平均颜色,然后选出大于阈值的像素,乘上强度系数。小于阈值的直接设为0,这样的像素在后面计算中不会影响其他的像素。

下面对这张1/4屏幕像素的降采样结果进行模糊处理:

Shader中使用的一维的高斯模糊,用先纵向再横向的方式进行了两次模糊处理。

下面是高斯模糊系数数组:

Vertex Shader如下:在顶点上方和下方各取了3个采样点,一共7个。

Fragment Shader如下:

 

各个采样点的颜色使用高斯模糊系数加权相加,就得到了模糊后的像素颜色,横向的算法相同,只不过采样点是在横向上选择的。

最后,把降采样,模糊后的RenderTexture与原图像叠加,就完成了Bloom效果。叠加Shader如下:

下面是效果图,原图:

QQ截图20160104211209

降采样,模糊后的1/4 RenderTexture:

QQ截图20160104211225

叠加后效果:

QQ截图20160104211245