您的位置:首页 > 移动开发 > Unity3D

unity 优化2

2016-07-01 11:40 246 查看
角色优化

要做到对Unity角色的优化,我们在确定角色的时候就要为角色使用一个Skinned Mesh Renderer,这里大家需要注意的是必须是使用一个SkinnedMesh Renderer,因为Unity对角色采用优化的时候是对其使用可见的裁剪和更新的方法进行优化,而这种优化必须是在角色使用一个Skinned Mesh Renderer的基础上才能实现的

摄像机的优化

对于Unity摄像机的优化就要考虑到一个距离的运用,我们首先要将摄入的物体进行分层,大物体曾设置的可视距离要大一点,相反的小物体层的可视距离就要相应进行调成小一点的距离,这样才能避免距离的不平衡而导致摄入一些不必要的物体进行渲染,从而降低Unity的性能。

静态物体优化

对于静态物体,我建议大家要精确的计算定点数以及UV的取值范围,并且不要在静态物体上添加Animation组件,这里给大家介绍我自己的经验,一般,静态物体的定点少于500,UV的取值在(0,1)区间。这样做对于Unity的纹理拼合优化很有帮助。

顶点性能的优化

顶点的数量确定要根据不同的设备进行分类讨论,一般来说对于刚上市的系统以及刚更新的系统设备上建议每帧渲染不超过40000点,而在一些相对较老的设备上,建议每帧渲染顶点在10000以下,这样既能保证设备使用的正常还能提高Unity运行的效率。

光照性能优化

对于光照的使用也是非常有考究的,并不是所有的物体都能千篇一律的采用统一的光照效果,在提高Unity性能的前提下,应该尽量避免任何给定物体同时被多个光源照亮的情况,而对于静态物体,则要采用烘焙光照方法才是最合适的。

Draw Call性能优化

Unity每次在准备数据并通知GPU渲染的过程称为一次Draw Call。一般情况下,渲染一次拥有一个网格并携带一种材质的物体便会使用一次Draw Call。对于渲染场景中的这些物体,在每一次Draw Call中除了在通知GPU的渲染上比较耗时之外,切换材质与shader也是非常耗时的操作。Draw Call的次数是决定性能比较重要的指标。对于IOS平台上来说,Draw Call应该控制在20此以内,这个值可以在Game视图窗口中的Statistic面板中查看。

unity3D 对于移动平台的支持无可厚非,但是也有时候用Unity3D开发出来的应用、游戏在移动终端上的运行有着明显的效率问题,比如卡、画质等各种问题。自己在做游戏开发的时候偶有所得。对于主要影响性能的因素做个总结。

现在的游戏跑起来会有接近130-170个左右的DrawCall,游戏运行起来明显感觉到卡,而经过一天的优化,DrawCall成功缩减到30-70个,这个效果是非常显著的,并且这个优化并没有通过将现有的资源打包图集来实现,图集都是原有的图集,如果从全局的角度对图集再进行一次优化,那么DrawCall还可以再减少十几个

本次优化的重点包括:层级关系和特效

对于U3D,我是一个菜鸟,对于U3D的一些东西是一知半解,例如DrawCall,我得到的是一些并不完全正确的信息,例如将N个纹理打包成一个图集,这个图集就只会产生一个DrawCall,如果不打成图集,那么就会有N个DrawCall,这个观点在很多人的认识里都是正确的,因为可以通过简单的操作来验证,但严格来说,这个观点是错误的,因为它还受层级关系影响!

1)渲染顺序

U3D的渲染是有顺序的,U3D的渲染顺序是由我们控制的,控制好U3D的渲染顺序,你才能控制好DrawCall

一个DrawCall,表示U3D使用这个材质/纹理,来进行一次渲染,那么这次渲染假设有3个对象,那么当3个对象都使用这一个材质/纹理的时候,就会产生一次DrawCall,可以理解为一次将纹理输送到屏幕上的过程,(实际上引擎大多会使用如双缓冲,缓存这类的手段来优化这个过程,但在这里我们只需要这样子认识就可以了),假设3个对象使用不同的材质/纹理,那么无疑会产生3个DrawCall

接下来我们的3个对象使用2个材质,A和B使用材质1,C使用材质2,这时候来看,应该是有2个DrawCall,或者3个DrawCall。应该是2个DrawCall啊,为什么会有3个DrawCall???而且是有时候2个,有时候3个。我们按照上面的DrawCall分析流程来分析一下:

1.渲染A,使用材质1

2..渲染B,使用材质1

3..渲染C,使用材质2

在这种情况下是2个DrawCall,在下面这种情况下,则是3个DrawCall

1.渲染A,使用材质1

2..渲染C,使用材质2

3.渲染B,使用材质1

因为我们没有控制好渲染顺序(或者说没有去特意控制),所以导致了额外的DrawCall,因为A和B不是一次性渲染完的,而是被C打断了,所以导致材质1被分为两次渲染

那么是什么在控制这个渲染顺序呢?首先在多个相机的情况下,U3D会根据相机的深度顺序进行渲染,在每个相机中,它会根据你距离相机的距离,由远到近进行渲染,在UI相机中,还会根据你UI对象的深度进行渲染

那么我们要做的就是,对要渲染的对象进行一次规划,正确地排列好它们,规则是,按照Z轴或者深度,对空间进行划分,然后确定好每个对象的Z轴和深度,让使用同一个材质的东西,尽量保持在这个空间内,不要让其他材质的对象进入这个空间,否则就会打断这个空间的渲染顺序

在这个基础上,更细的规则有:

场景中的东西,我们使用Z轴来进行空间的划分,例如背景层,特效层1,人物层,特效层NGUI中的东西,我们统一使用Depth来进行空间的划分

人物模型,当人物模型只是用一个材质,DrawCall只有1,但是用了2个以上的材质,DrawCall就会暴增(或许对材质的RenderQueue进行规划也可以使DrawCall只有2个,但这个要拆分好才行),3D人物处于复杂3D场景中的时候,我们的空间规则难免被破坏,这只能在设计的时候尽量去避免这种情况了

使用了多个材质的特效,在动画的过程中,往往会引起DrawCall的波动,在视觉效果可以接受的范围内,可以将特效也进行空间划分,假设这个特效是2D显示,那么可以使用Z轴来划分空间

2/)打包图集

每个材质/纹理的渲染一定是会产生DrawCall的,这个DrawCall只能通过打包图集来进行优化

制作图集一般遵循几个规则:

从功能角度进行划分,例如UI可以划分为公共部分,以及每个具体的界面,功能上,显示上密切相关的图片打包到一起不要一股脑把所有东西打包到一个图集里,特别是那些不可能同时出现的东西,它们就不应该在一个图集里,这样的图集意义不大,减少不了DrawCall,并且一个你不需要显示的图片,会一直占用你的内存,这让我非常不爽

注意控制图集的大小,不要让图集太大,一个超级大图集的DrawCall消耗或许顶的上十几个小图集的消耗字符图集,在使用BMFont或者其他工具生成图片字的时候,我们往往是直接导入一大串文字,然后直接生成图片,但实际上这上面的操作也有优化空间,例如BMFont生成的图片大小,是可以设置的,有两个规则,一个规则是导出的图片尽量小,另一个是导出的图片尽量少,默认的大小应该是512x512,假设你生成的图片256x256就可以容纳,那么多做一个操作你可以节省这么多空间,另外当你输入多几个字,就导致增加一张图片时,例如1024变成2048,那么你可以考虑使用3张512的图片,这样也会节省空间

经过精心划分的图集在加上精心规划的渲染顺序,DrawCall会有一个质的优化

3) 特效清理

U3D提供了非常便捷的方法让我们很轻易地使用美术给过来的特效,懒惰的U3D程序猿会直接放入U3D,甚至不去看这是个什么特效,我们的特效一般都是一瞬间的事情,例如技能特效,或者其他什么特效,那么特效播放完,这个特效我们就看不到了,但假设这个特效在播放结束的时候,没有将自身的Active属性设置为false,那么它就会继续占用你的DrawCall,消耗你设备的计算能力,所以程序需要保证当一个特效播放完之后,能够被消耗,或者设置为非激活的状态,可以使用一些公共方法来完成特效播放完之后的清理工作(自己实现2个静态函数,一个播放完销毁,一个播放完设置未激活)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  unity 优化