概述
1.视锥体剔除(Frustum Culling)这个unity系统自带了好像,就不用操心了。
2.遮挡剔除(Occlusion Culling)
视锥体剔除只是不渲染摄像机视角范围外的物体而对于被其他物体遮挡但依然在视角范围内的物体则不包括在内.
1、带宽是用来宽带的单位,比如一条宽带为50MB带宽的光纤,即为单位时间内最大的数据流量
移动平台体积小,计算能力弱,带宽小
2、3D移动游戏的优化方向
资源优化:
不要在静态物体上附加Animation组件,虽然加了对结果没什么影响,但是会增加CPU开销。
动态物体:主角、NPC、怪物等控制面片数量300–2000面片;Skinned Mesh Renderer 1个;
骨骼数量小于30根;其他物体利用动态合批(相同的材质,不要接收实时阴影,避免非等比缩放)
http://gad.qq.com/article/detail/25980
静态物体:控制网格顶点数少于500个,标记为static;不要附加Animation组件;地形长宽尽量小于257,混合纹理数量不要超过4(纹理混合就是将几张纹理重合在一起显示。最常见的情形是地形纹理。混合纹理可以优化性能,这样只要渲染一次混合后的纹理即可,而不必渲染多次。);纹理格式png或tga,长宽小于1024.尽可能小,够用就好,可使用mipmap模式(mipmap原理:把一张图片按2的倍数进行缩小,直到1x1.把缩小的图都存起来。在渲染时根据一个像素离眼睛的距离,来判断从一个合适的图层取出颜色赋值给像素;
为了加快渲染速度和减少图像锯齿,贴图被处理成由一系列被预先计算和优化过的图片组成的文件,这样的贴图被称为mipmap)
lightMap–一种贴图,烘培后能产生光的反射效果,但不会改变(unity中有一种光脚indirection light间接光,默认都不为间接光,利用lightmap实现间接光)
mipmap–和LOD很相似,离相机的距离来渲染不同的mesh来达到网格面数上的优化,mipmap是在贴图上优化,不同距离使用不同像素的贴图来渲染以达到空间换时间(占用内存增大)。在Texture的mipmap打勾就行了
normalMap–用于shader的法线贴图,是模式更立体
cubeMap–主要用于天空盒
更新不透明贴图的压缩格式为ETC 4bit,因为android市场的手机中的GPU有多种,
每家的GPU支持不同的压缩格式,但他们都兼容ETC格式
对于透明贴图,我们只能选择RGBA 16bit 或者RGBA 32bit。 减少FPS,在ProjectSetting-> Quality中的VSync Count 参数会影响你的FPS,EveryVBlank相当于FPS=60,EverySecondVBlank = 30;这两种情况都不符合游戏的FPS的话,我们需要手动调整FPS,首先关闭垂直同步这个功能,然后在代码的Awake方法里手动设置FPS(Application.targetFrameRate = 45;)降低FPS的好处:1)省电,减少手机发热的情况;2)能都稳定游戏FPS,减少出现卡顿的情况。
待机时,调整游戏的FPS为1,节省电量。
UV值范围尽量不要超过(0,1)。UV模型贴图坐标,UV变化,贴图发生偏移
尽量保证UV值不越界,这对于将来的纹理拼合优化很有帮助。
音频数据
• 播放时间较长的音乐(如背景音乐)
• 建议使用.ogg或.mp3的压缩格式
• 播放时间较短的音乐(如枪声)
• 使用.wav的未压缩音频格式
• 加载方式
• Decompress on load
• Compressed in memory
• Stream from disc
两个都是关于声音格式和导入
https://www.cnblogs.com/fortomorrow/archive/2012/10/31/unity06.html
https://blog.csdn.net/u012565990/article/details/51794486
• Assetbundle
• 依赖关系打包
• 减少资源冗余性(重复)
• 数量不要太多
• 降低IO负担
• Size不要大于1M
• 降低解压过程压力
unity打包出去发布的时候会有包体大小限制,要针对这方面优化
• 程序包数据
• 减小程序包的大小
• 使用压缩格式的纹理
• 使用压缩的网格和动画数据
• 尽量不要使用System.Xml而使用较小的Mono.Xml
• 启用Stripping来减小库的大小 (iOS)
引擎优化:
控制光源数量,一个或者没有,个数越多,draw call越多
• Pixel Light数目
• 1-2个
质量设置
http://www.ceeger.com/Components/class-QualitySettings.html
• 设置分层的远裁剪平面
• 根据物体的体积大小、渲染成本来进行分层(camera.layerCullSpherical)
• 粒子特效
• 屏幕上的最大粒子数
• 建议小于200个粒子
• 每个粒子发射器发射的最大粒子数
• 建议不超过50个
• 粒子大小
• 如果可以的话,粒子的size应该尽可能地小
• 对于非常小的粒子,建议粒子纹理去掉alpha通道
• 尽量不要开启粒子的碰撞功能
物理系统
• 碰撞体控制
• 如果可以的话,尽可能地使用Sphere Collider、Box Collider
• 尽量避免使用Mesh Collider等
• 控制Rigidbody的物理模拟占用
• Rigidbody数量
• Rigidbody API使用
• Static Collider
• Static Collider.Move -> Physics.Simulate
• 添加RigidBody,勾选 isKinematic
• 渲染设置**********************************
• 尽可能地避免Alpha Test和Alpha Blend
• 非常耗时,性价比很低!
• 手工变为较复杂的多边形,以减小透明区域(甚至转为不透明)
• 可将需要 Alpha Test 的面片手工分为两部分,内部作为不透明绘制
(diffuse),边缘部分才用Alpha Test 或 alpha Blend
• 如果必须使用 Alpha Test,尽可能使得这部分面片始终只占屏幕上较小的区域(像素)
• DrawCall Batching
Unity在运行时可以将一些物体进行合并,从而用一个Draw Call来渲染
它们。我们将这一操作称之为“DrawCall Batching”
一般来说,Unity batch的物体越多,你就会得到越好的渲染性能
• Static Batching
• 针对材质相同的静态物体进行batch
• 对几何数据的大小没有限制
• 原理
• 静态VertexBuffer + 动态IndexBuffer
• 在Build过程中,同种材质的物体被合并在一个大的VertexBuffer中
• 在Run-time时,通过视域体裁剪来动态改变IndexBuffer
• 注意
• 使用Static Batching需要额外的内存开销来储存batch后的几何数据
• Dynamic Batching
• 相同材质的动态物体,Unity会自动对其进行batch
• 原理
• 动态VertexBuffer + 动态IndexBuffer
• 注意
• 目前仅支持小于900顶点属性的网格物体
• 如果shader里使用Position,Normal和UV三种属性,那么你只能batch
300顶点以下的物体;如果使用Position,Normal,UV0,UV1和Tangent ,
那你只能batch 180顶点以下的物体
• 进行缩放物体无法与非缩放物体进行batch
• 不同材质在深度尽量不要穿插
• 纹理拼合(Texture Packing)
• 遮挡剔除(Occlusion Culling)
• 没有骨骼动画的模型要除去Animation组件
• 如果Animation不进行缩放,去除Scale Curves
• 减少33%的Blending时间
• 使用Body Mask来减少不必要的计算量
• Optimize Game Objects 能够优化骨骼动画,将无用的骨骼合并
代码优化**********************
time是从程序开始执行到现在的时间,deltaTime上一帧完成的时间,fixedTime表示FixedUpdate已经执行的时间,而fixedDeltatime是一个固定的时间增量。
• 减少Update函数中所做的事情
• 减少Fixed Delta Time
• 将Fixed Delta Time设定在0.04-0.067区间(即每秒15-25帧)
• 降低FixedUpdate函数的调用频率
• 降低物理引擎执行碰撞检测与刚体更新的频率
• 减少不必要的内存分配
• 使用iOS脚本调用优化功能
• Slow and Safe
• Fast and Exceptions Unsupported
• 尽可能地使用 “for”循环来代替“foreach”循环
• 使用 struct 替换 class
• Struct分配的内存在栈上,Class分配的内存在堆上。
• 栈上的内存空间是连续的,且由操作系统负责分配,执行较快。
• 堆上的内存由GC负责回收
• 使用资源缓存池(Object Pool)
• 大量减少Instantiate和Destroy的频率
• 减少GC的频率
• 游戏运行更加流畅
堆内存分配(GC Alloc)
• 加速系统GC的频率
• 增加Mono内存占用
着色器优化:**************************
• 减少复杂的数学计算
• 一些数学函数(如pow、exp、log、cos、sin、tan等)将增大GPU计算的负担,
减少其使用次数,可用查找纹理来代替
• 不要使用discard操作
• 效率低下
• 考虑浮点数计算
• float/highp – 全32位浮点型,适合顶点变换,效率最低
• half/mediump – 缩减的16位浮点型,适合于纹理UV坐标
• fixed/lowp – 10位定点型,适合于颜色,光照计算
• PowerVR特点
• 使用两个vec2变量,而不是将其拼合成一个vec4
在美术制作场景的过程中,会使用到大量的粒子系统。比如场景中的火把。在我们的一个地下城场景中,美术们放置了大量的火把。整个场景中的各个地方,有100来个火把。unity中,在摄像机范围外的粒子系统虽然不会被绘制。但是update是一直持续的。这也就意味着,这100多个火把,不论是否可见都在更新。这个设计应该是很不合理的,在我看过的其他引擎中,都会有一个开关,来控制不可见的粒子系统是否需要update。有的粒子系统在不可见的时候需要更新,比如爆炸。有的不需要更新,比如火堆火把。为了避免不必要的update开销,尤其是最后游戏是要发布到页游平台(web player只能使用一个cpu的核)。于是写了一个脚本,控制不可见的粒子系统就不更新。该脚本主要是用到了2个MonoBehaviour的函数。OnBecameInvisible() 当变为不可见
和 OnBecameVisible() 当变成可见。 要这2个函数起作用的前提是,该GameObject绑定了MeshRender组件。所以,我们要在粒子系统的GameObject放置在一个GameObject 下,且给该GameObject绑定一个MeshRender 与 MeshFilter。MeshFilter中的mesh可以随便找个cube。在Start() 的时候,把最GameObject的scale设置为很小,以保证该cube不被看见。其实遍历所有的child,把active设置为false。在OnBecameVisible 中 遍历所有child,把active设置为true。在OnBecameInvisible中 遍历所有child,把active设置为false。
1、如果你做了一个图集是1024X1024的。此时你的界面上只用了图集中的一张很小的图,那么很抱歉1024X1024这张大图都需要载入你的内存里面,1024就是4M的内存,如果你做了10个1024的图集,你的界面上刚好都只用了每个图集里面的一张小图,那么再次抱歉你的内存直接飙40M。意思是任何一个4096的图片,不管是图集还是texture,他都占用4*4=16M?
2、对于静态物体,采用烘焙光照方法则是更为有效的方法。
• 多用Profiler
• 良好的规划
优化做的好,不如规划做的好!!----那张表
最后
以上就是受伤百合为你收集整理的unity 性能优化的全部内容,希望文章能够帮你解决unity 性能优化所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复