【转】unity3d 各类优化综合

 

 


  检测方式:

  一,unity3d 渲染统计窗口

  Game视窗的Stats去查看渲染统计的信息:

  一、FPS

  fps其实就是 frames per second,也就是每一秒游戏执行的帧数,这个数值越小,说明游戏越卡。

  二、Draw calls

  batching以后渲染mesh的数量,和当前渲染到的网格的材质球数量有关。

  三、Saved by batching

  渲染的批处理数量,这是引擎将多个对象的绘制进行合并从而减小GPU的开销;

  不少GUI插件的一个好处就是合并多个对象的渲染,从而下降DrawCalls ,保证游戏帧数。

  四、Tris 和 Draw Calls

  预览的时候,可点开 Stats,查看图形渲染的开销状况。特别注意 Tris 保持在 7.5k 如下,有待考证。

  Draw Calls 保持在 20 如下,有待考证。

  2,FPS,每一秒游戏执行的帧数,这个数值越小,说明游戏越卡。

  3,Render Textures 渲染的图片占用内存大小。

  4,VRAM usage 显存的使用状况,VRAM总大小取决于你的显卡的显存。

  二,代码优化

  1. 尽可能避免每帧处理

  好比:

  function Update() { DoSomeThing(); }

  可改成每5帧处理一次:

  function Update() { if(Time.frameCount % 5 == 0) { DoSomeThing(); } }

  2. 定时重复处理用 InvokeRepeating 函数实现

  好比,启动0.5秒后每隔1秒执行一次 DoSomeThing 函数:

  function Start() { InvokeRepeating(“DoSomeThing”, 0.5, 1.0); }

  3. 优化 Update, FixedUpdate, LateUpdate 等每帧处理的函数

  函数里面的变量尽可能在头部声明。

  好比:

  function Update() { var pos: Vector3 = transform.position; }

  可改成

  private var pos: Vector3; function Update(){ pos = transform.position; }

  4. 主动回收垃圾

  给某个 GameObject 绑上如下的代码:

  function Update() { if(Time.frameCount % 50 == 0) { System.GC.Collect(); } }

  5. 优化数学计算

  好比,若是能够避免使用浮点型(float),尽可能使用整形(int),尽可能少用复杂的数学函数好比 Sin 和 Cos 等等

  6,减小固定增量时间

   将固定增量时间值设定在0.04-0.067区间(即,每秒15-25帧)。您能够经过Edit->Project Settings->Time来改变这个值。这样作下降了FixedUpdate函数被调用的频率以及物理引擎执行碰撞检测与刚体更新的频率。若是 您使用了较低的固定增量时间,而且在主角身上使用了刚体部件,那么您能够启用插值办法来平滑刚体组件。

  7,减小GetComponent的调用

  使用 GetComponent或内置组件访问器会产生明显的开销。您能够经过一次获取组件的引用来避免开销,并将该引用分配给一个变量(有时称为“缓存”的引用)。例如,若是您使用以下的代码:

css

[AppleScript] 纯文本查看 复制代码
  function Update () {

  transform.Translate(0, 1, 0);

  }


  经过下面的更改您将得到更好的性能:

[AppleScript] 纯文本查看 复制代码
  var myTransform : Transform;

  function Awake () {

  myTransform = transform;

  }

  function Update () {

  myTransform.Translate(0, 1, 0);

  }


  8,避免分配内存

  您应该避免分配新对象,除非你真的须要,由于他们再也不在使用 时,会增长垃圾回收系统的开销。您能够常常重复使用数组和其余对象,而不是分配新的数组或对象。这样作好处则是尽可能减小垃圾的回收工做。同时,在某些可能 的状况下,您也可使用结构(struct)来代替类(class)。这是由于,结构变量主要存放在栈区而非堆区。由于栈的分配较快,而且不调用垃圾回收 操做,因此当结构变量比较小时能够提高程序的运行性能。可是当结构体较大时,虽然它仍可避免分配/回收的开销,而它因为“传值”操做也会致使单独的开销, 实际上它可能比等效对象类的效率还要低。

  9,使用iOS脚本调用优化功能

  UnityEngine 命名空间中的函数的大多数是在 C/c + +中实现的。从Mono的脚本调用 C/C++函数也存在着必定的性能开销。您可使用iOS脚本调用优化功能(菜单:Edit->Project Settings->Player)让每帧节省1-4毫秒。此设置的选项有:

  Slow and Safe – Mono内部默认的处理异常的调用

  Fast and Exceptions Unsupported –一个快速执行的Mono内部调用。不过,它并不支持异常,所以应谨慎使用。它对于不须要显式地处理异常(也不须要对异常进行处理)的应用程序来讲,是一个理想的候选项。

  10,

  优化垃圾回收

  如上文所述,您应该尽可能避免分配操做。可是,考虑到它们是不能彻底杜绝的,因此咱们提供两种方法来让您尽可能减小它们在游戏运行时的使用:

  若是堆比较小,则进行快速而频繁的垃圾回收

   这一策略比较适合运行时间较长的游戏,其中帧率是否平滑过渡是主要的考虑因素。像这样的游戏一般会频繁地分配小块内存,但这些小块内存只是暂时地被使 用。若是在iOS系统上使用该策略,那么一个典型的堆大小是大约 200 KB,这样在iPhone 3G设备上,垃圾回收操做将耗时大约 5毫秒。若是堆大小增长到1 MB时,该回收操做将耗时大约 7ms。所以,在普通帧的间隔期进行垃圾回收有时候是一个不错的选择。一般,这种作法会让回收操做执行的更加频繁(有些回收操做并非严格必须进行的), 但它们能够快速处理而且对游戏的影响很小:

[AppleScript] 纯文本查看 复制代码
  if (Time.frameCount % 30 == 0)

  {

  System.GC.Collect();

  }


  可是,您应该当心地使用这种技术,而且经过检查Profiler来确保这种操做确实能够下降您游戏的垃圾回收时间

  若是堆比较大,则进行缓慢且不频繁的垃圾回收

  这一策略适合于那些内存分配 (和回收)相对不频繁,而且能够在游戏停顿期间进行处理的游戏。若是堆足够大,但尚未大到被系统关掉的话,这种方法是比较适用的。可是,Mono运行时会尽量地避免堆的自动扩大[url=http://www.unitymanual.com/forum-develop-1.html]unity 3d开发心得[/url] 所以,您须要经过在启动过程当中预分配一些空间来手动扩展堆(ie,你实例化一个纯粹影响内存管理器分配的“无用”对象):

[AppleScript] 纯文本查看 复制代码
  function Start() {

  var tmp = new System.Object[1024];

  // make allocations in smaller blocks to avoid them to be treated in a special way, which is designed for large blocks

  for (var i : int = 0; i < 1024; i++)

  tmp[i] = new byte[1024];

  // release reference

  tmp = null;

  }


  游戏中的暂停是用来对堆内存进行回收,而一个足够大的堆应该不会在游戏的暂停与暂停之间被彻底占满。因此,当这种游戏暂停发生时,您能够显式请求一次垃圾回收:

  System.GC.Collect();

  另外,您应该谨慎地使用这一策略并时刻关注Profiler的统计结果,而不是假定它已经达到了您想要的效果。

  三,模型

  1,压缩 Mesh

  导入 3D 模型以后,在不影响显示效果的前提下,最好打开 Mesh Compression。

  Off, Low, Medium, High 这几个选项,可酌情选取。

  2,避免大量使用 Unity 自带的 Sphere 等内建 Mesh

  Unity 内建的 Mesh,多边形的数量比较大,若是物体不要求特别圆滑,可导入其余的简单3D模型代替。
        游戏蛮牛:http://www.unitymanual.com

 

 

 

 

 

最简单的优化建议:

1.PC平台的话保持场景中显示的顶点数少于200K~3M,移动设备的话少于10W,一切取决于你的目标GPU与CPU。
2.若是你用U3D自带的SHADER,在表现不差的状况下选择Mobile或Unlit目录下的。它们更高效。
3.尽量共用材质。
4.将不须要移动的物体设为Static,让引擎能够进行其批处理。
5.尽量不用灯光。
6.动态灯光更加不要了。
7.尝试用压缩贴图格式,或用16位代替32位。
8.若是不须要别用雾效(fog)
9.尝试用OcclusionCulling,在房间过道多遮挡物体多的场景很是有用。若不当反而会增长负担。
10.用天空盒去“褪去”远处的物体。
11.shader中用贴图混合的方式去代替多重通道计算。
12.shader中注意float/half/fixed的使用。
13.shader中不要用复杂的计算pow,sin,cos,tan,log等。
14.shader中越少Fragment越好。
15.注意是否有多余的动画脚本,模型自动导入到U3D会有动画脚本,大量的话会严重影响消耗CPU计算。
16.注意碰撞体的碰撞层,没必要要的碰撞检测请舍去。


1.为何须要针对CPU(中央处理器)与GPU(图形处理器)优化?

CPU和GPU都有各自的计算和传输瓶颈,不一样的CPU或GPU他们的性能都不同,因此你的游戏须要为你目标用户的CPU与GPU能力进行针对开发。


2.CPU与GPU的限制

GPU通常具备填充率(Fillrate)和内存带宽(Memory Bandwidth)的限制,若是你的游戏在低质量表现的状况下会快不少,那么,你极可能须要限制你在GPU的填充率。

CPU 通常被所须要渲染物体的个数限制,CPU给GPU发送渲染物体命令叫作DrawCalls。通常来讲DrawCalls数量是须要控制的,在能表现效果的 前提下越少越好。一般来讲,电脑平台上DrawCalls几千个以内,移动平台上DrawCalls几百个以内。这样就差很少了。固然以上并非绝对的, 仅做一个参考。

每每渲染(Rendering)并非一个问题,不管是在GPU和CPU上。极可能是你的脚本代码效率的问题,用Profiler查看下。

关于Profiler介绍:http://docs.unity3d.com/Documentation/Manual/Profiler.html

须要注意的是:
在GPU中显示的RenderTextureTexture2D.html

图片压缩将下降你的图片大小(更快地加载更小的内存跨度(footprint)),并且大大提升渲染表现。压缩贴图比起未压缩的32位RGBA贴图占用内存带宽少得多。

以前U3D会议还据说过一个优化,贴图尽可能都用一个大小的格式(512 * 512 , 1024 * 1024),这样在内存之中能获得更好的排序,而不会有内存之间空隙。这个是否真假没获得过测试。

MIPMAps(多重纹理格式):

http://docs.unity3d.com/Documentation/Components/class-html

[Unity3D]图形渲染优化、渲染管线优化、图形性能优化
     
         
 
 
 
 
转载请留下本文原始连接,谢谢。本文会不按期更新维护,最近更新于2013.11.09
 
主要内容也能够参考:
http://docs.unity3d.com/Documentation/Manual/OptimizingGraphicsPerformance.html
 
最简单的优化建议:
 
1.PC平台的话保持场景中显示的顶点数少于200K~3M,移动设备的话少于10W,一切取决于你的目标GPU与CPU。
2.若是你用U3D自带的SHADER,在表现不差的状况下选择Mobile或Unlit目录下的。它们更高效。
3.尽量共用材质。
4.将不须要移动的物体设为Static,让引擎能够进行其批处理。
5.尽量不用灯光。
6.动态灯光更加不要了。
7.尝试用压缩贴图格式,或用16位代替32位。
8.若是不须要别用雾效(fog)
9.尝试用OcclusionCulling,在房间过道多遮挡物体多的场景很是有用。若不当反而会增长负担。
10.用天空盒去“褪去”远处的物体。
11.shader中用贴图混合的方式去代替多重通道计算。
12.shader中注意float/half/fixed的使用。
13.shader中不要用复杂的计算pow,sin,cos,tan,log等。
14.shader中越少Fragment越好。
15.注意是否有多余的动画脚本,模型自动导入到U3D会有动画脚本,大量的话会严重影响消耗CPU计算。
16.注意碰撞体的碰撞层,没必要要的碰撞检测请舍去。
 
 
1.为何须要针对CPU(中央处理器)与GPU(图形处理器)优化?
 
CPU和GPU都有各自的计算和传输瓶颈,不一样的CPU或GPU他们的性能都不同,因此你的游戏须要为你目标用户的CPU与GPU能力进行针对开发。
 
 
2.CPU与GPU的限制
 
GPU通常具备填充率(Fillrate)和内存带宽(MemoryBandwidth)的限制,若是你的游戏在低质量表现的状况下会快不少,那么,你极可能须要限制你在GPU的填充率。
 
CPU 通常被所须要渲染物体的个数限制,CPU给GPU发送渲染物体命令叫作DrawCalls。通常来讲DrawCalls数量是须要控制的,在能表现效果的 前提下越少越好。一般来讲,电脑平台上DrawCalls几千个以内,移动平台上DrawCalls几百个以内。这样就差很少了。固然以上并非绝对的, 仅做一个参考。
 
每每渲染(Rendering)并非一个问题,不管是在GPU和CPU上。极可能是你的脚本代码效率的问题,用Profiler查看下。
 
关于Profiler介绍:http://docs.unity3d.com/Documentation/Manual/Profiler.html
 
须要注意的是:
在GPU中显示的RenderTexture.SetActive()占用率很高,是由于你同时打开了编辑窗口的缘由,而不是U3D的BUG。
 
3.关于顶点数量和顶点计算
 
CPU和GPU对顶点的计算处理都不少。GPU中渲染的顶点数取决于GPU性能和SHADER的复杂程度,通常来讲,每帧以内,在PC上几百万顶点内,在移动平台上不超过10万顶点。
 
CPU中的计算主要是在蒙皮骨骼计算,布料模拟,顶点动画,粒子模拟等。GPU则在各类顶点变换、光照、贴图混合等。
 
【个 人认为,具体仍是看各位的项目需求,假设你项目的是3D游戏。你游戏须要兼容低配置的硬件、流畅运行、控制硬件发热的话,还要达到必定效果 (LIGHTMAP+雾效),那么顶点数一定不能高。此时同屏2W顶点我认为是个比较合适的数目,DRAWCALL最好低于70。另,控制发热请控制最高 上限的帧率,流畅的话,帧率其实不须要过高的。】
 
 
 
4.针对CPU的优化——减小DRAW CALL 的数量
 
为了渲染物体到显示器上,CPU须要作一些工做,如区分哪一个东西须要渲染、区分开物体是否受光照影响、使用哪一个SHADER而且为SHADER传参、发送绘图命令告诉显示驱动,而后发送命令告诉显卡删除等这些。
 
假设你有一个上千三角面的模型却用上千个三角型模型来代替,在GPU上花费是差很少的,可是在CPU上则是极其不同,消耗会大不少不少。为了让CPU更少的工做,须要减小可见物的数目:
 
a.合并相近的模型,手动在模型编辑器中合并或者使用UNITY的Draw call批处理达到相同效果(Draw callbatching)。具体方法和注意事项查看如下连接:
 
Draw call batching :http://docs.unity3d.com/Documentation/Manual/DrawCallBatching.html
 
 
b.在项目中使用更少的材质(material),将几个分开的贴图合成一个较大的图集等方式处理。
 
若是你须要经过脚原本控制单个材质属性,须要注意改变Renderer.material将会形成一份材质的拷贝。所以,你应该使用Renderer.sharedMaterial来保证材质的共享状态。
 
有一个合并模型材质不错的插件叫Mesh Baker,你们能够考虑试下。
 
c.尽可能少用一些渲染步骤,例如reflections,shadows,per-pixel light 等。
 
d.Draw call batching的合并物体,会使每一个物体(合并后的物体)至少有几百个三角面。
 
假设合并的两个物体(手动合并)但不共享材质,不会有性能表现上的提高。多材质的物体至关于两个物体不用一个贴图。因此,为了提高CPU的性能,你应该确保这些物体使用一样的贴图。
 
另外,用灯光将会取消(break)引擎的DRAW CALL BATCH,至于为何,查看如下:
 
Forward Rendering Path Details:
http://docs.unity3d.com/Documentation/Components/RenderTech-ForwardRendering.html
 
e.使用相关剔除数量直接减小Draw Call数量,下文有相关说起。
 
 
5.优化几何模型
 
最基本的两个优化准则:
a.不要有没必要要的三角面。
b.UV贴图中的接缝和硬边越少越好。
 
需 要注意的是,图形硬件须要处理顶点数并跟硬件报告说的并不同。不是硬件说能渲染几个点就是几个点。模型处理应用通展现的是几何顶点数量。例如,一个由一 些不一样顶点构成的模型。在显卡中,一些集合顶点将会被分离(split)成两个或者更多逻辑顶点用做渲染。若是有法线、UV坐标、顶点色的话,这个顶点必 须会被分离。因此在游戏中处理的实际数量显然要多不少。
 
 
6.关于光照
 
若不用光确定是最快的。移动端优化能够采用用光照贴图(Lightmapping)去烘培一个静态的贴图,以代替每次的光照计算,在U3D中只须要很是短的时间则能生成。这个方法能大大提升效率,并且有着更好的表现效果(平滑过渡处理,还有附加阴影等)。
 
在移动设备上和低端电脑上尽可能不要在场景中用真光,用光照贴图。这个方法大大节省了CPU和GPU的计算,CPU获得了更少的DRAWCALL,GPU则须要更少顶点处理和像素栅格化。
 
Lightmapping :http://docs.unity3d.com/Documentation/Manual/Lightmapping.html
 
 
7.对GPU的优化——图片压缩和多重纹理格式
 
Compressed Textures(图片压缩):
 
http://docs.unity3d.com/Documentation/Components/class-Texture2D.html
 
图片压缩将下降你的图片大小(更快地加载更小的内存跨度(footprint)),并且大大提升渲染表现。压缩贴图比起未压缩的32位RGBA贴图占用内存带宽少得多。
 
以前U3D会议还据说过一个优化,贴图尽可能都用一个大小的格式(512 * 512 , 1024 *1024),这样在内存之中能获得更好的排序,而不会有内存之间空隙。这个是否真假没获得过测试。
 
MIPMAPS(多重纹理格式):
 
http://docs.unity3d.com/Documentation/Components/class-Texture2D.html
 
跟网页上的略缩图原理同样,在3D游戏中咱们为游戏的贴图生成多重纹理贴图,远处显示较小的物体用小的贴图,显示比较大的物体用精细的贴图。这样能更加有效的减小传输给GPU中的数据。
 
 
8.LOD 、 Per-Layer Cull Distances 、 OcclusionCulling
 
LOD (Level Of Detail)是很经常使用的3D游戏技术了,其功能理解起来则是至关于多重纹理贴图。在以在屏幕中显示模型大小的比例来判断使用高或低层次的模型来减小对GPU的传输数据,和减小GPU所须要的顶点计算。
 
摄像机分层距离剔除(Per-Layer CullDistances):为小物体标识层次,而后根据其距离主摄像机的距离判断是否须要显示。
 
遮挡剔除(OcclusionCulling)其实就是当某个物体在摄像机前被另一个物体彻底挡住的状况,挡住就不发送给GPU渲染,从而直接下降DRAWCALL。不过有些时候在CPU中计算其是否被挡住则会很耗计算,反而得不偿失。
 
如下是这几个优化技术的相关使用和介绍:
 
Level Of Detail :
http://docs.unity3d.com/Documentation/Manual/LevelOfDetail.html
 
Per-Layer Cull Distances :
http://docs.unity3d.com/Documentation/ScriptReference/Camera-layerCullDistances.html
 
Occlusion Culling :
http://docs.unity3d.com/Documentation/Manual/OcclusionCulling.html
 
 
9.关于Realtime Shadows(实时阴影)
 
实时阴影技术很是棒,但消耗大量计算。为GPU和CPU都带来了昂贵的负担,细节的话参考下面:
 
http://docs.unity3d.com/Documentation/Manual/Shadows.html
 
 
10.对GPU优化:采用高效的shader
 
a.须要注意的是有些(built-in)Shader是有mobile版本的,这些大大提升了顶点处理的性能。固然也会有一些限制。
 
b.本身写的shader请注意复杂操做符计算,相似pow,exp,log,cos,sin,tan等都是很耗时的计算,最多只用一次在每一个像素点的计算。不推荐你本身写normalize,dot,inversesqart操做符,内置的确定比你写的好。
 
c.须要警醒的是alpha test,这个很是耗时。
 
d.浮点类型运算:精度越低的浮点计算越快。
 
在CG/HLSL中--
 
float :32位浮点格式,适合顶点变换运算,但比较慢。
half:16位浮点格式,适合贴图和UV坐标计算,是highp类型计算的两倍。
fixed: 10位浮点格式,适合颜色,光照,和其余。是highp格式计算的四倍。
 
写Shader优化的小提示:
http://docs.unity3d.com/Documentation/Components/SL-ShaderPerformance.html
 
 
11.另外的相关优化:
 
a.对Draw Call Batching的优化
http://docs.unity3d.com/Documentation/Manual/DrawCallBatching.html
 
b.对Rendering Statistics Window的说明和提示:
http://docs.unity3d.com/Documentation/Manual/RenderingStatistics.html
 
c.角色模型的优化建议
用单个蒙皮渲染、尽可能少用材质、少用骨骼节点、移动设备上角色多边形保持在300~1500内(固然还要看具体的需求)、PC平台上1500~4000内(固然还要看具体的需求)。
 
http://docs.unity3d.com/Documentation/Manual/ModelingOptimizedCharacters.html
相关文章
相关标签/搜索