飞道的博客

unity 贴图、模型、shader、光照、编码、 cup、gpu、内存、shader 性能优化相关

478人阅读  评论(0)

优化,老生常谈。游戏的优化和网站、软件优化没有任何不同,除了编码质量和使用技巧以外,都是那些空间<>时间、效果<>性能的老套路。

Debug工具介绍

Statistics
Profile

内存优化

【适当的GC(Garbage Collection垃圾回收)】

GC有两种触发方式,1内存不足自动触发,2手动触发。
首先内存不足时自动GC,经反复测试,并不是很好的办法。因为当内存不足时cpu压力也比较大,在GC之前就已经会发生卡顿现象,GC时还会发生更严重的卡顿。最好的办法还是手动GC。但一定要设计好触发条件。因为过于频繁的GC也很影响性能。

函数相关的优化

【使用for循环,减少foreach】

foreach会涉及到迭代器的使用,而据传每次循环所产生的迭代器会带来24 Bytes的垃圾。

【不直接访问gameobject的tag属性】

比如if (object.tag == “target”)最好换成if (object.CompareTag (“target”))。因为访问物体的tag属性会在堆上额外的分配空间。

【使用对象池,实现对象的复用】

将场景中的对象放在池中调用,节省反复实例化的开销

*【减少GetComponent方法调用组件】

脚本中三种调用Transform组件的方式,其响应时间有着巨大的不同,按时间的相应毫秒数大小排列的话是这个样子:GetComponen > transform= 60ms >myTransformCache
所以应该建立组件的引用留作复用,而不是每次都使用GetComponent。

*【只运行物体在摄像机视野内的脚本】

使用void OnBecameVisible()和void OnBecameVisible()减少摄像机事业外脚本运行的开销。这两个函数分别是 当前物体在摄像机范围内或离开摄像机范围触发。

【尽量使用内建值,减少new的开销】

使用数组内建值,比如Vector3.zero而不是new Vector(0, 0, 0)。

【位置、旋转、缩放的数值要使用低精度】

设置位置旋转和缩放的时,不要使用高精度的变换。否则会产生模型抖动的问题。

贴图、材质优化

【纹理尺寸最好2的整数幕】
【使用纹理图集】

类似前端的雪碧图。用一张包含了很多子贴图的大贴图,来代替一系列单独的小贴图。可以提高加载效率,并且更易于批量处理。
需要使用Renderer.sharedMaterial 代替Renderer.material

【减少透明物体的使用】

由于透明没有开启深度写入所以会造成overdraw。

【使用共享材质】

共享材质可以减少材质数量,便于批量处理。
需要使用Renderer.sharedMaterial 代替Renderer.material

【压缩纹理】

unity统合了纹理压缩的方法。只需按质量等级选择好即可。不过越高的压缩质量,画质越不好。GUI最好不要压缩,质量影响很明显。
【用法&步骤】
点击贴图文件 -> Inspector -> Default -> Compression 选择压缩质量

*【使用多级渐远纹理MipMap】

类似模型LOD技术,逐级生成多个低精度贴图,在适当的情况使用适当的贴图。缺点是会增加内存占用,典型的空间换时间优化。
【操作步骤】
点击贴图文件 -> Generate Mip Map -> Apply。
这时点击Sprite Editor打开窗口,拖拽右上角的拉杆就能看到结果了。

光照优化

*【减少实时光照,使用光照纹理烘焙,或灯光探针】

如果物体使用了多个Pass 的Shader,使用实时光照很有可能会造成性能下降。这是因为实时光照会产生更多的计算量,而且还无法使用动态批处理和静态批处理。
1 使用光照纹理烘焙技术(GI、bake),把光照提前烘焙到一张光照纹理(lightmap ),运行时映射相应的纹理实现光照效果 。这样不仅性能更好而且效果也更好。但缺点是物体必须设置为静态。对于需要移动的物体来说就不太合适。
2 这个时候使用灯光探针(Light Probe Group)是比较好的办法
3如果一定要使用更多的实时光,也可以选择用逐顶点光照来代替。

【减少实时阴影】

使用烘焙把静态物体的阴影信息存储到光照纹理中,只对动态物体使用适当的实时阴影。

模型优化

【尽可能移除隐藏的面】

这会减少顶点和三角面的处理。比如我们的相机在阳台,附近高楼林立。那么实际上只有前面几个楼需要前、左、右的面。远处的楼是不需要左或、右的面。因为看不到。

【合并mesh】
【减少顶点】

建模时应尽量减少模型的顶点。根据动态、静态批处理的触发相关规则,简单着色器模型顶点数必须小于900。如果着色器同时使用顶点位置、法线、UV值三种属性则模型顶点数必须小于300。如果着色器同时使用顶点位置、法线、UV0、UV1、切向量五种属性则模型顶点数必须小于180。

*【减少模型缩放(Scale)】

模型缩放会导致创建新的Batch。不利于动态、静态批处理

【不使用mesh collider】

尽量使用cube collider 等内置colliser。性能会提高很多

*【使用模型的LOD (Level ofDetail )】

使用模型的多级细节技术,在不同的距离使用不同精度的模型、材质。提升cpu、gpu型能,加重内存负担。典型的空间换时间优化技术。

*【使用遮挡剔除( Occlusion Culling )】
*【使用动态批处理(Baches,Saved by batching)】

【使用条件&步骤】

  1. 场景中存在多个相同模型。如果不是多个相同模型,则批处理无意义。
  2. 模型顶点数必须小于900。
  3. 如果着色器同时使用顶点位置、法线、UV值三种属性则模型顶点数必须小于300。如果着色器同时使用顶点位置、法线、UV0、UV1、切向量五种属性则模型顶点数必须小于180。
  4. 不能进行缩放 Scale。每次调整模型的大小都会产生新的Batch。
  5. 不能修改材质。每次修改材质都会缠身新的Batch。
  6. 不能使用lightmap(烘焙光照贴图),除非是先烘焙,后实例化物体。
  7. 多通道的shader会妨碍批处理操作。比如,几乎unity中所有的着色器在前向渲染中都支持多个光源,并为它们有效地开辟多个通道
*【使用静态批处理】

【使用条件&步骤】
点击目标物体,在Inspector窗口勾选Static。
要注意静态批处理不允许改变位置

shader相关优化

【内置shader使用mobile中的】

相比较其他内置shader,mobile性能更好

【尽量把计算放在对象或逐顶点着色器中】

优化对象数量 > 顶点运算 > 像素运算。
尽量不要把运算拖在片源元色器中计算。

【使用更低精度的值类型进行运算】

1 float 计算速度最慢,适合存储顶点坐标,在顶点着色器中使用。
2 half 计算速度快些,适用纹理坐标等变量。
3 fixed 计算速度最快,适用于颜色变量和归一化后的方向矢量,适合在片元着色器中使用。

【使用shader的lod技术】

与模型的 LOD 技术类似, Shader的LOD技术可以根据条件启用shader片段,当Shader 的 LOD 值满足条件设才会渲染。

【根据硬件性能和平台,调整效果方案】

根据不同的硬件性能,选择性的启用特效。

【尽量不要关闭深度测试】

由于被遮挡的物体无法通过深度测试,就不会再进行后面的渲染处理。

*【控制绘制顺序队列】

从前往后绘制,比从后往前绘制性能好的多。这是因为深度测试的存在减少了被遮挡部分的绘制。
【从前往后绘制的队列 - 不透明物体(Opaque)】
Shader中渲染队列值小于2500的对象都被认为是不透明(Opaque)的物体。如“Background"、“Geometry”、“Alpha Test”。
【从后往前绘制的队列 - 透明物体(Transparent)】
Shader中渲染队列值大于2500的对象都被认为是透明(Transparent)物体。如"Transparent"、"Overlay"等
尽可能地把物体的染队列值设置大于2500从而实现从前向后的渲染提升性能。

其他优化

【打包压缩】

Build settings -> compression Method中设置压缩

*【摄像机视锥剔除( Occlusion culling)】

剔除掉那些不在摄像机的视野范围内的对象,从而避免不必要的计算。
【用法&步骤】
点击摄像机 -> Inspector窗口 -> Camera组件 -> 勾选Occlusion Culling。

*【遮挡剔除技术( Occlusion culling)】

剔除掉那些被其他物体遮挡的看不到的物体,从而提升性能。
【用法&步骤】
unity工具栏 -> Windows -> Rending -> Occlusion culling -> Occlusion窗口 -> 作相关设置 -> Bake

后期效果优化插件Process

指定特效作用范围,不要设置ervay thing。这是因为比如GUI之类的东西没有必要被计算。

【gui和场景使用不同的摄像机渲染】

GUI由于其特殊性大多需要设置成透明。如果GUI与场景物体一同西汉时,并且屏幕占比太多,就会造成很多不必要的overdraw。
可以用两个相机分别渲染ui和场景。

*【减小分辨率】

降低屏幕分辨率是 非常有效 的性能优化手段。尤其对于大屏幕低配置的设备。这时可以使用等比例缩小屏幕分辨率的方法来适当优化。用部分效果来换取性能山的提升
【用法&步骤】

///这里作等比例运算,适配过长或过宽的设备
{
	//获取当前分辨率
	int width = Screen.currentResolution.width;
	int height = Screen.currentResolution.height;
}
///
//设置当前分辨率
Screen.SetResolution(640, 480,true);

unity官方移动平台优化文档
unity性能优化


转载:https://blog.csdn.net/lengyoumo/article/details/105654499
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场