关于ShaderLab 内存问题

2017-3-28 雨辰 遇到的一些问题

由于模型导入是Unity生成引用内建的材质球,导致shaderLab内存占用。美术可以通过修改导入配置。外我这边也写替换到unity内建shader 的引用方法:


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Text.RegularExpressions;
using Assets.Foundation.Localization.Editor;


public class ImportMaterialTool : AssetPostprocessor
{
    public static List<Material> AllMaterialsList = new List<Material>();
    public static List<Material> AllMaterialsList2 = new List<Material>();

    public static bool m_bNeedWaiting = false;
    public static bool m_bEnableDelete = false;

    public static string MATERIALFILESUFFIX = ".fbx";
    public static string SHADERFILESUFFIX = ".mat";

    public static int m_nObjectNum = 0;
    public static int m_nImportNum = 0;

    private void OnPostprocessModel(GameObject mGameObjectmodel)
    {
        if (null == mGameObjectmodel)
            return;
        if (!m_bEnableDelete)
            return;
        m_bEnableDelete = false;

        Renderer[] mRenderList = mGameObjectmodel.GetComponentsInParent<Renderer>();
        if (mRenderList == null)
            return;
        foreach (Renderer render in mRenderList)
        {
            render.sharedMaterials = new Material[render.sharedMaterials.Length];
        }
        m_bNeedWaiting = false;
    }

    private static IEnumerator DefalutMaterialListClearCoroutine(List<Object> GameObjectList)
    {
        foreach (Object mGameObject in GameObjectList)
        {
            while (m_bNeedWaiting)
                yield return null;
            DefalutMaterialClearByBoject(mGameObject as GameObject);
        }
    }

    private static void DefalutMaterialClearByBoject(GameObject mTempGameObject)
    {
        if (null == mTempGameObject)
            return;
        string GameObjectAssetPath = AssetDatabase.GetAssetPath(mTempGameObject);
        ModelImporter modelimporter = AssetImporter.GetAtPath(GameObjectAssetPath) as ModelImporter;
        if (modelimporter == null)
            return;
        m_bEnableDelete = true;
        m_bNeedWaiting = true;

        modelimporter.importMaterials = true;
        modelimporter.importMaterials = false;
        AssetDatabase.ImportAsset(GameObjectAssetPath);
        m_nImportNum++;
        if (m_nImportNum == m_nObjectNum)
        {
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();

            ClearData1();
            EditorUtility.DisplayDialog("提示", "清理DefalutMaterial结束,请清理重复shader", "OK");
        }
    }

    private static void AllDefalutMaterialClearFunc()
    {
        List<Object> GameObjectList = new List<Object>();
        var FbxPathList = AssetDatabase.GetAllAssetPaths();

        for (int index = 0; index < FbxPathList.Length; index++)
        {
            string FileSuffix = Path.GetExtension(FbxPathList[index]);
            if (FileSuffix.ToLower() == MATERIALFILESUFFIX)
            {
                GameObject mTempGameObject = AssetDatabase.LoadAssetAtPath(FbxPathList[index], typeof(GameObject)) as GameObject;
                if (mTempGameObject != null)
                {
                    ModelImporter modelimporter = ModelImporter.GetAtPath(FbxPathList[index]) as ModelImporter;
                    if (modelimporter != null && !modelimporter.importMaterials)
                        GameObjectList.Add(mTempGameObject);
                }
            }
        }
        m_nObjectNum = GameObjectList.Count;
        EditorCoroutine.Start(DefalutMaterialListClearCoroutine(GameObjectList));
    }

    private static void Changershader()
    {
        var MaterialsPathList = AssetDatabase.GetAllAssetPaths();

        for (int index = 0; index < MaterialsPathList.Length; index++)
        {
            string FileSuffix = Path.GetExtension(MaterialsPathList[index]);
            if (FileSuffix.ToLower() == SHADERFILESUFFIX)
            {
                Material mTempMaterial = AssetDatabase.LoadAssetAtPath(MaterialsPathList[index], typeof(Material)) as Material;
                AllMaterialsList.Add(mTempMaterial);
            }
        }

        Shader DefaultMaterialUnlitShader = Shader.Find("Unlit/DefaultMaterialUnlitShader");
        if (DefaultMaterialUnlitShader == null)
        {
            Debug.Log("Unlit/DefaultMaterialUnlitShader is null!");
            return;
        }
        for (int index = 0; index < AllMaterialsList.Count; index++)
        {
            Material mTempMaterial = AllMaterialsList[index];
            if (mTempMaterial.shader.name == "Standard")
            {
                AllMaterialsList[index].shader = DefaultMaterialUnlitShader;
                EditorUtility.SetDirty(AllMaterialsList[index]);
            }

        }
    }

    private static void ClearRepetitionShader()
    {
        var MaterialsPathList = AssetDatabase.GetAllAssetPaths();

        for (int index = 0; index < MaterialsPathList.Length; index++)
        {
            string FileSuffix = Path.GetExtension(MaterialsPathList[index]);
            if (FileSuffix == SHADERFILESUFFIX)
            {
                Material mTempMaterial = AssetDatabase.LoadAssetAtPath(MaterialsPathList[index], typeof(Material)) as Material;
                AllMaterialsList2.Add(mTempMaterial);
            }
        }

        for (int index = 0; index < AllMaterialsList2.Count; index++)
        {
            Shader TempShader = Shader.Find(AllMaterialsList2[index].shader.name);
            if (TempShader == null || TempShader.name == "Standard" || TempShader.name == "Particles/Alpha Blended Premultiply")
                return;
            AllMaterialsList2[index].shader = TempShader;
            EditorUtility.SetDirty(AllMaterialsList2[index]);
        }
    }

    private static void ClearData1()
    {
        m_nObjectNum = 0;
        m_nImportNum = 0;

        m_bNeedWaiting = false;
        m_bEnableDelete = false;
    }

    private static void ClearData2()
    {
        AllMaterialsList.Clear();
        AllMaterialsList2.Clear();
    }


    [MenuItem("Game301/命令/Shader优化/清理DefalutMaterial")]
    private static void ImportMaterialFunction1()
    {
        AllDefalutMaterialClearFunc();
    }

    [MenuItem("Game301/命令/Shader优化/清理重复shader")]
    private static void ImportMaterialFunction2()
    {
        Changershader();
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();

        ClearRepetitionShader();
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();

        ClearData2();

        EditorUtility.DisplayDialog("提示", "清理重复shader完成,请打bundle包", "OK");
    }
}




标签: Unity3D-Shader

发表评论:

朱文华 joyimp|@2011-2019 京ICP备16030765号