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

(整理总结)unity性能优化

2017-11-08 16:58 357 查看

一 减少Draw call

Draw call就是cpu对图形绘制接口的调用,CPU通过调用图形库(directx/opengl)接口,命令GPU进行渲染操作。

 

每一次绘制CPU都要调用DrawCall,调用DrawCall之前,CPU要进行很多准备工作:检测渲染状态,提交渲染所需要的数据,提交渲染所需要的结果,当DrawCall过多CPU会有很多额外的开销用于准备工作,CPU负载,GPU限制。

解决方案:把小的DrawCall合并为一个大的DrawCall中,这就是批处理思想。

使用批处理的注意事项:

合并的网格会在一次渲染任务中进行绘制,他们的渲染数据,渲染状态和shader都是一样的,因此合并的条件至少是:同材质、同贴图、同shader。最好网格顶点格式也一致。

尽量避免使用大量小的网格,当确实需要时,考虑是否要合并。

避免使用过多的材质,尽量共享材质。

网格合并的顶点数量有上限(Unity中好像是65535)

合并本身有消耗,因此尽量在编辑器下进行合并

确实需要在运行时合并的,将静态的物体和动态的物体分开合并:静态的合并一次就可以,动态的只要有物体发生变换就要重新合并。

参考:https://zhuanlan.zhihu.com/p/26386905

在unity菜单栏window-profiler可以看项目性能数据:



二 资源优化

优化标准:
Mesh

动态模型:面片数材质数<3

骨骼数<50

静态模型:定点数<500

长时间音乐(背景音乐)压缩格式mp3

短时间音乐(音效)非压缩格式wav(例如战斗音效,如果压缩,攻击一次就需要压缩一次)

贴图长宽<1025

Shader

减少复杂数学运算

减少discard操作

一贴图优化:

二模型优化:

减少顶点数量

三减少冗余资源和重复资源:

   1.Resources目录下不管资源是否被使用都会被打包

   2.不同目录下的相同资源文件,如果被引用,那么大宝都会打包进资源包

   3.保证同一个资源文件在项目中只存放在一个目录位置



相关文档:http://blog.csdn.net/u012565990/article/details/51794486

三 渲染优化

一 LOD层级

   让模型在视野的不同范围内显示不同精度的模型,距离越远模型越粗糙,渲染越简单。

   在属性面板添加LOD Group组件,设置摄像机视野显示的模型。






具体细节设置在Edit-projectsetting-QualitySetting

二 遮挡剔除

在摄像机视野范围内的渲染显示,不在范围内的不渲染显示

1. 全选要进行遮挡剔除的物体

2. 在static里面选中OcclusionCulling Static属性

3. 在Window-Occlusion Culling中设置烘焙,选择目标摄像机

三 光照贴图

把环境的光照效果提前计算好,生成一张光照贴图,这样以后就不需要再去实时渲染环境的光照效果

1.选择环境,再static里面选择lightmap Static

2.在window-Lightting-setting设置烘焙

3.在资源文件夹中会生成光照贴图信息,彩色的一个属性图标

四 网格合并

把多个物体合并成为一个大的物体,需要通过代码实现,把要合并的物体放到一个物体下面作为子物体:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MeshCombiner : MonoBehaviour {

// Use this for initialization
void Start () {
MeshCombine();
}

void MeshCombine()
{
MeshFilter[] filters = GetComponentsInChildren<MeshFilter>();

CombineInstance[] combiners = new CombineInstance[filters.Length];

for(int i = 0; i < filters.Length; i++)
{
combiners[i].mesh = filters[i].sharedMesh;
combiners[i].transform = filters[i].transform.localToWorldMatrix;
}

Mesh finalMesh = new Mesh();
finalMesh.CombineMeshes(combiners);

GetComponent<MeshFilter>().sharedMesh = finalMesh;
}


四 其他优化

一  对象池
   当有物体大量重复出现时可以使用对象池去优化,例如子弹,每此扣动扳机都要射出一发子弹,实例化一个子弹,太浪费性能,这时候就可以去使用对象池解决。
   参考博客:http://blog.csdn.net/qq_35957011/article/details/73187706
二 代码编写

   1.尽量不要动态的instantiate和destroy
object,使用object pool

   2.尽量不要再update函数中做复杂计算,如有需要,可以隔N帧(FixedUpdate)计算一次

   3.不要动态的产生字符串,如Debug.Log("boo" + "hoo"),尽量预先创建好这些字符串资源

   4.cache一些东西,在update里面尽量避免search,如GameObject.FindWithTag("")、GetComponent这样的调用,可以在start中预先存起来

   5.尽量减少函数调用栈,用x = (x
> 0 ? x : -x);代替x = Mathf.Abs(x)

   参考博客:http://blog.csdn.net/leonwei/article/details/18042603

三  其他优化博文

       http://www.cnblogs.com/harlan1009/p/3970584.html

       http://www.cnblogs.com/chwen/p/4396515.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息