需求
手游,对3D及某些UI的渲染结果进行高斯模糊,在模糊的结果上显示另一层UI弹出框。
方案探索过程
GrabPass 2Pass法(纯shader)
- 好处:可以在任意UI节点使用
- 坏处:gpu压力过大,安卓真机帧率60->40,PC感觉没什么压力
- 参考:@ruccho_vector 一篇日文blog
https://qiita.com/ruccho_vector/items/651f760b3240a253bd1d
简单介绍就是两个Pass先横后竖两次模糊,第二次抓取了第一次的结果。
但上面提到的shader算法,如果直接搬运会发现效率很差,因为shader计算用到了pow,于是个人做了优化,高斯的权重计算结果可以缓存,需要的见:“源码汇总”
GrabPass 1Pass法(纯shader)
- 好处:同上
- 坏处:效率比上面还差,说明瓶颈并不在GrabPass本身,而在于每个像素都得过量取样。
而GrabPass本身不能降低分辨率而跳过一半像素去计算,如果真的一定要沿这个思路走就得用CommandBuffer了。
后处理法 OnRenderImage
- 好处:可以先降分辨率再计算,最终真机就掉了5fps。
- 坏处:不太灵活。
对overlay无效,以及需要将需要模糊的和不需要模糊的UI强行分两个Canvas,项目内本身的弹出框上再弹出多层弹出框还想模糊就比较蛋疼了。
方案参考:
毛星云版github
其它 - RT、CommandBuffer
其实也可以输出到RT再插入Image,还有说使用CommandBuffer,因为后处理法过得去所以未再细究,而CommandBuffer据说性能会跟GrabPass差不多差所以更不用试了。
参考资料
原理篇
高斯模糊原理:
https://zh.wikipedia.org/wiki/%E9%AB%98%E6%96%AF%E6%A8%A1%E7%B3%8A
GrabPass
https://docs.unity3d.com/2018.4/Documentation/Manual/SL-GrabPass.html
Graphics.Blit
https://docs.unity3d.com/2018.4/Documentation/ScriptReference/Graphics.Blit.html
CommandBuffer 命令缓冲
https://docs.unity3d.com/2018.4/Documentation/Manual/GraphicsCommandBuffers.html
实践篇
@浅墨_毛星云:
【Unity Shader编程】之十五 屏幕高斯模糊(Gaussian Blur)后期特效的实现 https://blog.csdn.net/poem_qianmo/article/details/51871531
高品质后处理:十种图像模糊算法的总结与实现 https://zhuanlan.zhihu.com/p/125744132
Unity Shader-后处理:高斯模糊
https://blog.csdn.net/puppet_master/article/details/52783179
grabpass纯shader @ruccho_vector 一篇日文blog
https://qiita.com/ruccho_vector/items/651f760b3240a253bd1d
CommandBuffer版
https://github.com/andydbc/unity-frosted-glass
性能相关篇
Unity中GrabPass、OnRenderImage、TargetTexture性能测试
https://zhuanlan.zhihu.com/p/83507625
OnRenderImage 效率探索原理-2
http://www.gamethk.com/news/detail/4751/6.html
tbr(解释为何Grap Pass慢)
https://zhuanlan.zhihu.com/p/301155768
题外话
- opengl 2.0
都说OnRenderImage对opengl 2.0 会特别慢,但现在机型几乎是3.0以上了,so不考虑。而c#内也可判断SystemInfo.supportsImageEffects
2.0替代方案: https://zhuanlan.zhihu.com/p/38520983
unity back buffer
Graphics.PresentAndSync
源码汇总
- GrabPass 2Pass法
1 | Shader "Unlit/UIBlur" |
- GrabPass 1Pass法
1 | Shader "Unlit/UIBlur" |
- 后处理法
毛星云版github