Unity项目优化

 

 

 特殊文件链接

Unity3D研究院之手游开发中所有特殊的文件夹 | 雨松MOMO程序研究院

CPU和GPU的分工链接

Render - 浅谈 CPU 与 GPU 如何分工? - 知乎 

 脚本优化链接

MipMap与LOD是何物?_penchaoo-CSDN博客_mipmaplod偏移怎么调

知识补充:HZ:赫兹,刷新的频率。

        比如显卡的赫兹是144,而显示器的帧率是60,那么帧率就会更不上显卡。每两帧渲染cpu的画面在屏幕上只能显示一帧,那么还有一帧的时候显示器就是黑的,只是太快了,看不出来。这时候就需要更好的显示器了。

        但是一般,我们的手机60Hz就是极限了,再高你的屏幕也看不出来..

        所以这时候就有垂直同步的概念了:设置一个项,把我们显卡的帧率和显示器的帧率做一个强行的同步(如果HZ不同步的话,画面会有撕裂感的,所以说要开垂直同步)。

1.Profiler

在unity的window下面可以打开profiler

点击运行之后 可以在左边面板选择你要监听的部分(可以看CPU,渲染,物理等等),右边第一个面板可以看到其占用情况的曲线

下面面板的左边可以看到不同函数,右边使其占用情况。

(当然了我这个面板选择的是cpu,你也可以选择别的去看看)

2.Statistics

 FPS:渲染物体的数量和GPU性能的影响关系,如上图的数据770.0FPS(1.3ms),表示每帧的间隔为1.3ms,770.2帧。

CPU:占用CPU所用的时间

GPU:GPU渲染所用的时间

Batches(批处理):unity优化的而一种技术,类似于打包。打包的数量。基本上对应于draw call,这个是为了减少draw call的次数。(材质和shader会影响到这个Batches,如果都用同一个材质那么Batches就会变成1)

Saved by batching:节省的打包的次数。

Tris:三角形的数量。

Verts:顶点数(模型的数量)。

Screen:画面的分辨率。  同一行后面是这个是画面占用的显存的大小。

SetPass calls:unity中Shader里面调用pass的次数,如果这个越大那么渲染的压力越大

Shadow casters:影子的计算,比较消耗性能。

Visible skinned meshes:渲染的皮肤的网格的数量。(有皮肤(蒙皮)的网格)

Animations:unity中的animations。

draw call就是CPU调用GPU渲染的次数。

如果说drawcall一开始是一个一个调用格子的话,那么Batches批处理就是圈其中几个一起调用

 

而批处理又有静态批处理(Static),动态批处理等等。有的批处理的要求是要同一种材质。 

美术资源优化:

        一、模型

        1.减少模型中那些没有用的面

        2.合并模型,合并那些静态的模型和贴图。这样可以减少Draw Call的数量

        3.LOD:建筑和复杂的物件用LOD模型和远处剔除来减少同屏面数。(比如吃鸡的里面那些树,你远处看看不清,近了才能看清)。

        可以添加一个LOD Group的组件,但是记住下面Add的模型一定要是该物体的子物体。所以如果你想让他远处变成A,那你就要把A拖进来,变成他的子物体,然后再Add。

        

 

        4.模型的重复利用

        5.地形优化

        

        二、材质

        1.贴图大小

        2.资源重复利用

        3.小物件的贴图合并  (单个物品的贴图最好是一张,最多不易超过3张,相同贴图的材质球统一)

        4.少用透明贴图,因为非常消耗GPU资源

        5.minimap,跟LOD的效果差不多。节省GPU的消耗,但是会增加存储空间的大小。

        6.小场景可以使用PBR材质,用了OBR就一定要用实时灯光才有效果。大场景尽量避免使用PBR材质,大场景可以用烘焙光影。

        7.贴图压缩,对贴图进行PVRT(ios)或者ETC(Android)格式的压缩可以减少大量的内存消耗

        三、灯光

        1、灯光的数量:室外开放式大场景建议只用一盏平行光。室内场景可适当多一点,室内环境可以用reflection probe来加强反射效果。

        2、场景烘焙:大场景和比较复杂的室内场景要避免实时灯光的使用。利用UNITY的烘焙系统把光影烘焙成贴图来实现光影效果。烘培贴图本身是一个浩大的工程,大场景的烘培可以选择性的去烘焙。UNITY里自动分UV功能不好控制,所以一般在max\Maya里分好第2套UV,也可以直接在max\Maya里烘焙好lightmap导入到unity里。

        3.Unity提供了混合模式灯光,所以我们可以用混合灯光来实现LIGHTMAP与实时灯光结合。既:一个大场景中,大件如建筑、地形占据画面较大的物件烘焙lightmap,小物件繁多,占据画面的面积很小可以不用烘焙,把灯光设置为mixed模式.

        四、其他

        1.摄像机上少用镜头效果,要有选择性的使用。

        2.特殊的shader慎用

        

 

=========================================================================

遮挡剔除:

效果:可以看到随着摄像机视野的不断往前,被挡住的部分就直接被剔除了。

对于大场景非常好用。

 

 

实现方法:

        1.选中你要遮挡剔除得物体,然后选择Occludee Static

         

2.选中挡住剔除物的物体,然后设置为Occluder Static 

3.打开window下的Occlusion Culling,然后点击bake烘焙。

4.选择隐藏模式,不要选Edit模式。(选了Edit模式你就看不见效果了(●'◡'●)

 

=========================================================================

光照烘焙

1.把光的Model设置成Baked

2.选中物体,将其勾选上Lightmap Static

 

3.在Window下的lighting下的settings下面去自动烘焙或者手动烘焙

 

4.效果对比

左边为我们烘焙的静态效果,右边为原来的动态光。

可以发现左边烘焙出来的效果更加好,但是不能移动物体(或者场景)了,如果移动的话,就会发现光影效果都是贴图,很假(就暴露了哈哈哈哈哈 

=========================================================================合并mesh

效果

首先可以看到将所有物体合成了同一个物体,然后对应Statistics下面的话

1.Saved by batching由原先的114变成了0,因为原来由很多物体,然后批处理可以节约很多,但是现在变成了一个物体,所以没有节约的,就是单纯的对这个物体操作。

2.Shadow casters由原来的39变成了现在的1,因为原来是由很多物体叠加出来的,所以会有很多的shadow阴影,但是现在只有当前一个物体了,合并了,所有只有1。

实现方法:

1.首先将所有要合并的对象放在一个对象的子集下面

 

2.添加Mesh Conbine脚本,并且设置一个皮肤材质M,有个IsHideChild可以看效果。

Mesh Conbine.cs:

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

public class MeshCombiner : MonoBehaviour {
    public Material m;
    public bool isHideChild;
	void Start () {
        Combine();
        HideChild();

    }



    void Combine()
    {
        MeshFilter[] meshs = GetComponentsInChildren<MeshFilter>();

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

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


        }

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

        //设置材质
        GetComponent<MeshFilter>().sharedMesh = target;
        GetComponent<Renderer>().material = m;
    }
    /// <summary>
    /// 隐藏子对象
    /// </summary>
    private void HideChild()
    {
        if (isHideChild)
        {
            var list = GetComponentsInChildren<Renderer>();
            foreach (var item in list)
            {
                if (GetComponent<Renderer>() != item)
                {
                    item.enabled = false;
                }
            }
        }
    }
}

3.添加Mesh Filter和MeshRenderer

 

=========================================================================

对象池

ObjectPool.cs:

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

public class ObjectPool : MonoBehaviour {

    public int poolCount = 30;

    public GameObject objPf;

    private List<GameObject> objList = new List<GameObject>();
    private void Start()
    {
        InitPool();
    }
    void InitPool()
    {
        for(int i = 0; i < poolCount; i++)
        {
            GameObject go = GameObject.Instantiate(objPf);
            objList.Add(go);
            go.SetActive(false);
            go.transform.parent = this.transform;
        }
    }

    public GameObject GetObj()
    {
        foreach(GameObject go in objList)
        {
            if (go.activeInHierarchy == false)
            {
                go.SetActive(true);
                return go;
            }
        }
        return null;
    }

}

=========================================================================

关于脚本的性能优化:附上链接

Unity性能优化 – 脚本篇 | Tim's Blog

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值