Unity DrawCalls优化

首先我们需要一个插件 Mesh Baker

下载链接传送门
a.我们创建2个物体分别给予不同的材质球
b.我们先来看一个Betches 及SetPass Calls
在这里插入图片描述
未处理前是6个,这里我把阴影关闭了。默认下可能会更高点

c.我们找到GameObject 工具栏下面的CreateOther 下新建一个TextureBakerAndMeshBaker

d.这个时候我们就开始合并吧

在这里插入图片描述
首先是待合并的MeshRender 当然也可以是SkinMeshRender 然后就是打包的图片图集一些相关的设置然后直接Bake 材质球吧

然后Bake Mesh 一下
在这里插入图片描述

最后我们关闭原来的MeshRender来看一下。可以插件关闭也可以手动关闭

在这里插入图片描述

有关动画的问题

个人测试下来,目前我带有动画的物体合并均需要在Bake成 SkinMeshRender 才可以播放,目前没有深究,我个人的处理办法是把原物体的Render关闭,然后挂在Animation 或者Animator 组件,然后Bake的时候选择SkinMeshRender动画正常播放,并且合并Mesh及材质球后互相不影响。

在这里插入图片描述

有关相同Shader 只是颜色不同的处理,或者就是仅仅颜色不同的材质球如何处理。

这里我们想到最简单的方式是用色块贴图来代替Shader中的RGB数值,这样在合并材质球的时候,它会打包成一个色块的颜色图集,然后对应的UV对上就好了(建议带纹理的贴图,颜色保持一致,如果颜色不一样,那么Shader也要对应的更改成用色块取色的Shader)这样就可以在同一个材质球下不同的颜色可以达到使用同一个材质的效果。

效果如下:
在这里插入图片描述
在这里插入图片描述

最后附一下自己尝试的Mesh 合并的代码及贴图合并的代码(仅供自己以后重构)
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MeshCombine : MonoBehaviour
{

    private void Start()
    {
        CombineMesh();
        // SetColor();
        // CombineMeshColor();
    }

    void CombineMesh()
    {
        MeshFilter[] mfChildren = GetComponentsInChildren<MeshFilter>();
        CombineInstance[] combine = new CombineInstance[mfChildren.Length];


        MeshRenderer[] mrChildren = GetComponentsInChildren<MeshRenderer>();
        Material[] materials = new Material[mrChildren.Length];


        MeshRenderer mrSelf = gameObject.AddComponent<MeshRenderer>();
        MeshFilter mfSelf = gameObject.AddComponent<MeshFilter>();


        Texture2D[] textures = new Texture2D[mrChildren.Length];
        for (int i = 0; i < mrChildren.Length; i++)
        {
            if (mrChildren[i].transform == transform)
            {
                continue;
            }

            materials[i] = mrChildren[i].sharedMaterial;
            Texture2D tx = materials[i].GetTexture("_MainTex") as Texture2D;

            if (tx == null)
            {
                continue;
            }

            Texture2D tx2D = new Texture2D(tx.width, tx.height, TextureFormat.ARGB32, false);
            tx2D.SetPixels(tx.GetPixels(0, 0, tx.width, tx.height));
            tx2D.Apply();
            textures[i] = tx2D;
        }


        Material materialNew = new Material(materials[0]);
        materialNew.CopyPropertiesFromMaterial(materials[0]);
        mrSelf.sharedMaterial = materialNew;


        Texture2D texture = new Texture2D(1024, 1024);
        materialNew.SetTexture("_MainTex", texture);
        Rect[] rects = texture.PackTextures(textures, 10, 1024);


        for (int i = 0; i < mfChildren.Length; i++)
        {
            if (mfChildren[i].transform == transform)
            {
                continue;
            }

            Rect rect = rects[i];

            Mesh meshCombine = mfChildren[i].mesh;
            Vector2[] uvs = new Vector2[meshCombine.uv.Length];
            for (int j = 0; j < uvs.Length; j++)
            {
                uvs[j].x = rect.x + meshCombine.uv[j].x * rect.width;
                uvs[j].y = rect.y + meshCombine.uv[j].y * rect.height;
            }

            meshCombine.uv = uvs;
            combine[i].mesh = meshCombine;
            combine[i].transform = mfChildren[i].transform.localToWorldMatrix;
            mfChildren[i].gameObject.SetActive(false);
        }

        Mesh newMesh = new Mesh();
        newMesh.CombineMeshes(combine, true, true); 
        mfSelf.mesh = newMesh;
    }

    void CombineMeshColor()
    {

        MeshFilter[] mfChildren = GetComponentsInChildren<MeshFilter>();
        CombineInstance[] combine = new CombineInstance[mfChildren.Length];


        MeshRenderer[] mrChildren = GetComponentsInChildren<MeshRenderer>();
        Material[] materials = new Material[mrChildren.Length];


        MeshRenderer mrSelf = gameObject.AddComponent<MeshRenderer>();
        MeshFilter mfSelf = gameObject.AddComponent<MeshFilter>();


        // Texture2D[] textures = new Texture2D[mrChildren.Length];
        for (int i = 0; i < mrChildren.Length; i++)
        {
            if (mrChildren[i].transform == transform)
            {
                continue;
            }

            materials[i] = mrChildren[i].sharedMaterial;
            //  Texture2D tx = materials[i].GetTexture("_MainTex") as Texture2D;

            // if (tx == null)
            // {
            //     continue;
            // }
            //
            // Texture2D tx2D = new Texture2D(tx.width, tx.height, TextureFormat.ARGB32, false);
            // tx2D.SetPixels(tx.GetPixels(0, 0, tx.width, tx.height));
            // tx2D.Apply();
            // textures[i] = tx2D;
        }


        Material materialNew = new Material(materials[0]);
        materialNew.CopyPropertiesFromMaterial(materials[0]);
        mrSelf.sharedMaterial = materialNew;


        // Texture2D texture = new Texture2D(1024, 1024);
        // materialNew.SetTexture("_MainTex", texture);
        // Rect[] rects = texture.PackTextures(textures, 10, 1024);


        for (int i = 0; i < mfChildren.Length; i++)
        {
            if (mfChildren[i].transform == transform)
            {
                continue;
            }


            Mesh meshCombine = mfChildren[i].mesh;
            Vector2[] uvs = new Vector2[meshCombine.uv.Length];
       
            meshCombine.uv = uvs;
            combine[i].mesh = meshCombine;
            combine[i].transform = mfChildren[i].transform.localToWorldMatrix;
            mfChildren[i].gameObject.SetActive(false);
        }

        Mesh newMesh = new Mesh();
        newMesh.CombineMeshes(combine, true, true); //合并网格
        mfSelf.mesh = newMesh;
    }
    
}

这段代码仅仅是参考理解原理使用。效果达不到上述插件的效果(仅理解)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值