原文地址:html
http://www.cnblogs.com/harlan1009/p/3970584.htmlandroid
优化:
1. 更新不透明贴图的压缩格式为ETC 4bit,由于android市场的手机中的GPU有多种,
每家的GPU支持不一样的压缩格式,但他们都兼容ETC格式,
2. 对于透明贴图,咱们只能选择RGBA 16bit 或者RGBA 32bit。
3. 减小FPS,在ProjectSetting-> Quality中的
VSync Count 参数会影响你的FPS,EveryVBlank至关于FPS=60,EverySecondVBlank = 30;
这两种状况都不符合游戏的FPS的话,咱们须要手动调整FPS,首先关闭垂直同步这个功能,而后在代码的Awake方法里手动设置FPS(Application.targetFrameRate = 45;)
下降FPS的好处:
1)省电,减小手机发热的状况;
2)能都稳定游戏FPS,减小出现卡顿的状况。
4. 当咱们设置了FPS后,再调整下Fixed timestep这个参数,
这个参数在ProjectSetting->Time中,目的是减小物理计算的次数,来提升游戏性能。
5. 尽可能少使用Update LateUpdate FixedUpdate,这样也能够提高性能和节省电量。
多使用事件(不是SendMessage,使用本身写的,或者C#中的事件委托)。
6. 待机时,调整游戏的FPS为1,节省电量。
7. 图集大小最好不要高于1024,不然游戏安装以后、低端机直接崩溃、缘由是手机系统版本低于2.二、超过1000的图集没法读取、致使。
2.2 以上没有碰见这个状况。
注意手机的RAM 与 ROM、小于 512M的手机、直接放弃机型适配。
VSCount 垂直同步
unity3d中新建一个场景空的时候,帧速率(FPS老是很低),大概在60~70之间。
一直不太明白是怎么回事,如今基本上明白了。我在这里解释一下缘由,若有错误,欢迎指正。
在Unity3D中当运行场景打开Profiler的时候,咱们会看到VSync 这一项占了很大的比重。
这个是什么呢,这个就是垂直同步,稍后再作解释。
咱们能够关闭VSync来提升帧速率,选择edit->project settings->Quality。ios
<ignore_js_op>web
在右侧面板中能够找到VSync Count,把它选成Don't Sync。
<ignore_js_op>
这就关闭了VSync(垂直同步),如今在运行场景看看,帧速率是否是提升不少。
如今来讲说什么是垂直同步,要知道什么是垂直同步,必需要先明白显示器的工做原理,
显示器上的全部图像都是一线一线的扫描上去的,不管是隔行扫描仍是逐行扫描,
显示器都有两种同步参数——水平同步和垂直同步。
什么叫水平同步?什么叫垂直同步?
垂直和水平是CRT中两个基本的同步信号,水平同步信号决定了CRT画出一条横越屏幕线的时间,
垂直同步信号决定了CRT从屏幕顶部画到底部,再返回原始位置的时间,
而偏偏是垂直同步表明着CRT显示器的刷新率水平。
为何关闭垂直同步信号会影响游戏中的FPS数值?
若是咱们选择等待垂直同步信号(也就是咱们平时所说的垂直同步打开),
那么在游戏中或许强劲的显卡迅速的绘制完一屏的图像,可是没有垂直同步信号的到达,
显卡没法绘制下一屏,只有等85单位的信号到达,才能够绘制。
这样FPS天然要受到操做系统刷新率运行值的制约。
而若是咱们选择不等待垂直同步信号(也就是咱们平时所说的关闭垂直同步),那么游戏中做完一屏画面,
显卡和显示器无需等待垂直同步信号就能够开始下一屏图像的绘制,天然能够彻底发挥显卡的实力。
可是不要忘记,正是由于垂直同步的存在,才能使得游戏进程和显示器刷新率同步,使得画面更加平滑和稳定。
取消了垂直同步信号,当然能够换来更快的速度,可是在图像的连续性上势必打折扣。
这也正是不少朋友抱怨关闭垂直后发现画面不连续的理论缘由。
合并材质球unity 3d中每倒入一次模型就多一个材质球,可个人这些模型都是共用一张贴图的就想共用一个材质球,因此每次都要删除再附上,很麻烦。怎么才能合并这些材质球?
采用TexturePacking吧
一、遍历gameobject,取出material,并根据shader来将material分类
二、调用Unity自带的PackTextures函数来合并每一个shader分类中的material所对应的textures(PackTextures函数有缺陷,不过能够将就用)
三、根据合并的大的texture来更新原有模型的texture、material已经uv坐标值。
须要注意的是:须要合并的纹理应该是物体在场景中距离相近的,若是物体在场景中的距离较远,
则不建议合并纹理,由于这样作颇有可能非但起不到优化的做用,反而下降了运行效率。
mesh合并
分为2种方式合并
1.自带的合并必须勾选静态。
<ignore_js_op>
全部被勾选了“Static”的GameObject,其中的Mesh Filter中的mesh都会被合并到 "Combined Mesha (root: scene)" 中
2.也能够用脚原本合并mesh 。算法
[C#]
纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
using
UnityEngine;
using
System.Collections;
public
class
MyClass : MonoBehaviour
{
void
Start ()
{
MeshFilter [] meshFilters = GetComponentsInChildren<MeshFilter> ();
CombineInstance[] combine =
new
CombineInstance[meshFilters.Length];
for
(
int
i = 0; i < meshFilters.Length; i++) {
combine [i].mesh = meshFilters [i].sharedMesh;
combine [i].transform = meshFilters [i].transform.localToWorldMatrix;
meshFilters [i].gameObject.active =
false
;
}
transform.GetComponent<MeshFilter> ().mesh =
new
Mesh ();
transform.GetComponent<MeshFilter> ().mesh.CombineMeshes (combine);
transform.gameObject.active =
true
;
}
}
|
1. 先在 Unity 中创建 空物件 ( Empty )
2. 再建立2个 Cube 方块,并放入 空物件底下 (能够改为你本身的模型)
3. 把 MyClass 代码丟进 空物件上 。
4. (可选) 创建一个 Material 材质,而且丢进 空物件上
5. 执行
前
<ignore_js_op>
后
<ignore_js_op>
========================================分割线====================================数组
2-3个
小于30个
300-1500
这是由于角色的动做大多数都是事先设定好的,并不须要通过IK操做来进行实时计算(Rogdoll除外),因此在模型导入时,不要将IK结点一块儿导入。
二、静态实体性能优化
在静态实体上附加Animation部件虽然对结果没有影响,但却会增长必定的CPU开销来调用这一组件,因此尽可能去掉该组件。
小于500
尽可能保证UV值不越界,这对于未来的纹理拼合优化颇有帮助。
三、地形app
长宽均尽可能小于257。这是由于地形太大,会形成大量顶点数据,给你的内存带宽形成必定的影响,在目前的ios设备中,内存带宽是很是有限的,须要尽可能节省。同时,若是用Unity自带的地形,必定也要使用Occlusion Culling,由于Unity的刷地形工具虽然方便,但倒是framekiller,刷过以后,你会发现drawcall增长的很是多。
不要超过4。地形的混合操做是很耗时的,应该尽可能避免。能合并的纹理尽可能合并。
四、纹理less
建议png或tga。不用转成ios硬件支持的PVRTC格式,由于Unity在发布时会帮你自动转的。
长宽小于1024。同时应该尽量地小,够用就好,以保证纹理对内存带宽的影响达到最小。
建议生成Mipmap。虽然这种作法会增长一些应用程序的大小,但在游戏运行时,系统会根据需求应用Mipmap来渲染,从而减小内存带宽。
若是纹理的alpha通道均为1,则用RGB的24位纹理来代替RGBA的32位纹理。(听说Unity内部会进行自动检测)
五、光源编辑器
建议1个,通常为方向光。“Important”个数应该越小越少。个数越多,drawcall越多。
1-2个。
六、粒子特效
建议小于200个粒子。
建议不超过50个。
若是能够的话,粒子的size应该尽量地小。由于Unity的粒子系统的shader不管是alpha test仍是alpha blending都是一笔不小的开销。同时,对于很是小的粒子,建议粒子纹理去掉alpha通道。
很是耗时。
七、音频
使用.ogg或.mp3的压缩格式。
使用.wav和.aif的未压缩音频格式。
八、相机
将远平面设置成合适的距离。远平面过大会将一些没必要要的物体加入渲染,下降效率。
Unity提供了能够根据不一样的layer来设置不一样的view distance,因此咱们能够实现将物体进行分层,大物体层设置的可视距离大些,而小物体层能够设置地小些,另外,一些开销比较大的实体(如粒子系统)能够设置得更小些等等。
九、碰撞
若是能够的话,尽可能不用MeshCollider,以节省没必要要的开销。若是不能避免的话,尽可能用减小Mesh的面片数,或用较少面片的代理体来代替。
十、其余
尽量地减小Drawcall的数量。IOS设备上建议不超过100。减小的方法主要有以下几种:Frustum Culling,Occlusion Culling,Texture Packing。Frustum Culling是Unity内建的,咱们须要作的就是寻求一个合适的远裁剪平面;Occlusion Culling,遮挡剔除,Unity内嵌了Umbra,一个很是好OC库。但Occlusion Culling也并非放之四海而皆准的,有时候进行OC反而比不进行还要慢,建议在OC以前先肯定本身的场景是否适合利用OC来优化;Texture Packing,或者叫Texture Atlasing,是将同种shader的纹理进行拼合,根据Unity的static batching的特性来减小draw call。建议使用,但也有弊端,那就是必定要将场景中距离相近的实体纹理进行拼合,不然,拼合后极可能会增长每帧渲染所需的纹理大小,加大内存带宽的负担。这也就是为何会出现“DrawCall降了,渲染速度也变慢了”的缘由。
Unity在运行时会对static物体进行自动优化处理,因此应该尽量将非运行实体勾上static标签。
尽量地使用prefab的实例化物体,以下降内存带宽的负担。检查实体的PrefabType,尽可能将其变成PrefabInstance,而不是ModelPrefabInstance。
========================================分割线====================================
移动平台相对于PC机,具备体积小,计算弱,带宽少的特色。
所以作手机游戏的开发,优化的方向,与力度对比PC游戏都有所区别。
必需要作到优化流程,合理利用资源。
目前在手机上面,还不可以像PC游戏那样追求高质量渲染效果,为了让手机不那么容易发烫,还要控制cpu,gpu,不能让他们全速运算。
材质方面:
纹理方面,建议使用压缩纹理,
Android上面使用ETC1,苹果上面使用PVRTC。
UV坐标控制在0到1之间,人物模型面数控制在1500内,骨骼控制在30个之内。
场景中使用一个主光(不能再多了)。
尽可能减小alphaTest和alphaBlend材质的使用。在手机上,这是很杀效率的。
骨骼动画方面:
在动画方面能够考虑不使用插值,固定的帧率的动画。
若是要作插值,考虑使用四元数(表示旋转)和向量(表示位移)来作插值。
四元数作插值速度比矩阵来的快,Slerp提供了平滑插值。
========================================分割线====================================
优化的常规技巧
剖析你的游戏。
不要花费时间来优化那些晦涩的代码或者缩减图形文件的大小,除非这是你游戏的瓶颈。
第一次剖析你的游戏将会使你发现你游戏的瓶颈。Apple's Shark是一个很好的用来剖析基于OpenGL的程序的工具。
再次剖析你的游戏。
优化以后不要忘记再剖析一次你的游戏,这样能够检查你所作的优化是否达到了预期的效果。
固然,这样作也可能会使你发现更多的瓶颈。
流程第1、性能第二。花费时间来使你游戏的建立尽量地流畅。
尽量快地修正游戏中的错误将会使你后期更容易优化你的游戏。
在Scene View中测试场景。
这样作将会使你清楚了解这个场景中的物体或者附加在物体上的脚本是否下降了游戏性能。
若是Scene View反应迟钝,那么有多是图形方面的缘由,若是Scene View反应不迟钝,那么瓶颈可能出在脚本或者物理系统上。
禁用指定游戏物体。
在play模式下,尝试禁用并启用游戏物体来排查出游戏慢的缘由。
网格
若是可能的话,把相邻的物体(网格)合并为一个只有一个材质的物体(网格)。好比,你的游戏中包含一个桌子,上面有一堆东西,你彻底能够在3D程序中将它们合并在一块儿(这可能也须要你将这些物体的纹理合并为一个大的纹理集)。减小须要渲染的物体的数量能够极大地提升游戏性能。
不要有没必要要的网格。
若是你的游戏场景中有一我的物,那么他应该是一个网格。若是你有一个船,那么它也应该只是一个网格。
每个网格只用一种材质。
使用极少的面数的网格(好比500个多边形如下)。
最好把你人物的三角面数量控制在1500-2000个之间。
这个数量能够说是游戏质量和性能之间一个均衡值。若是你的模型有四边形,那么在导入模型的时候,引擎将会把每一个四边形变为两个三角形。
光照
像素光。
像素光可让你的游戏看起来效果很牛逼,可是不要使用过多的像素光。
在你的游戏中可使用质量管理器来调节像素光的数量来取得一个性能和质量的均衡点.
性能占用顺序:聚光灯>点光源>平行光。
一个好的点亮场景的方法就是先获得你想要的效果,而后看看哪些光更重要;
在保持光效的前提下看看哪些光能够去掉。
点光源和聚光灯只影响它们范围内的网格。
若是一个网格处于点光源或者聚光灯的照射范围以外,而且光源的attenuate开关是打开的,那么这个网格将不会被光源所影响,这样就能够节省性能开销。
这样作理论上来说可使用不少小的点光源并且依然能有一个好的性能,由于这些光源只影响一小部分物体。
一个网格在有8个以上光源影响的时候,只响应前8个最亮的光源。
贴图
在外观不变的前提下,贴图大小越小越好。
若是你的显卡的显存不够大的话,你游戏中的贴图将会被转存到系统内存中,在显卡调用它们的时候再传到显卡中。
对于比较新的电脑来讲,内存和显卡之间有足够的带宽来达到一个很好的性能;
若是你很无耻地用了巨多的大图片的话,在低显存的电脑上运行你的游戏的时候,你的游戏必然会挂掉。
却是没有必要在图形编辑软件中调整贴图的大小。你能够在unity导入贴图的时候进行调整。
不要使用低质量的图片。
在小播放界面的游戏中使用低质量的jpeg图片或者低色彩的png图片亦或是gif图片没什么问题。
在发布游戏的时候,引擎会自动压缩这些图片,多重压缩和解压将会下降图片的质量,因此最好保持贴图文件的分辨率为原始分辨率。
这样就会减小多重压缩和解压所致使的图片失真现象。
Shaders
多重效果的shader就比看起来样式很单一的shader要更耗费资源。
一样在一个拥有贴图和光反射的物体上,使用VertexLit Diffuse shader无疑是最省资源的。
========================================分割线====================================
在美术制做场景的过程当中,会使用到大量的粒子系统。
好比场景中的火把。在咱们的一个地下城场景中,美术们放置了大量的火把。整个场景中的各个地方,有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。
========================================分割线====================================
Unity 性能优化 Draw Call
Unity(或者说基本全部图形引擎)生成一帧画面的处理过程大体能够这样简化描述:引擎首先通过简单的可见性测试,肯定摄像机能够看到的物体,而后把这些物体的顶点(包括本地位置、法线、UV等),索引(顶点如何组成三角形),变换(就是物体的位置、旋转、缩放、以及摄像机位置等),相关光源,纹理,渲染方式(由材质/Shader决定)等数据准备好,而后通知图形API——或者就简单地看做是通知GPU——开始绘制,GPU基于这些数据,通过一系列运算,在屏幕上画出成千上万的三角形,最终构成一幅图像。 在Unity中,每次引擎准备数据并通知GPU的过程称为一次Draw Call。这一过程是逐个物体进行的,对于每一个物体,不仅GPU的渲染,引擎从新设置材质/Shader也是一项很是耗时的操做。所以每帧的Draw Call次数是一项很是重要的性能指标,对于iOS来讲应尽可能控制在20次之内,这个值能够在编辑器的Statistic窗口看到。 Unity内置了Draw Call Batching技术,从名字就能够看出,它的主要目标就是在一次Draw Call中批量处理多个物体。只要物体的变换和材质相同,GPU就能够按彻底相同的方式进行处理,便可以把它们放在一个Draw Call中。Draw Call Batching技术的核心就是在可见性测试以后,检查全部要绘制的物体的材质,把相同材质的分为一组(一个Batch),而后把它们组合成一个物体(统一变换),这样就能够在一个Draw Call中处理多个物体了(其实是组合后的一个物体)。 但Draw Call Batching存在一个缺陷,就是它须要把一个Batch中的全部物体组合到一块儿,至关于建立了一个与这些物体加起来同样大的物体,与此同时就须要分配相应大小的内存。这不只会消耗更多内存,还须要消耗CPU时间。特别是对于移动的物体,每一帧都得从新进行组合,这就须要进行一些权衡,不然得不偿失。但对于静止不动的物体来讲,只须要进行一次组合,以后就能够一直使用,效率要高得多。 Unity提供了Dynamic Batching和Static Batching两种方式。Dynamic Batching是彻底自动进行的,不须要也没法进行任何干预,对于顶点数在300之内的可移动物体,只要使用相同的材质,就会组成Batch。Static Batching则须要把静止的物体标记为Static,而后不管大小,都会组成Batch。如前文所说,Static Batching显然比Dynamic Batching要高效得多,因而,Static Batching功能是收费的…… 要有效利用Draw Call Batching,首先是尽可能减小场景中使用的材质数量,即尽可能共享材质,对于仅纹理不一样的材质能够把纹理组合到一张更大的纹理中(称为Texture Atlasing)。而后是把不会移动的物体标记为Static。此外还能够经过CombineChildren脚本(Standard Assets/Scripts/Unity Scripts/CombineChildren)手动把物体组合在一块儿,但这个脚本会影响可见性测试,由于组合在一块儿的物体始终会被看做一个物体,从而会增长GPU要处理的几何体数量,所以要当心使用。 对于复杂的静态场景,还能够考虑自行设计遮挡剔除算法,减小可见的物体数量同时也能够减小Draw Call。 总之,理解Draw Call和Draw Call Batching原理,根据场景特色设计相应的方案来尽可能减小Draw Call次数才是王道,其它方面亦然。 Draw Call Batching (绘制调用批处理) To draw an object on the screen, the engine has to issue a draw call to the graphics API (OpenGL ES in the case of iOS). Every single draw call requires a significant amount of work on the part of the graphics API, causing significant performance overhead on the CPU side. 在屏幕上渲染物体,引擎须要发出一个绘制调用来访问图形API(iOS系统中为OpenGL ES)。 每一个绘制调用须要进行大量的工做来访问图形API,从而致使了CPU方面显著的性能开销。 Unity combines a number of objects at runtime and draws them together with a single draw call. This operation is called "batching". The more objects Unity can batch together, the better rendering performance you will get. Unity在运行时能够将一些物体进行合并,从而用一个绘制调用来渲染他们。这一操做,咱们称之为“批处理”。 通常来讲,Unity批处理的物体越多,你就会获得越好的渲染性能。 Built-in batching support in Unity has significant benefit over simply combining geometry in the modeling tool (or using theCombineChildren script from the Standard Assets package). Batching in Unity happensafter visibility determination step. The engine does culling on each object individually, and the amount of rendered geometry is going to be the same as without batching. Combining geometry in the modeling tool, on the other hand, prevents effecient culling and results in much higher amount of geometry being rendered. Unity中内建的批处理机制所达到的效果要明显强于使用几何建模工具(或使用Standard Assets包中的CombineChildren脚本)的批处理效果。 这是由于,Unity引擎的批处理操做是在物体的可视裁剪操做以后进行的。 Unity先对每一个物体进行裁剪,而后再进行批处理,这样可使渲染的几何总量在批处理先后保持不变。 可是,使用几何建模工具来拼合物体,会妨碍引擎对其进行有效的裁剪操做,从而致使引擎须要渲染更多的几何面片。 Materials 材质 Only objects sharing the same material can be batched together. Therefore, if you want to achieve good batching, you need to share as many materials among different objects as possible. 只有拥有相同材质的物体才能够进行批处理。 所以,若是你想要获得良好的批处理效果,你须要在程序中尽量地复用材质和物体。 If you have two identical materials which differ only in textures, you can combine those textures into a single big texture - a process often calledtexture atlasing. Once textures are in the same atlas, you can use single material instead. 若是你的两个材质仅仅是纹理不一样,那么你能够经过 纹理拼合 操做来将这两张纹理拼合成一张大的纹理。 一旦纹理拼合在一块儿,你就可使用这个单一材质来替代以前的两个材质了。 If you need to access shared material properties from the scripts, then it is important to note that modifyingRenderer.material will create a copy of the material. Instead, you should useRenderer.sharedMaterial to keep material shared. 若是你须要经过脚原本访问复用材质属性,那么值得注意的是改变Renderer.material将会形成一份材质的拷贝。 所以,你应该使用Renderer.sharedMaterial来保证材质的共享状态。 Dynamic Batching 动态批处理 Unity can automatically batch moving objects into the same draw call if they share the same material. 若是动态物体共用着相同的材质,那么Unity会自动对这些物体进行批处理。 Dynamic batching is done automatically and does not require any additional effort on your side. 动态批处理操做是自动完成的,并不须要你进行额外的操做。 Tips: 提醒: 一、 Batching dynamic objects has certain overheadper vertex, so batching is applied only to meshes containing less than900 vertex attributes in total. 批处理动态物体须要在每一个顶点上进行必定的开销,因此动态批处理仅支持小于900顶点的网格物体。 二、 If your shader is using Vertex Position, Normal and single UV, then you can batch up to 300 verts and if your shader is using Vertex Position, Normal, UV0, UV1 and Tangent, then only 180 verts. Please note: attribute count limit might be changed in future 若是你的着色器使用顶点位置,法线和UV值三种属性,那么你只能批处理300顶点如下的物体; 若是你的着色器须要使用顶点位置,法线,UV0,UV1和切向量,那你只 能批处理180顶点如下的物体。 请注意:属性数量的限制可能会在未来进行改变。 四、 Don't use scale. Objects with scale (1,1,1) and (2,2,2) won't batch. 不要使用缩放尺度(scale)。分别拥有缩放尺度(1,1,1)和(2,2,2)的两个物体将不会进行批处理。 五、 Uniformly scaled objects won't be batched with non-uniformly scaled ones. 统一缩放尺度的物体不会与非统一缩放尺度的物体进行批处理。 Objects with scale (1,1,1) and (1,2,1) won't be batched. On the other hand (1,2,1) and (1,3,1) will be. 使用缩放尺度(1,1,1)和 (1,2,1)的两个物体将不会进行批处理,可是使用缩放尺度(1,2,1)和(1,3,1)的两个物体将能够进行批处理。 六、 Using different material instances will cause batching to fail. 使用不一样材质的实例化物体(instance)将会致使批处理失败。 七、 Objects with lightmaps have additional (hidden) material parameter: offset/scale in lightmap, so lightmapped objects won't be batched (unless they point to same portions of lightmap) 拥有lightmap的物体含有额外(隐藏)的材质属性,好比:lightmap的偏移和缩放系数等。因此,拥有lightmap的物体将不会进行批处理(除非他们指向lightmap的同一 部分)。 八、 Multi-pass shaders will break batching. E.g. Almost all unity shaders supports several lights in forward rendering, effectively doing additional pass for them 多通道的shader会妨碍批处理操做。好比,几乎unity中全部的着色器在前向渲染中都支持多个光源,并为它们有效地开辟多个通道。 九、 Using instances of a prefab automatically are using the same mesh and material. 预设体的实例会自动地使用相同的网格模型和材质。 Static Batching 静态批处理 Static batching, on the other hand, allows the engine to reduce draw calls for geometry of any size (provided it does not move and shares the same material). Static batching is significantly more efficient than dynamic batching. You should choose static batching as it will require less CPU power. 相对而言,静态批处理操做容许引擎对任意大小的几何物体进行批处理操做来下降绘制调用(只要这些物体不移动,而且拥有相同的材质)。所以,静态批处理比动态批处理更加有效,你应该尽可能低使用它,由于它须要更少的CPU开销。 In order to take advantage of static batching, you need explicitly specify that certain objects are static and willnot move, rotate or scale in the game. To do so, you can mark objects as static using the Static checkbox in the Inspector: 为了更好地使用静态批处理,你须要明确指出哪些物体是静止的,而且在游戏中永远不会移动、旋转和缩放。想完成这一步,你只须要在检测器(Inspector)中将Static复选框打勾便可,以下图所示: Using static batching will require additional memory for storing the combined geometry. If several objects shared the same geometry before static batching, then a copy of geometry will be created for each object, either in the Editor or at runtime. This might not always be a good idea - sometimes you will have to sacrifice rendering performance by avoiding static batching for some objects to keep a smaller memory footprint. For example, marking trees as static in a dense forest level can have serious memory impact. 使用静态批处理操做须要额外的内存开销来储存合并后的几何数据。在静态批处理以前,若是一些物体共用了一样的几何数据,那么引擎会在编辑以及运行状态对每一个物体建立一个几何数据的备份。这并不老是一个好的想法,由于有时候,你将不得不牺牲一点渲染性能来防止一些物体的静态批处理,从而保持较少的内存开销。好比,将浓密森里中树设为Static,会致使严重的内存开销。 Static batching is only available in Unity iOS Advanced. 静态批处理目前只支持Unity iOS Advanced。 备注:最近一直在研究Unity3D的性能优化问题,这段时间可能会多翻译这方面的文章。 前两天,MadFinger,就是当今iOS与Android上画质最牛逼闪闪的游戏之一——ShadowGun的开发商,使人惊异地放出了一个ShadowGun的样例关卡以及若干可无偿使用的Shader,国外同行们的分享精神真的是使人赞叹不已。原文在这里,如下是个人一些摘录和笔记。 首先是一些优化常识。针对图形方面的优化主要包括三角形数量,纹理所占内存,以及Shader,前两项基本没什么好讲的,针对设备机能的限制制定相应的指标便可,因此Shader就成为了图形性能优化的关键。 Alpha blending 在Unity官方文档中讲,因为硬件缘由,在iOS设备上使用alpha-test会形成很大的性能开销,应尽可能使用alpha-blend代替。这里提到,在同屏使用alpha-blend的面数,尤为是这些面所占屏幕面积的大小,对性能也会形成很大影响。缘由是使用alpha-blend的面会形成overdraw的增长,这尤为对低性能设备的影响很大。不过没有购买Pro版,没有Occlusion Culling功能的话,就没必要顾虑这一问题了,反正overdraw是必然的。 复杂的Per-pixel shader Per-pixel shader即Fragment shader,顾名思义是要对每一个渲染到屏幕上的像素作处理的shader,若是per-pixel shader比较复杂且须要处理的像素不少时,也就是使用该shader的面占屏幕面积很大时,对性能的影响甚至要超过alpha blending。所以复杂的per-pixel shader只适用于小物体。 下面是对几个Shader的逐一讲解: Environment specular maps(Shader Virtual Gloss Per Vertex Additive) Specular map一般都是利用贴图的alpha通道来定义物体表面的光滑程度(反光度),这个shader的特色是per-vertex计算反光度的,有着至关不错的效果的同时比per-pixel的shader性能要高得多。这个shader很适用于关卡环境等占很大区域的模型。 通过优化的动态角色光照和阴影(Light probes和BRDF Shader) 传统的Lightmaps没法支持动态物体,对此Unity提供了Light probes技术,预先把动态物体的光照信息保存在代理对象(即Light probes)中,运行时动态物体从距离最近的Probe中获取光照信息。 Unity自己还提供了一个效果很是棒的专为移动设备优化过的角色Shader,支持Diffuse、Specular和Normal maps,并经过一个特殊的脚本生成贴图用于模仿BRDF光照效果。最终产生的效果堪比次时代大做中的角色光影效果。 雾和体积光(Shader Blinking Godrays) 目前在移动设备上要开启真正的雾效基本不可行,ShadowGun的方案是经过简单的网格+透明贴图(称为雾面)来模拟雾效。在玩家靠近时,雾面逐渐变淡,同时fog plane的顶点也会移开(即便彻底透明的alpha面也会消耗不少渲染时间)。 使用这个Shader的网格须要通过处理: 顶点的alpha值用于决定顶点是否能够移动(在例子中0为不可动,1为可动)。 顶点法线决定移动的方向 而后Shader经过计算与观察者的距离来控制雾面的淡入/淡出。 这个Shader还能够用来作体积光和其它一些alpha效果。 飞机坠毁的浓烟效果(Shader Scroll 2 Layers Sine Alpha-blended) 经过粒子产生浓烟的代价过高,因此ShadowGun中使用了网格+贴图动画来制做这个效果。经过混合两层贴图并让它们交错移动来产生动画效果。其中顶点alpha值用于让网格的边缘看起来比较柔和,同时使用顶点颜色来模拟从火焰到烟雾的过渡效果。 带动态效果的天空盒(Shader Scroll 2 Layers Multiplicative) 经过两张贴图的混合和移动产生云的动态效果。 旗帜和衣服的飘动效果(Shader Lightmap + Wind) 一样利用顶点alpha值决定哪些顶点能够移动,而后shader的参数用于调整摆动的方向和速度。 =======================分割线======================== 1、程序方面 0一、务必删除脚本中为空或不须要的默认方法; 0二、只在一个脚本中使用OnGUI方法; 0三、避免在OnGUI中对变量、方法进行更新、赋值,输出变量建议在Update内; 0四、同一脚本中频繁使用的变量建议声明其为全局变量,脚本之间频繁调用的变量或方法建议声明为全局静态变量或方法; 0五、不要去频繁获取组件,将其声明为全局变量; 0六、数组、集合类元素优先使用Array,其次是List; 0七、脚本在不使用时脚本禁用之,须要时再启用; 0八、可使用Ray来代替OnMouseXXX类方法; 0九、须要隐藏/显示或实例化来回切换的对象,尽可能不要使用SetActiveRecursively或active,而使用将对象远远移出相机范围和移回原位的作法; 十、尽可能少用模运算和除法运算,好比a/5f,必定要写成a*0.2f。 十一、对于不常常调用或更改的变量或方法建议使用Coroutines & Yield; 十二、尽可能直接声明脚本变量,而不使用GetComponent来获取脚本; iPhone 1三、尽可能使用整数数字,由于iPhone的浮点数计算能力不好; 1四、不要使用原生的GUI方法; 1五、不要实例化(Instantiate)对象,事先建好对象池,并使用Translate“生成”对象; 2、模型方面 0一、合并使用同贴图的材质球,合并使用相同材质球的Mesh; 0二、角色的贴图和材质球只要一个,若必须多个则将模型离分离为多个部分; 0二、骨骼系统不要使用太多; 0三、当使用多角色时,将动画单独分离出来; 0四、使用层距离来控制模型的显示距离; 0五、阴影其实包含两方面阴暗和影子,建议使用实时影子时把阴暗效果烘焙出来,不要使用灯光来调节光线阴暗。 0六、少用像素灯和使用像素灯的Shader; 0八、若是硬阴影能够解决问题就不要用软阴影,而且使用不影响效果的低分辨率阴影; 0八、实时阴影很耗性能,尽可能减少产生阴影的距离; 0九、容许的话在大场景中使用线性雾,这样可使远距离对象或阴影不易察觉,所以能够经过减少相机和阴影距离来提升性能; 十、使用圆滑组来尽可能减小模型的面数; 十一、项目中若是没有灯光或对象在移动那么就不要使用实时灯光; 十二、水面、镜子等实时反射/折射的效果单独放在Water图层中,而且根据其实时反射/折射的范围来调整; 1三、碰撞对效率的影响很小,但碰撞仍是建议使用Box、Sphere碰撞体; 1四、建材质球时尽可能考虑使用Substance; 1五、尽可能将全部的实时反射/折射(如水面、镜子、地板等等)都集合成一个面; 1六、假反射/折射没有必要使用过大分辨率,通常64*64就能够,不建议超过256*256; 1七、须要更改的材质球,建议实例化一个,而不是使用公共的材质球; 1八、将不须射线或碰撞事件的对象置于IgnoreRaycast图层; 1九、将水面或相似效果置于Water图层 20、将透明通道的对象置于TransparentFX图层; 2一、养成良好的标签(Tags)、层次(Hieratchy)和图层(Layer)的条理化习惯,将不一样的对象置于不一样的标签或图层,三者有效的结合将很方便的按名称、类别和属性来查找; 2二、经过Stats和Profile查看对效率影响最大的方面或对象,或者使用禁用部分模型的方式查看问题到底在哪儿; 2三、使用遮挡剔除(Occlusion Culling)处理大场景,一种较原生的类LOD技术,而且可以“分割”做为总体的一个模型。 3、其它 场景中若是没有使用灯光和像素灯,就不要使用法线贴图,由于法线效果只有在有光源(Direct Light/Point Light/Angle Light/Pixel Light)的状况下才有效果。