欢迎关注“数天技术”!作者介绍:数字天空项目组客户端工程师 – 文立

导语

在游戏界面显示时,通常会对背景进行模糊,使显示界面更加清楚。此外,在处理景深(Depth of Field)和泛光(Bloom)等后处理特效时,模糊效果也是必不可少的。本文针对移动平台,结合实际项目中遇到的UI背景模糊显示效果,讨论了模糊效果的优化解决方案。

为了测试不同方案的实际模糊性能,新建了一个较为简单的测试工程,并使用了2款较为低端的手机进行测试:红米4,处理器为骁龙625和三星Galaxy C5,处理器为骁龙617。在没有背景模糊效果时,2款手机的帧率都稳定在60FPS左右。

高斯模糊

说到模糊效果,必然提及高斯模糊。

高斯模糊通常用来减少图像噪声,降低细节层次和图像模糊等,其利用高斯滤波函数处理图像。

简单地讲,高斯模糊就是对图像中的每个像素进行加权平均,利用高斯核函数对像素周围的多个采样点加权相加,结果作为新的像素值。在实现时,可以预先计算归一化的二维高斯核函数。当采用n阶高斯核函数时,算法的复杂度是Ο(n²)

一种常见的优化方案是将二维运算拆分成两次一维运算,先在水平方向做一维高斯运算,再在竖直方向做一次高斯运算,以7阶二维高斯运算为例,二维运算需要49次计算,拆分成两次一维运算只需要14次计算,大大降低了计算消耗。

一维0均值高斯函数数学表示如下:

此外,因为背景图片本来就要进行模糊,没有必要按照全分辨率进行采样,对背景图片进行降采样可以提升模糊计算效率。

最初项目里采用的模糊方案就是优化高斯模糊算法。

GrabPass {}Pass{ … } // 处理水平方向GrabPass {}Pass{ … } // 处理垂直方向

利用2次GrabPass进行截屏,截屏结果一次进行水平方向模糊处理,一次进行垂直方向模糊处理,2次处理都用了9个采样点。由于进行了2次截屏,然后进行高斯处理,性能消耗挺大的。游戏在一些手机上开启模糊时较为卡顿,性能较差。

利用测试工程进行测试,结果在红米上帧率只有40FPS,在三星上帧率只有20FPS。可以看到,在低端机上这样处理的性能损耗还是很大的,比较严重的影响了游戏体验。

初步优化方案就是减少2次处理的采样点数,从9个减为7个,并且发现原来的采样坐标计算是在fragment shader中计算,会对性能产生一定影响,改在vertex shader中计算,然后传到fragment shader中。

再次测试,在红米上帧率提升到46FPS,在三星上仍然只有22FPS,比之前结果稍好一点。

因为移动端使用GrabPass性能消耗较大,考虑只用一次截屏,利用原始高斯模糊算法进行测试,因为原始计算采样点数较多,所以只使用了5阶高斯核函数。

fixed4 col = fixed(0, 0, 0, 0);for (int s = 0; s 5; ++s){for (int t = 0; t 5; ++t){half4 uv = i.grabuv + _GrabTexture_TexelSize * half4(s - 2, t - 2, 0, 0) * _BlurRadius;col += tex2Dproj(_GrabTexture, uv) * GaussWeight[s][t];}}return col;

测试结果在红米上帧率降到20FPS,三星上帧率降到13FPS。果然还是采样点数过多,计算消耗太大。

后来考虑过使用后处理或者RenderTexture,但是这样会对前景界面产生影响,不能很好地产生背景模糊效果。

Scriptable 

Render Pipeline

为了不使用GrabPass,减少性能开销,尝试从Unity的渲染管线看看能不能在渲染背景遮罩之前进行截屏处理。

在2018年,Unity官方推出了Scriptable Render Pipeline(可编程渲染管线),用户可以根据自己项目的实际需要自定义渲染管线,或者使用官方开放的2个模板:LightweightRenderPipeline和HighDifinitionRenderPipeline,目前这2个渲染管线还处于测试当中,会有一些变动。在LightweightRP中,可以自定义ScriptableRenderPass,并可以自定义RenderPassEvents,目前预设了BeforeRendering,Before/AfterRenderingShadows,Before/AfterRenderingPrepasses,Before/AfterRenderingOpaques,…,AfterRendering等系列事件。

因为UI界面都是在Transparent阶段进行绘制的,如何在背景遮罩之前增加一个pass进行模糊处理,仍未找到一个好的办法,可能是我对可编程渲染管线理解尚不深刻,虽然没有找到方法,还是做个记录,后面可以继续研究。

Kawase模糊

最后还是采用2个GrabPass,但是要对高斯模糊算法再次优化,后面发现了一种优化高斯模糊算法的Kawase模糊算法。

Kawase模糊算法最先是由Masaki Kawase在GDC2003上提出的,是一种性能优于高斯模糊算法,但是模糊效果稍差的解决方案。该算法最初用于泛光效果,效果十分接近高斯模糊。

Kawase滤波器是一个多通道滤波器,每个通道都会利用上一通道的结果,通过累加足够的滤波通道逼近高斯滤波器。在每个通道中,对距离当前像素一定距离的矩形范围的采样点进行平均更新当前像素值。处理通道的数量和距离像素中心的距离可以根据结果灵活调整。

5通道Kawase模糊,采样距离分别为0, 1, 2, 2, 3

测试采用2个通道,每个通道处理4个采样点,通道采样距离逐渐增加,具体数值可以调整。

采样代码如下:

fixed4 col = fixed4(0, 0, 0, 0);col += tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab[0]));col += tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab[1]));col += tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab[2]));col += tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab[3]));col *= 0.25;return col;

测试结果在红米上帧率未见明显下降,在三星上稳定在28FPS左右,达到还算流畅的效果。模糊效果相比高斯模糊稍差一点,但是仍然可以接受。Kawase模糊只用4个采样点,能够获得比较不错的模糊效果,是一种不错的解决方案。

最后将项目中使用的9阶高斯模糊算法和Kawase模糊算法进行实际对比,如图所示:

(a)优化高斯算法

(b)Kawase算法

从图中可以看出,Kawase算法的模糊效果稍差于高斯算法,但是考虑到Kawase算法每个通道只用了4个采样点,算法消耗明显降低,模糊效果也是可以接受的,仍是一种不错的模糊方案。

总结

采用原始高斯模糊算法,虽然只用一次截屏,但是采样点数过多,即使只是5阶,计算消耗仍然太高,移动端性能承受不了。采用2次截屏方案,优化高斯算法分成2次一维模糊处理,大大减少了采样点,性能有所提升,但仍对帧率有较大影响,通道采样点数可以根据模糊效果和机器性能进行选择,一般采用5个或7个采样点;Kawase模糊算法每个通道只用4个采样点,减少了计算消耗,性能最好,并且显示效果比较接近高斯模糊,是一种不错的模糊方案。

另外,对于Shader编写有一些常见的优化:

1. 使用合适的数值精度:

0.0-1.0范围内的颜色值通常使用低精度变量fixed表示;

位置数据通常使用高精度float;

光照计算中的法线和向量通常使用中等精度half;

不清楚时,数据默认采用高精度float。

2. 延后向量计算

先进行标量计算,再进行向量计算

3. 使用Uniforms或Constants变量,而不是在Shader中计算

4. 避免动态查找

避免在fragment shader中对纹理坐标进行数学计算,在vertex shader中计算。

uniform sampler2D textureSampler;fixed4 frag(v2f i){   half2 modifiedTexCoord = half2(1 – i.vTexCoord.x, 1 – i.vTexCoord.y);   fixed4 col = texture2D(textureSampler, modifiedTexCoord);return col;}

参考资料

https://blog.csdn.net/poem_qianmo/article/details/51871531

https://software.intel.com/en-us/blogs/2014/07/15/an-investigation-of-fast-real-time-gpu-based-image-blur-algorithms

http://www.daionet.gr.jp/~masa/archives/GDC2003_DSTEAL.ppt

https://developer.apple.com/library/archive/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/BestPracticesforShaders/BestPracticesforShaders.html

-END-

数天技术

让技术·更有趣

unity 手机 模糊效果_GUI背景模糊效果优化相关推荐

  1. Unity手机游戏发热发烫优化指南与技巧

    Unity手机游戏发热发烫优化指南与技巧 很多小伙伴做完游戏后,发布到Android,运行,游戏很流畅,也不卡顿,但是跑一会游戏,手机就发热,发烫.客户提出需求,能否让它不发烫? 本文从以下3方面来分 ...

  2. uniapp去掉顶部导航栏后计算手机安全区距离,css背景模糊效果

    问题: 1.uniapp去掉顶部导航栏后计算手机安全区距离 2.模糊背景的局部清晰 3.去除overflow: auto:带来的滚动条(没有滚动条也可以滚动) 4.监测页面滑动使用的方法 5.data ...

  3. html背景视频模糊效果,视频背景如何模糊效果 ae视频模糊效果怎么做

    有时候在看一些新闻视频啊,什么娱乐新闻的时候,视频上面的中间是一个小画面,然后它的背景视频是模糊的,但模糊的画面是跟中间那个视频一样的,那么这样的模糊的效果是怎么做成的呢?这种有点像视频画中画的风格, ...

  4. OpenCV4.x图像处理实例-仿微信视频通话背景模糊效果

    仿微信视频通话背景模糊效果 新版微信视频通话支持背景模糊功能.本文将演示如何实现该功能效果. 主要步骤如下: 对视频流进行人像与背景分割 对分割的背景进行模糊处理 对已经模糊的背景加上毛玻璃效果 将人 ...

  5. html css部分背景模糊效果,CSS3实现模糊背景的三种效果示例

    不开头了,直接进入主题. 普通背景模糊效果如下: 使用属性: filter:(2px) 普通背景模糊 为了美观不能使背景前的文字模糊,而filter属性会使这整个div的后代并且还会出现白边.也就是说 ...

  6. css实现背景模糊效果

    最近在工作中写样式的时候碰到如图这样的背景模糊效果,思来想去没有合适的方法.后查询相关资料后得出解决方案 方法:background-color + backdrop-filter 来配合实现 bac ...

  7. Unity大型场景程序化生成及优化技术—FPS迷宫生成和优化

    Unity大型场景程序化生成及优化技术-FPS迷宫生成和优化 1.知名游戏中的大型场景生成 场景程序化生成技术是一个广泛应用在游戏开发中的技术,较早的使用这类技术有名游戏<暗黑破坏神>系列 ...

  8. Unity 蓝湖 关于UI工作流优化的思考(二)

    背景和历史版本在下面这篇博客中查看: Unity & 蓝湖 关于UI工作流优化的思考 最新版本: 本文旨在让不会使用Unity的其他人员在简单了解该工具后,可以帮助研发人员搭建Unity中的U ...

  9. Unity手机游戏开发:从搭建到发布上线全流程实战

    前言: 技术书籍是学习技术知识的重要资源之一.读技术书可以帮助我们学习新技能和知识,技术书籍提供了可靠的.全面的信息,帮助我们快速学习新技能和知识.同时技术书籍有助于保持你的竞争力,因为它们提供了最新 ...

最新文章

  1. R把天数据按照不同时间粒度聚合数据(Aggregate)
  2. sqoop同步hdfs与mysql端口_使用Sqoop将数据在HDFS与MySQL互导
  3. 电话无人应答转总机的配置方法
  4. JDBC的开发流程是什么?
  5. 在MapPath的Path参数中不允许字符'..',解决方法。
  6. Hive笔记之JOIN的左外链接和右外链接
  7. C++: error: call of overloaded ‘abs(int)’ is ambiguous
  8. 信息学奥赛一本通(1003:对齐输出)
  9. HTML placeholder
  10. 各执一词,民用安防市场现状看法PK
  11. 记录——《C Primer Plus (第五版)》第八章编程练习第三题
  12. Centos7+LVS-DR+Apache负载均衡web实验
  13. ttc文件linux安装,Linux当中如何安装字体?
  14. COMSOL模拟卡门涡街的模型
  15. 2023年东北大学外国语言学及应用语言学考研上岸经验贴
  16. friendly发音_friendly是什么意思
  17. 异步电机无差拍模型预测电流控制(MPCC)
  18. 和平精英官方网站静态页面制作与学习html+css保姆级教程
  19. 彩色图像色彩空间原理(理论篇—6)
  20. r7 3700u性能怎么样 相当于英特尔什么水平

热门文章

  1. Matlab实现字符串分割
  2. 小程序获取sessionkey_小程序,足不出户获取更多客源
  3. 102.怎么学好软件工程?软件工程 = 工具 + 方法 + 过程
  4. python中callable什么意思_Python中callable的理解?
  5. Oracle 原理: 初步认识程序包
  6. 理解单片机系统—汇编语言
  7. 启明云端分享|乐鑫ESP32-WROOM-32E和ESP32-WROOM-32UE两款模组的区别
  8. 正点原子stm32f407开发板pcb图_#试用名单公布#正点原子ARM Linux开发板I.MX6ULL
  9. python history没有定义_python AttributeError:'Tensor'对象没有属性'_keras_history'_python_酷徒编程知识库...
  10. 计算机科学与技术专业导论_教育部最新公布!西安工业大学新增4个本科专业!...