Unity 关于仿崩坏3部分Bloom(部分泛光)效果实现原理(附源码)

之前写每个物体的材质球控制屏幕bloom效果,由于性能问题,换了另外一种实现方式

部分泛光的功能,这个是之前写的,不过性能不行,如果简单的游戏还可以,如果大场景的话就不行了

 

原理分析

我这边就研究崩坏3编译过的源码,下面是分析崩坏bloom效果实现

1.我看崩坏编译过的源码基本所有shader都会有一个_BloomFactor,这个用于控制泛光强度,用于存储输入屏幕那张图的alpha通道上

2.泛光强弱图:通过source的rendertexture的alpha乘以source的RGB,就得到一张泛光强弱图

3.泛光图:根据泛光的亮度阈值来获取一张那些地方需要发光的图

4.泛光图模糊:按照泛光图4个大小依次递半的(1/4,1/8,1/16,1/32)尺寸的rendertexture来进行高斯模糊,得到的四张图进行叠加

5.最终效果图:原图+泛光模糊图

PS:最近遇到一个问题就是点光源(顶点模式除外),影响rendertexture的alpha通道(会使alpha通道变大)

之前的方案是alpha值越大就越亮,加了点光源,本来暗的东西都变亮,所以为了解决点光源问题,我们就反过来写,alpha值为1就没有bloom效果,就是alpha越小就越亮,mask图就是越黑越亮

让我突然想起之前抓取崩坏的渲染,一张白色为主的mask图,才明白人家做成这样是有他道理,我自己搞从黑色开始的mask图

最终方案:存储的alpha值越小,bloom效果越强烈

实现难点

2,3,4都比较容易,百度一下就有

关于存储alpha

1.对于Geometry渲染队列的直接在shader输入颜色的alpha直接修改就可以

standard存储alpha值

surface shader存储alpha值

2.对于半透的渲染物体来说(特效)因为输出本来就带alpha值,这个需要我们加一个pass来存储alpha值

第一个pass需要加ColorMask RGB(避免影响alpha存储)

第二个pass需要加ColorMask A(避免影响第一个pass输出颜色)

粒子shader alpha通道存储

(对于粒子系统,如果不用bloom效果就不要用改过可以存储alpha通道的shader,直接用原来没加alpha存储的版本

因为粒子系统,有两个pass的情况,相同材质球不能合并drawcall)

 

因为我看崩坏那些特效源码都是用两个pass,所以反推是这样用的,在实际项目中确实有效,不过多了pass,不过比之前那个方案渲染多一份来得快得多

 

下面是输出屏幕的图source的alpha通道

下面是旧版的图,我就懒得更新,正常颜色应该和下图相反

这图可以在framedebug里面看到,选中alpha通道就可以

Unity 关于仿崩坏3部分Bloom(部分泛光)效果实现原理(附源码)_第1张图片

下面是优化过的bloom和扭曲效果

下面是提取出来的demo

链接:https://pan.baidu.com/s/1q4OcQlAFF5Zjm480pwdpPw 
提取码:zahv 

 

 

 

你可能感兴趣的:(Shader)