void CreatePackageForExampleMaterials()
    {
        // Check if examples folder is "Assets/MeshBaker/Examples"
        // Get all materials in examples.
        string unityPackageFilename;
        string examplesPathRelative = GetRelativeExamplesPath();

        if (examplesPathRelative == null)
        {
            Debug.LogError("Cannot package example materials as no Mesh Baker Example scenes were found. Renaming example scenes may cause this error.");
            return;
        }

        MBVersion.PipelineType pipelineType = MBVersion.DetectPipeline();
        if (pipelineType == MBVersion.PipelineType.Default)
        {
            unityPackageFilename = examplesPathRelative + "/Examples_Default.unitypackage";
        }
        else if (pipelineType == MBVersion.PipelineType.HDRP)
        {
            unityPackageFilename = examplesPathRelative + "/Examples_HDRP.unitypackage";
        }
        else if (pipelineType == MBVersion.PipelineType.URP)
        {
            unityPackageFilename = examplesPathRelative + "/Examples_URP.unitypackage";
        }
        else
        {
            Debug.LogError("Unknown pipeline type.");
            return;
        }

        string[]      matGIDs            = AssetDatabase.FindAssets("t:Material", new string[] { examplesPathRelative });
        string[]      assetPathNames     = new string[matGIDs.Length];
        List <string> assetPathNamesList = new List <string>();

        for (int i = 0; i < matGIDs.Length; i++)
        {
            string path = AssetDatabase.GUIDToAssetPath(matGIDs[i]);
            if (!path.Contains("SceneBasicTextureArrayAssets") && !path.EndsWith(".fbx")) // don't do texture array assets.
            {
                assetPathNamesList.Add(path);
                // Debug.Log(path);
            }
        }
        assetPathNames = assetPathNamesList.ToArray();

        Debug.Log("Found " + assetPathNames.Length + " materials in " + examplesPathRelative);

        AssetDatabase.ExportPackage(assetPathNames, unityPackageFilename);

        Debug.Log("Create Unity Package: " + unityPackageFilename);
    }
        public static string ValidatePlayerSettingsDefineSymbols()
        {
            // Check that the needed defines exist or are present when they should not be.
            MBVersion.PipelineType pipelineType = MBVersion.DetectPipeline();
            BuildTargetGroup       targetGroup  = EditorUserBuildSettings.selectedBuildTargetGroup;
            string scriptDefines = PlayerSettings.GetScriptingDefineSymbolsForGroup(targetGroup);

            string s = "";

            if (pipelineType == MBVersion.PipelineType.HDRP)
            {
                if (!scriptDefines.Contains(MBVersion.MB_USING_HDRP))
                {
                    s += "The GraphicsSettings -> Render Pipeline Asset is configured to use HDRP. Please add 'MB_USING_HDRP' to PlayerSettings -> Scripting Define Symbols for all the build platforms " +
                         " that you are targeting. If there are compile errors check that the MeshBakerCore.asmdef file has references for:\n\n" +
                         "   Unity.RenderPipelines.HighDefinition.Runtime\n" +
                         "   Unity.RenderPipelines.HighDefinition.Config.Runtime (Unity 2019.3+)\n";
                }

                /*
                 * Type tp = Type.GetType("UnityEngine.Rendering.HighDefinition.HDAdditionalCameraData");
                 * if (tp == null)
                 * {
                 *  s += "The class 'HDAdditionalCameraData' cannot be found by the MeshBaker assembly. Ensure that the following assemblies are referenced by the MeshBaker.asmdef file: \n" +
                 *      "    Unity.RenderPipelines.HighDefinition.Runtime\n" +
                 *      "    Unity.RenderPipelines.HighDefinition.Config.Runtime (Unity 2019.3+)\n\n"+
                 *      "Or download the HDRP version of the package from the asset store.";
                 * }
                 */
            }
            else
            {
                if (scriptDefines.Contains(MBVersion.MB_USING_HDRP))
                {
                    s += "Please remove 'MB_USING_HDRP' from PlayerSettings -> Scripting Define Symbols for the current build platform. If this define is present there may be compile errors because Mesh Baker tries to access classes which only exist in the HDRP API.";
                }
            }

            if (s.Length > 0)
            {
                return(s);
            }
            else
            {
                return(null);
            }
        }
    string MapDefault2OtherShader(string defaultName, MBVersion.PipelineType pipelineType)
    {
        // pipelineType
        // Unsupported = 0
        // Default = 1
        // URP = 2
        // HDRP = 3
        for (int i = 0; i < shaderMap_Unsupported_Default_URP_HDRP.Length; i++)
        {
            if (defaultName == shaderMap_Unsupported_Default_URP_HDRP[i][(int)MBVersion.PipelineType.Default])
            {
                return(shaderMap_Unsupported_Default_URP_HDRP[i][(int)pipelineType]);
            }
        }

        return(null);
    }
        public void DoSpecialRenderPipeline_TexturePackerFastSetup(GameObject cameraGameObject)
        {
#if MB_USING_HDRP && UNITY_2018_4_OR_NEWER
            MBVersion.PipelineType pipelineType = DetectPipeline();
            if (pipelineType != MBVersion.PipelineType.HDRP)
            {
                Debug.LogError("The 'PlayerSettings -> Other Settings -> Scripting Define Symbols' included the symbol 'MB_USING_HDRP' which should only be used " +
                               "if the GraphicsSettings -> Render Pipeline Asset is HDRenderPipelineAsset. The Render Pipeline Asset is NOT HDRenderPipelineAsset. Please " +
                               " remove the symbol MB_USING_HDRP from PlayerSettings -> Other Settings -> Scripting Define Symbols");
            }

            HDAdditionalCameraData acd = cameraGameObject.GetComponent <HDAdditionalCameraData>();
            if (acd == null)
            {
                acd = cameraGameObject.AddComponent <HDAdditionalCameraData>();
            }

            acd.volumeLayerMask = LayerMask.GetMask("UI");
#endif
        }
    void Start()
    {
#if UNITY_2018_4_OR_NEWER
        MBVersion.PipelineType pipelineType = MBVersion.DetectPipeline();
        int materialPipeline = GetMaterialPipelineType();
        // Do not prompt if example materials cannot be found, are using an unsupported shader, or are already suitable for the current pipeline
        if (materialPipeline != -1 && pipelineType != (MBVersion.PipelineType)materialPipeline)
        {
            if (pipelineType != MBVersion.PipelineType.Unsupported)
            {
                bool convert = EditorUtility.DisplayDialog(
                    "Different Pipline Detected",
                    "Would you like to try converting the default Mesh Baker example scene materials to suit the " + pipelineType + " pipeline?",
                    "Yes",
                    "No");

                if (convert)
                {
                    MigrateMaterials();
                    if (pipelineType == MBVersion.PipelineType.HDRP)
                    {
                        Debug.LogWarning("If the Mesh Baker Example Scenes appear dark, try adding an Empty GameObject to the scene, adding a 'Volume' component to it, and assigning that volume one of the default profiles.");
                    }
                }
            }
            else
            {
                Debug.LogWarning("Mesh Baker's example scenes only support the Default Pipeline, URP, and HDRP.");
            }
        }
#endif
#if !MB_ALLOW_ADD_MIGRATE_MAT_SCRIPT
        // Add the MB_ALLOW_ADD_MIGRATE_MAT_SCRIPT to script defines to add this to scenes.
        DestroyImmediate(this.gameObject);
#endif
    }
Beispiel #6
0
            internal static void BuildAtlas(
                AtlasPackingResult packedAtlasRects,
                List <MB_TexSet> distinctMaterialTextures,
                int propIdx,
                int atlasSizeX, int atlasSizeY,
                Mesh m,
                List <Material> generatedMats,
                ShaderTextureProperty property,
                MB3_TextureCombinerPipeline.TexturePipelineData data,
                MB3_TextureCombiner combiner,
                MB2_EditorMethodsInterface textureEditorMethods,
                MB2_LogLevel LOG_LEVEL)
            {
                // Collect vertices and quads for mesh that we will use for the atlas.
                Debug.Assert(generatedMats.Count == 0, "Previous mats should have been destroyed");
                generatedMats.Clear();
                List <Vector3> vs  = new List <Vector3>();
                List <Vector2> uvs = new List <Vector2>();

                // One submesh and material per texture that we are packing
                List <int>[] ts = new List <int> [distinctMaterialTextures.Count];
                for (int i = 0; i < ts.Length; i++)
                {
                    ts[i] = new List <int>();
                }

                MeshBakerMaterialTexture.readyToBuildAtlases = true;
                GC.Collect();
                MB3_TextureCombinerPackerRoot.CreateTemporaryTexturesForAtlas(data.distinctMaterialTextures, combiner, propIdx, data);

                Rect[] uvRects = packedAtlasRects.rects;
                for (int texSetIdx = 0; texSetIdx < distinctMaterialTextures.Count; texSetIdx++)
                {
                    MB_TexSet texSet = distinctMaterialTextures[texSetIdx];
                    MeshBakerMaterialTexture matTex = texSet.ts[propIdx];

                    if (LOG_LEVEL >= MB2_LogLevel.trace)
                    {
                        Debug.Log(string.Format("Adding texture {0} to atlas {1} for texSet {2} srcMat {3}", matTex.GetTexName(), property.name, texSetIdx, texSet.matsAndGOs.mats[0].GetMaterialName()));
                    }
                    Rect      r  = uvRects[texSetIdx];
                    Texture2D t  = matTex.GetTexture2D();
                    int       x  = Mathf.RoundToInt(r.x * atlasSizeX);
                    int       y  = Mathf.RoundToInt(r.y * atlasSizeY);
                    int       ww = Mathf.RoundToInt(r.width * atlasSizeX);
                    int       hh = Mathf.RoundToInt(r.height * atlasSizeY);
                    r = new Rect(x, y, ww, hh);
                    if (ww == 0 || hh == 0)
                    {
                        Debug.LogError("Image in atlas has no height or width " + r);
                    }
                    DRect samplingRect = texSet.ts[propIdx].GetEncapsulatingSamplingRect();
                    Debug.Assert(!texSet.ts[propIdx].isNull, string.Format("Adding texture {0} to atlas {1} for texSet {2} srcMat {3}", matTex.GetTexName(), property.name, texSetIdx, texSet.matsAndGOs.mats[0].GetMaterialName()));

                    AtlasPadding padding = packedAtlasRects.padding[texSetIdx];
                    AddNineSlicedRect(r, padding.leftRight, padding.topBottom, samplingRect.GetRect(), vs, uvs, ts[texSetIdx], t.width, t.height, t.name);

                    Material mt = new Material(Shader.Find("MeshBaker/Unlit/UnlitWithAlpha"));

                    bool isSavingAsANormalMapAssetThatWillBeImported = property.isNormalMap && data._saveAtlasesAsAssets;
                    MBVersion.PipelineType pipelineType = MBVersion.DetectPipeline();
                    if (pipelineType == MBVersion.PipelineType.URP)
                    {
                        ConfigureMaterial_DefaultPipeline(mt, t, isSavingAsANormalMapAssetThatWillBeImported, LOG_LEVEL);
                        //ConfigureMaterial_URP(mt, t, isSavingAsANormalMapAssetThatWillBeImported, LOG_LEVEL);
                    }
                    else if (pipelineType == MBVersion.PipelineType.HDRP)
                    {
                        ConfigureMaterial_DefaultPipeline(mt, t, isSavingAsANormalMapAssetThatWillBeImported, LOG_LEVEL);
                    }
                    else
                    {
                        ConfigureMaterial_DefaultPipeline(mt, t, isSavingAsANormalMapAssetThatWillBeImported, LOG_LEVEL);
                    }

                    generatedMats.Add(mt);
                }

                // Apply to the mesh
                m.Clear();
                m.vertices     = vs.ToArray();
                m.uv           = uvs.ToArray();
                m.subMeshCount = ts.Length;
                for (int i = 0; i < m.subMeshCount; i++)
                {
                    m.SetIndices(ts[i].ToArray(), MeshTopology.Triangles, i);
                }
                MeshBakerMaterialTexture.readyToBuildAtlases = false;
            }
        public bool CollectPropertyNames(List <ShaderTextureProperty> texPropertyNames, ShaderTextureProperty[] shaderTexPropertyNames, List <ShaderTextureProperty> _customShaderPropNames, Material resultMaterial, MB2_LogLevel LOG_LEVEL)
        {
#if UNITY_2019_3_OR_NEWER
            // 2018.2 and up
            // Collect the property names from the shader
            // Check with the lists of property names to flag which ones are normal maps.
            if (resultMaterial != null && resultMaterial.shader != null)
            {
                Shader s = resultMaterial.shader;

                for (int i = 0; i < s.GetPropertyCount(); i++)
                {
                    if (s.GetPropertyType(i) == UnityEngine.Rendering.ShaderPropertyType.Texture)
                    {
                        string matPropName = s.GetPropertyName(i);
                        if (resultMaterial.GetTextureOffset(matPropName) != new Vector2(0f, 0f))
                        {
                            if (LOG_LEVEL >= MB2_LogLevel.warn)
                            {
                                Debug.LogWarning("Result material has non-zero offset for property " + matPropName + ". This is probably incorrect.");
                            }
                        }

                        if (resultMaterial.GetTextureScale(matPropName) != new Vector2(1f, 1f))
                        {
                            if (LOG_LEVEL >= MB2_LogLevel.warn)
                            {
                                Debug.LogWarning("Result material should probably have tiling of 1,1 for propert " + matPropName);
                            }
                        }

                        ShaderTextureProperty pn = null;
                        // We need to know if the property is a normal map or not.
                        // first check the list of default names
                        for (int defaultIdx = 0; defaultIdx < shaderTexPropertyNames.Length; defaultIdx++)
                        {
                            if (shaderTexPropertyNames[defaultIdx].name == matPropName)
                            {
                                pn = new ShaderTextureProperty(matPropName, shaderTexPropertyNames[defaultIdx].isNormalMap);
                            }
                        }

                        // now check the list of custom property names
                        for (int custPropIdx = 0; custPropIdx < _customShaderPropNames.Count; custPropIdx++)
                        {
                            if (_customShaderPropNames[custPropIdx].name == matPropName)
                            {
                                pn = new ShaderTextureProperty(matPropName, _customShaderPropNames[custPropIdx].isNormalMap);
                            }
                        }

                        if (pn == null)
                        {
                            pn = new ShaderTextureProperty(matPropName, false, true);
                        }

                        texPropertyNames.Add(pn);
                    }
                }

                // If using URP or HDRP AND using a default /Lit shader AND both _BaseMap and _MainTex are present, get rid of _MainTex since its essentially a duplicate of _BaseMap
                MBVersion.PipelineType pipelineType = DetectPipeline();
                int  _MainTexIndex = texPropertyNames.FindIndex(pn => pn.name.Equals("_MainTex"));
                bool endsWithLit   = s.name.EndsWith("/Lit");
                if (pipelineType == MBVersion.PipelineType.URP && endsWithLit && _MainTexIndex != -1 && texPropertyNames.FindIndex(pn => pn.name.Equals("_BaseMap")) != -1)
                {
                    texPropertyNames.RemoveAt(_MainTexIndex);
                    //Debug.Log("Removed _MainTex");
                }
                // HDRP uses _BaseColorMap instead of _BaseMap but same idea
                if (pipelineType == MBVersion.PipelineType.HDRP && endsWithLit && _MainTexIndex != -1 && texPropertyNames.FindIndex(pn => pn.name.Equals("_BaseColorMap")) != -1)
                {
                    texPropertyNames.RemoveAt(_MainTexIndex);
                    //Debug.Log("Removed _MainTex");
                }
            }

            return(true);
#elif UNITY_2018_3_OR_NEWER
            // 2018.2 and up
            // Collect the property names from the material
            // Check with the lists of property names to flag which ones are normal maps.
            string[] matPropertyNames = resultMaterial.GetTexturePropertyNames();
            for (int matIdx = 0; matIdx < matPropertyNames.Length; matIdx++)
            {
                string matPropName = matPropertyNames[matIdx];
                if (resultMaterial.GetTextureOffset(matPropName) != new Vector2(0f, 0f))
                {
                    if (LOG_LEVEL >= MB2_LogLevel.warn)
                    {
                        Debug.LogWarning("Result material has non-zero offset for property " + matPropName + ". This is probably incorrect.");
                    }
                }

                if (resultMaterial.GetTextureScale(matPropName) != new Vector2(1f, 1f))
                {
                    if (LOG_LEVEL >= MB2_LogLevel.warn)
                    {
                        Debug.LogWarning("Result material should probably have tiling of 1,1 for propert " + matPropName);
                    }
                }

                ShaderTextureProperty pn = null;
                // We need to know if the property is a normal map or not.
                // first check the list of default names
                for (int defaultIdx = 0; defaultIdx < shaderTexPropertyNames.Length; defaultIdx++)
                {
                    if (shaderTexPropertyNames[defaultIdx].name == matPropName)
                    {
                        pn = new ShaderTextureProperty(matPropName, shaderTexPropertyNames[defaultIdx].isNormalMap);
                    }
                }

                // now check the list of custom property names
                for (int custPropIdx = 0; custPropIdx < _customShaderPropNames.Count; custPropIdx++)
                {
                    if (_customShaderPropNames[custPropIdx].name == matPropName)
                    {
                        pn = new ShaderTextureProperty(matPropName, _customShaderPropNames[custPropIdx].isNormalMap);
                    }
                }

                if (pn == null)
                {
                    pn = new ShaderTextureProperty(matPropName, false, true);
                }

                texPropertyNames.Add(pn);
            }

            return(true);
#else
            { // Pre 2018.2, doesn't have API for querying material for property names.
                //Collect the property names for the textures
                string shaderPropStr = "";
                for (int i = 0; i < shaderTexPropertyNames.Length; i++)
                {
                    if (resultMaterial.HasProperty(shaderTexPropertyNames[i].name))
                    {
                        shaderPropStr += ", " + shaderTexPropertyNames[i].name;
                        if (!texPropertyNames.Contains(shaderTexPropertyNames[i]))
                        {
                            texPropertyNames.Add(shaderTexPropertyNames[i]);
                        }
                        if (resultMaterial.GetTextureOffset(shaderTexPropertyNames[i].name) != new Vector2(0f, 0f))
                        {
                            if (LOG_LEVEL >= MB2_LogLevel.warn)
                            {
                                Debug.LogWarning("Result material has non-zero offset. This is may be incorrect.");
                            }
                        }
                        if (resultMaterial.GetTextureScale(shaderTexPropertyNames[i].name) != new Vector2(1f, 1f))
                        {
                            if (LOG_LEVEL >= MB2_LogLevel.warn)
                            {
                                Debug.LogWarning("Result material should have tiling of 1,1");
                            }
                        }
                    }
                }

                for (int i = 0; i < _customShaderPropNames.Count; i++)
                {
                    if (resultMaterial.HasProperty(_customShaderPropNames[i].name))
                    {
                        shaderPropStr += ", " + _customShaderPropNames[i].name;
                        texPropertyNames.Add(_customShaderPropNames[i]);
                        if (resultMaterial.GetTextureOffset(_customShaderPropNames[i].name) != new Vector2(0f, 0f))
                        {
                            if (LOG_LEVEL >= MB2_LogLevel.warn)
                            {
                                Debug.LogWarning("Result material has non-zero offset. This is probably incorrect.");
                            }
                        }
                        if (resultMaterial.GetTextureScale(_customShaderPropNames[i].name) != new Vector2(1f, 1f))
                        {
                            if (LOG_LEVEL >= MB2_LogLevel.warn)
                            {
                                Debug.LogWarning("Result material should probably have tiling of 1,1.");
                            }
                        }
                    }
                    else
                    {
                        if (LOG_LEVEL >= MB2_LogLevel.warn)
                        {
                            Debug.LogWarning("Result material shader does not use property " + _customShaderPropNames[i].name + " in the list of custom shader property names");
                        }
                    }
                }
            }
            return(true);
#endif
        }
    void RemapTextures_Default2OtherPipeline(Material m, MBVersion.PipelineType pipelineType)
    {
#if !UNITY_2018_4_OR_NEWER
        Debug.LogError("Must use Unity 2018.4 or greater");
        return;
#else
        if (m.shader == null)
        {
            Debug.LogError("Null shader found in material " + m + ", skipping");
            return;
        }
        string oldShaderName = m.shader.name;
        string newShaderName = MapDefault2OtherShader(m.shader.name, pipelineType);
        if (newShaderName == null)
        {
            Debug.LogError("Could not find mapping for shader " + newShaderName + " in " + AssetDatabase.GetAssetPath(m) + ", skipping");
            return;
        }

        Dictionary <string, string> propMap = new Dictionary <string, string>();
        for (int i = 0; i < propNameMap_Unsupported_Default_URP_HDRP.Length; i++)
        {
            // pipelineType
            // Unsupported = 0
            // Default = 1
            // URP = 2
            // HDRP = 3
            propMap[propNameMap_Unsupported_Default_URP_HDRP[i][(int)MBVersion.PipelineType.Default]] = propNameMap_Unsupported_Default_URP_HDRP[i][(int)pipelineType];
        }

        Dictionary <string, Texture> texMap   = new Dictionary <string, Texture>();
        Dictionary <string, Color>   colorMap = new Dictionary <string, Color>();
        for (int i = 0; i < propNameMap_Unsupported_Default_URP_HDRP.Length; i++)
        {
            string p = propNameMap_Unsupported_Default_URP_HDRP[i][(int)MBVersion.PipelineType.Default];
            if (m.HasProperty(p))
            {
                // So far the only property that we map of type (Color) is the main color, if this changes we might want to make a colorPropertyMap up top
                if (p == "_Color")
                {
                    Color c = m.GetColor(p);
                    if (m.HasProperty(p))
                    {
                        Debug.Assert(propMap.ContainsKey(p), "No mapping for " + p + " mat " + m + " " + m.shader);
                        //Debug.Log("Will Map " + p + " to " + colorMap[p]);
                        colorMap[propMap[p]] = c;
                    }
                }
                else
                {
                    Texture t = m.GetTexture(p);
                    if (t != null)
                    {
                        Debug.Assert(propMap.ContainsKey(p), "No mapping for " + p + " mat " + m + " " + m.shader);
                        //Debug.Log("Will Map " + p + " to " + propMap[p]);
                        texMap[propMap[p]] = t;
                    }
                }
            }
        }

        m.shader = Shader.Find(newShaderName);

        // Can be removed when HDRP adds a nice tree shader
        if (pipelineType == MBVersion.PipelineType.HDRP && oldShaderName == "Nature/Tree Creator Leaves Fast")
        {
            m = HandleHDRPTreeTransparency(m);
        }

        foreach (string p in texMap.Keys)
        {
            // Debug.Log("Mat " + m + " setting prop " + p + " to " + texMap[p]);
            m.SetTexture(p, texMap[p]);
        }
        foreach (string p in colorMap.Keys)
        {
            // Debug.Log("Mat " + m + " setting prop " + p + " to " + colorMap[p]);
            m.SetColor(p, colorMap[p]);
        }
#endif
    }
    void MigrateMaterials()
    {
        HashSet <string> shaderNames = new HashSet <string>();

        string examplesPathRelative = GetRelativeExamplesPath();

        if (examplesPathRelative == null)
        {
            Debug.LogError("Cannot convert example materials as no Mesh Baker Example scenes were found. Renaming example scenes may cause this error.");
            return;
        }

        Debug.Log("Found Mesh Baker Examples at: " + examplesPathRelative);

        MBVersion.PipelineType pipelineType = MBVersion.DetectPipeline();

        Material[] mats;
        {
            string[]        matGIDs = AssetDatabase.FindAssets("t:Material", new string[] { examplesPathRelative });
            List <Material> matList = new List <Material>();
            for (int i = 0; i < matGIDs.Length; i++)
            {
                string path = AssetDatabase.GUIDToAssetPath(matGIDs[i]);
                if (!path.Contains("SceneBasicTextureArrayAssets") && !path.EndsWith(".fbx")) // don't do texture array assets.
                {
                    matList.Add(AssetDatabase.LoadAssetAtPath <Material>(path));
                    string shaderName = matList[matList.Count - 1].shader.name;
                    shaderNames.Add(shaderName);

                    if (MapDefault2OtherShader(shaderName, pipelineType) == null)
                    {
                        Debug.LogError("Could not find mapping for shader " + shaderName + " in mat " + path);
                        return;
                    }
                }
            }
            mats = matList.ToArray();
        }

        string nn = "";

        foreach (string n in shaderNames)
        {
            if (MapDefault2OtherShader(n, pipelineType) == null)
            {
                Debug.LogError("Could not find mapping for shader " + n);
                return;
            }

            nn += "'" + n + "' will map to '" + MapDefault2OtherShader(n, pipelineType) + "',\n";
        }

        Debug.Log(examplesPathRelative + " Found Mats: " + mats.Length + " Shaders Found " + nn);
        for (int i = 0; i < mats.Length; i++)
        {
            Material m = mats[i];
            RemapTextures_Default2OtherPipeline(m, pipelineType);
            EditorUtility.SetDirty(m);
        }

        AssetDatabase.SaveAssets();
    }