游戏蛮牛学习群(纯技术交流,不闲聊):159852603
游戏蛮牛 手机端
开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

开发者专栏

关注:2335

当前位置:游戏蛮牛 技术专区 开发者专栏

__________________________________________________________________________________
开发者干货区版块规则:

  1、文章必须是图文形式。(至少2幅图)
      2、文章字数必须保持在1500字节以上。(编辑器右下角有字数检查)
      3、本版块只支持在游戏蛮牛原创首发,不支持转载。
      4、本版块回复不得无意义,如:顶、呵呵、不错......【真的会扣分的哦】
      5、......
__________________________________________________________________________________
查看: 1321|回复: 12

[士郎] Unity 后处理 性能优化

[复制链接]  [移动端链接]
排名
3
昨日变化

6887

主题

7411

帖子

2万

积分

Rank: 16

UID
1231
好友
185
蛮牛币
9920
威望
30
注册时间
2013-7-29
在线时间
3539 小时
最后登录
2018-10-22

社区QQ达人活力之星原创精华达人突出贡献奖财富之证游戏蛮牛QQ群会员蛮牛妹VIP

发表于 2018-8-10 10:59:22 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
  • OnRenderImage 的性能问题

在我们看到的后处理教程,或者后处理插件中,通常的处理方式是,在OnRenderImage方法中,处理后处理。

1.jpg



在我刚开始整合后处理的过程中,发现,即使不做任何后处理,仅仅一句Graphics.Blit(source, destination),也会导致严重的掉帧,这看起来是不符合逻辑的。在google后,找到问题的说明Post Process Mobile Performance : Alternatives To Graphics.Blit , OnRenderImage,原因如下


2.jpg

我的解决方案如下:
3.jpg

也就是,在OnPreRender中,奖rendertexture赋值给camera,在OnPostRender中,处理后处理渲染。

通过这种方案,能大幅度减少掉帧。我们测试过,用同样的后处理(例如bloom)在使用OnRenderImage的时候,从60 FPS 掉到40 FPS左右,改用pre post方法后,从60 FPS,掉到55 FPS左右,改善明显(用中低端手机测试效果明显些,我们是用的360手机。不同手机,改善的程度略有差异,但是还是能看到至少几帧的提升)。


相信这个优化方案,有不少同学之前已经看到过,并已经在使用。
这个方案,略有麻烦的一点是,当我们的camera开启MSAA或者HDR的时候,会导致后处理不起效果。我猜测应该是MSAA和HDR会激活unity内部的渲染流程必须走OnRenderImage。


(这里要特别注意的一点是,我们用的是Gamma color Space,如果我们要HDR的效果,最好不要用pre post这个优化方式,因为经过测试下来,会导致负优化,帧数反而下降,目前我还没找到好的办法,这里我们按照不需要HDR效果来说)
我们还是可以支持MSAA,解决方案是,根据QualitySettings.antiAliasing和我们的来创建temp 的rendertexture,同时,我们需要关闭摄像机的MSAA和HDR选项。
4.jpg
5.jpg

这里要注意处理的逻辑是:当我们在游戏设置界面开关后处理的时候,要配对地处理camera的MSAA 选项和rendertexture 的创建参数,以免出现后处理不起作用,或者关闭后处理后,抗锯齿没有正确开启的问题。


这应该是一个能立竿见影的优化,相对需要注意处理好一些细节和各种设置切换的处理,做好测试。



  • 合并多个后处理效果

当我们使用unity早期的Image Effect,或者一些单个效果后处理插件的时候,他们通常没有考虑整合的效率问题。以OnRenderImage的做法举例:通常是每个效果是一个脚本,他有自己的OnRenderImage,如果我们有4个效果,那就是4个单独的OnRenderImage,这在代码层面的简洁性和易扩展性上,当然是有优势的。但是,这样做,性能是有问题的,我们需要尽量将各种后处理效果,整合到同一个OnRenderImage(或pre post方法)中,这样能带来一些性能提升,虽然不如上面的pre post效果明显,但是优化是一点点积累的,也是值得做。



具体方法,Unity-Technologies/PostProcessing这个就比较有代表性,它将所有的效果,整合到同一个OnRenderImage,同一个shader中处理,只是通过材质的EnableKeyword来开关对应的功能。这块我就不展开讲了,大家看链接里的代码,最实在。



这里提一句,如果用pre post方式优化,将不能和OnRenderImage方式在同一个camera下混用,这里整合的时候,要根据项目的需求,处理好。我们现在是用unity 那个 post processing方案,改为pre post的方式。



同时,大家使用各种后处理插件,效果,要注意根据需求做一些裁剪,某些不需要的效果,尽量注释或删除,让整合的代码,更加清晰可读,也减少一些额外的性能消耗(shaderlab内存等)。


  • 修改材质属性,不要使用string

通常的例子代码中,会使用string作为key的方式来修改mat的属性,很多shader的插件内,也是这么用的。



6.jpg
                                                                                                      string的方式

7.jpg



这里,我们通过反编译可以看到,string的方式,实际上会调用Shader.PropertyToID,所以,我们应该将整个id cache下来,通过id的方式来调用

8.jpg

9.jpg




这也是一个很小的点,但是如果是后处理这种,可能每帧都会调用的地方,可能带来的优化,还是很有意义的。







还有一些优化,比如减少rendertexture的尺寸等,在网上很多关于优化的文章中都有提到,就不具体说了,网上能搜到很多。





总结一下,主要的优化,就是OnRenderImage转换为pre post的方式,能大大地改善后处理的渲染效率(opengles2 和 opengles3都测试过)。我们使用的Unity版本是5.6.4,其他版本未测试,如果用其他版本,大家需要自己先测试一下。



无论优化多好,后处理,始终还是对性能影响很大,特别是手机电量不足或者发热导致手机降频的时候,后处理将会导致掉帧加重。如果必须要使用后处理(策划,美术要求),那么做好性能开关,优化好后处理的性能,是必须要做的。我们也在进一步优化中,大家有好的优化心得和方案,也可以在评论里回复,谢谢大家。



最后说明一点:pre post的优化方案,只有在不需要HDR效果下,才有优化效果(基于我的测试),如果需要HDR效果,还是用OnRenderImage来做吧。这块优化,需要多多测试,不注意就容易出问题哦。图形渲染方面是我的弱项,希望大家指正。


知乎@Gordon


跟我念“站长妹纸萌萌哒!”我说站长,你说YO!爱你们么么哒~
回复

使用道具 举报

5熟悉之中
692/1000
排名
3526
昨日变化

2

主题

80

帖子

692

积分

Rank: 5Rank: 5

UID
98662
好友
2
蛮牛币
1748
威望
0
注册时间
2015-5-8
在线时间
214 小时
最后登录
2018-9-30
发表于 2018-8-10 14:19:07 | 显示全部楼层
支持支持支持支持支持支持支持支持支持支持

回复 支持 反对

使用道具 举报

5熟悉之中
695/1000
排名
6171
昨日变化

2

主题

331

帖子

695

积分

Rank: 5Rank: 5

UID
112390
好友
2
蛮牛币
850
威望
0
注册时间
2015-7-7
在线时间
154 小时
最后登录
2018-10-22
发表于 2018-8-10 14:52:39 | 显示全部楼层
学习了,谢谢分享

回复

使用道具 举报

7日久生情
3302/5000
排名
1931
昨日变化

0

主题

2122

帖子

3302

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
219676
好友
1
蛮牛币
2417
威望
0
注册时间
2017-7-12
在线时间
514 小时
最后登录
2018-10-22

活力之星

发表于 2018-8-10 16:42:50 | 显示全部楼层
谢谢分享

回复

使用道具 举报

6蛮牛粉丝
1398/1500
排名
1622
昨日变化

0

主题

403

帖子

1398

积分

Rank: 6Rank: 6Rank: 6

UID
87577
好友
0
蛮牛币
4660
威望
0
注册时间
2015-3-31
在线时间
241 小时
最后登录
2018-10-22
发表于 2018-8-10 17:01:06 | 显示全部楼层
too good too strong!

回复 支持 反对

使用道具 举报

7日久生情
2137/5000
排名
2815
昨日变化

1

主题

1375

帖子

2137

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
119154
好友
0
蛮牛币
2282
威望
0
注册时间
2015-8-21
在线时间
271 小时
最后登录
2018-10-22
发表于 2018-8-10 17:03:32 | 显示全部楼层
谢谢楼主大大。

回复

使用道具 举报

3偶尔光临
205/300
排名
46139
昨日变化

0

主题

12

帖子

205

积分

Rank: 3Rank: 3Rank: 3

UID
64429
好友
0
蛮牛币
326
威望
0
注册时间
2014-12-29
在线时间
190 小时
最后登录
2018-9-30
发表于 2018-8-12 22:19:07 | 显示全部楼层
本帖最后由 leosaac 于 2018-8-12 22:20 编辑

我们很早就这么做了(大约1年半前),还有个优化点:就是Camera.SetTargetBuffer,使用这个方法指定ColorBuffer和DepthBuffer,在foward下依然可以几乎没什么消耗的获取到深度图。对于后期中的景深效果、AO效果应该还是很有帮助的,如果是类似于防护罩之类的可以在和物体相交处显示高亮的特效,需要读取深度的(用深度图取得世界坐标),这个也是个好东西。之后还有个优化方法,就是双缓冲(其实是Temproal技术),奇数帧用A buffer,偶数帧用B buffer渲染非透明对象,这样的话可以对扭曲效果提供很大的支持,因为避免了一次截屏消耗,抗锯齿也可以用TAA了。

回复 支持 反对

使用道具 举报

6蛮牛粉丝
1467/1500
排名
1951
昨日变化

0

主题

376

帖子

1467

积分

Rank: 6Rank: 6Rank: 6

UID
136635
好友
0
蛮牛币
1469
威望
0
注册时间
2016-2-15
在线时间
431 小时
最后登录
2018-10-22
发表于 2018-8-13 09:17:53 | 显示全部楼层
大神,谢谢分享

回复

使用道具 举报

排名
15519
昨日变化

0

主题

13

帖子

68

积分

Rank: 2Rank: 2

UID
292037
好友
0
蛮牛币
154
威望
0
注册时间
2018-8-1
在线时间
13 小时
最后登录
2018-8-30
发表于 2018-8-13 09:36:48 | 显示全部楼层
感谢楼主分享,又涨见识了!

回复 支持 反对

使用道具 举报

5熟悉之中
740/1000
排名
6952
昨日变化

29

主题

245

帖子

740

积分

Rank: 5Rank: 5

UID
254245
好友
3
蛮牛币
8602
威望
0
注册时间
2017-11-14
在线时间
314 小时
最后登录
2018-10-22
发表于 2018-8-13 09:57:23 | 显示全部楼层
感谢楼主分享

回复

使用道具 举报

4四处流浪
426/500
排名
5610
昨日变化

0

主题

72

帖子

426

积分

Rank: 4

UID
71644
好友
0
蛮牛币
687
威望
0
注册时间
2015-1-28
在线时间
120 小时
最后登录
2018-10-22
发表于 2018-8-13 14:00:13 | 显示全部楼层
感谢分享

回复

使用道具 举报

7日久生情
3179/5000
排名
2316
昨日变化

0

主题

2276

帖子

3179

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
185339
好友
1
蛮牛币
4554
威望
0
注册时间
2016-11-20
在线时间
327 小时
最后登录
2018-10-22
发表于 2018-8-17 09:11:37 | 显示全部楼层

回复

使用道具 举报

5熟悉之中
695/1000
排名
6171
昨日变化

2

主题

331

帖子

695

积分

Rank: 5Rank: 5

UID
112390
好友
2
蛮牛币
850
威望
0
注册时间
2015-7-7
在线时间
154 小时
最后登录
2018-10-22
发表于 2018-8-18 12:48:51 | 显示全部楼层
学习了,谢谢分享                                          

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

快速回复 返回顶部 返回列表