欢迎来到淼淼之森的博客小站。  交流请加我微信好友: studyjava。  也欢迎关注同名公众号:Java学习之道

Unity优化之 draw call 有关的参数

  |   0 评论   |   0 浏览

Unity 优化(一) ------ 优化前了解以及方向

FPS:画面每秒传输帧数,,要避免动作不流畅的最低是 30;值越大性能越好
CPU:计算每帧需要消耗的时间,值越低说明计算越快,值越小性能越好
Batches:将某些 DrawCalls 合并,数量为合并后 DrawCall 的数量。
Tris:三角面
Verts:顶点
SetPass call:Shader 中 CPU 每次运行 Pass 之前都会产生一个 SetPass call。

Unity 优化(二) ------ 资源优化

长时间音乐使用 Mp3 格式(使用压缩格式),例如:背景音乐等
短时间音乐使用 wav 格式(不使用压缩格式),例如:音效
在这里插入图片描述

减少冗余资源和重复资源
A、Resources 目录下的资源不管是否被引用,都会打包进安装包
不使用的资源不要放在 Resources 目录下
B、不同目录下的相同资源文件,如果都被引用,那么都会打包进资源包,造成冗余
保证同一个资源文件在项目中只存放在一个目录位置
资源优化:使用 UWA 工具
渲染优化(GPU)和代码优化(CPU)
GPU:包括场景渲染和灯光处理等
CPU:数值计算
LOD——层级
当模型离视野近时,显示比较精细的模型,离视野比较远时显示比较粗糙的模型。
实现方法:
新建一个空物体,添加 LOD Group 组件,将模型拖进精细度按下图提示拖进对应位置,可根据实际情况调节每个 LOD 的占比。
image.png
遮挡剔除:降低 DrawCall
原理:在摄像机视野内的物体显示,在视野外的物体不显示。
实现方法:
(1)在场景中创建很多物体(方便观察)。全选中—点击 Static—Occluder Static
image.png
(2)点击 Windows—Occlusion Culling
image.png
image.png
(3)选择指定相机用于遮挡剔除计算
image.png
光照贴图:降低 Batches
实现方法:
(1)搭建好场景,选中场景中所有需要被光照的物体—点击 Static—LightmapStatic
image.png
(2)点击 Windowa—Lighting—Settings
image.png
(3)选择需要被烘焙的光源,将模式选择烘焙模式
image.png
(4)Scene—取消勾选—Generate Lighting
image.png
(5)选择烘焙后,下方是烘焙进度
image.png
(6)选择所有被烘焙的光源,取消 Light 勾选
image.png
这时还能看见光照效果,这时因为使用烘焙,生成了光照贴图
image.png
注意:如果觉得光照强度过强,在(4)前可修改
Light 组件中 Indensity 值,值越低,光照越暗
合并 Mesh:要求合并的 mesh 使用相同的材质。
实现方法:
(1)创建一个空物体 MeshCombine,并为其创建几个子物体,子物体层级任意
image.png
(2)新建脚本并挂在到(1)中的空物体 MeshCombine 上

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

public class MeshCombine : MonoBehaviour {

	// Use this for initialization
	void Start () {
        CombineMesh();
	}
    void CombineMesh() 
    {
        MeshFilter[] filters = GetComponentsInChildren<MeshFilter>();//获取空物体下所有子物体的MeshFilter组件并保存为一个数组
        CombineInstance[] combiners = new CombineInstance[filters.Length];//unity提供的一个类,用于处理合并的实例
        //将filters的一些属性设置給combiners
        for (int i = 0; i < combiners.Length; i++) 
        {
            combiners[i].mesh = filters[i].sharedMesh;
            combiners[i].transform = filters[i].transform.localToWorldMatrix;//这里的transform不是一个组件而是一个矩阵转换,用于世界坐标与局部坐标之间的转换
        }
        Mesh finalMesh = new Mesh();
        finalMesh.CombineMeshes(combiners);//合并mesh
        GetComponent<MeshFilter>().sharedMesh = finalMesh;//将合并后的Mesh赋值到父物体上

    }
}

(3)为(1)中的空物体 MeshCombine 添加两个组件:
MeshRender 组件:负责渲染
MeshFilter 组件:用于存放合并后的 mesh
并未 MeshRender 组件选择一个需要的材质。
(4)游戏运行,会将 MeshCombine 下的所有子物体中的 Mesh 合并并赋值到 MeshCombine 物体上,因此场景中将会出现两个一模一样的 mesh,这时在游戏运行时可直接删除其下的子物体,这时可明显看见 Batches 减少。
ObjectPool
对象池的使用可以说是非常常见。直接上代码:

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

public class ObjectPool : MonoBehaviour {

    public int objCount=5;//对象池中该类对象初始生成的个数
    public GameObject buttlePreb;//需要实例化的预制
    private List<GameObject> poolList = new List<GameObject>();//存放对象

	void Start () {
		InitPool();
	}
    //初始化对象池
    void InitPool()
    {
        for (int i = 0; i < objCount; i++) 
        {
            GameObject go = Instantiate(buttlePreb);//实例化对象
            poolList.Add(go);//将实例化的对象添加到对象次
            go.SetActive(false);//设置为隐藏—即未被使用
        }
    }
    //从对象池中取对象
    public GameObject ShowObj()
    {
        foreach (GameObject go in poolList)
        {
            if (!go.activeInHierarchy)
            {
                go.SetActive(true);
                return go;
            }
        }
        return null;
    }
    //使用协程,使得对象生成后等待指定时间隐藏—即放回对象池
    public IEnumerator HideObj(GameObject go)
    {
        yield return new WaitForSeconds(3);
        go.SetActive(false);
    }
}

使用对象池:

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

public class startBuntle : MonoBehaviour {

    private ObjectPool objPool;

	void Start () {
        objPool = GetComponent<ObjectPool>();
	}

	void Update () {
        if (Input.GetKeyUp(KeyCode.K)) 
        {
            GameObject go = objPool.ShowObj();
            if (go != null) 
            {
                //对象次还有可用对象
                go.GetComponent<Rigidbody>().velocity = transform.forward * 30;
                StartCoroutine(objPool.HideObj(go));
            }
        }
	}
}


标题:Unity优化之 draw call 有关的参数
作者:shirln
地址:https://www.mmzsblog.cn/articles/2019/08/29/1567085834529.html

如未加特殊说明,文章均为原创,转载必须注明出处。均采用CC BY-SA 4.0 协议

本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。若本站转载文章遗漏了原文链接,请及时告知,我们将做删除处理!文章观点不代表本网站立场,如需处理请联系首页客服。
• 网站转载须在文章起始位置标注作者及原文连接,否则保留追究法律责任的权利。
• 公众号转载请联系网站首页的微信号申请白名单!

个人微信公众号 ↓↓↓                 

微信搜一搜爱上游戏开发