• Unity优化(1)——合并Mesh


    在某些移动端项目中,对于DrawCall的要求是很严格的,我们一般查看DrawCall可以通过Statistics里面的Batches进行查看,一般对于移动设备的Batches要控制在200左右比较合适,所以降低Batches是很重要的。

    我们常常会遇到一个物体下挂载很多很多个子物体,子物体的模型又比较精细,且都是静态的Mesh,这样就会造成大量的DrawCall,我们多次渲染一个小Mesh和一次渲染一个大Mesh之间需要取得平衡,保持帧率稳定在目标数字,这时候我们可以考虑使用合并Mesh,就比如下图中

    这里面有非常多的面,在我们不进行处理的时候,可以看到我们的帧率和Mesh

    基本稳定在100左右,且Batch在800左右,消耗了很多的DrawCall,所以我们一次性处理一个大的Mesh,减少DrawCall,而不是一次处理一个小的mesh,为了合并Mesh,对于相同的一些物体,

    我们可以通过代码直接进行合并,代码如下:

    1. using UnityEngine;
    2. public class MeshCombine : MonoBehaviour
    3. {
    4. private void Start()
    5. {
    6. CombineMeshs();
    7. }
    8. void CombineMeshs()
    9. {
    10. MeshFilter[] meshFilters = GetComponentsInChildren();
    11. CombineInstance[] combines = new CombineInstance[meshFilters.Length];
    12. for (int i = 0; i < meshFilters.Length; i++)
    13. {
    14. combines[i].mesh = meshFilters[i].sharedMesh;
    15. combines[i].transform = meshFilters[i].transform.localToWorldMatrix;
    16. meshFilters[i].gameObject.SetActive(false);//关闭原始对象
    17. }
    18. MeshFilter parentFilter = gameObject.AddComponent();
    19. parentFilter.mesh = new Mesh();
    20. parentFilter.mesh.CombineMeshes(combines);
    21. MeshRenderer parentRender = gameObject.AddComponent();
    22. parentRender.material = meshFilters[0].GetComponent().sharedMaterial;
    23. gameObject.SetActive(true);
    24. }
    25. }

    开箱即用,挂载到父物体身上,就可以了,这里我们就用到了Combine这个方法,我们就是通过两个数组,一个数组把子物体的MeshFilter组件存储起来,然后创建一个和子物体长度相同的CombineInstace数组,把组件的mesh传递给它,最后在父物体身上创建meshFilter组件,就可以了

    但是其实现在有很多Mesh合并的工具,比如这个叫Simple LOD的,下载地址如下:

    文件 (lanzout.com)

    导入后选中父物体,选择Tools中的SimpleLod

    选择Merge child meshes即可!

  • 相关阅读:
    DeepLabCut简单安装
    云原生 | Docker - [Portainer]
    axios 代理服务器转发 get post
    Linux MMC子系统 - 2.eMMC 5.1总线协议浅析
    Opencv中的GrabCut图像分割
    双指针_快乐数
    各种开发语言运行时占用内存情况比较
    Prometheus & Grafana 的安装
    这些提高摸鱼效率的自动化测试技巧,提高打工人幸福感~
    SpringBoot--@InitBinder--使用/原理
  • 原文地址:https://blog.csdn.net/leikang111/article/details/134418943