static bool ResetAllLoadedMaterialKeywords(string descriptionPrefix, float progressScale, float progressOffset)
        {
            var materials = Resources.FindObjectsOfTypeAll <Material>();

            bool VSCEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);

            bool anyMaterialDirty = false; // Will be true if any material is dirty.

            for (int i = 0, length = materials.Length; i < length; i++)
            {
                EditorUtility.DisplayProgressBar(
                    "Setup materials Keywords...",
                    string.Format("{0}{1} / {2} materials cleaned.", descriptionPrefix, i, length),
                    (i / (float)(length - 1)) * progressScale + progressOffset);

                CoreUtils.CheckOutFile(VSCEnabled, materials[i]);

                if (HDEditorUtils.ResetMaterialKeywords(materials[i]))
                {
                    anyMaterialDirty = true;
                }
            }

            return(anyMaterialDirty);
        }
        static void SynchronizeAllLayeredMaterial()
        {
            var materials = Resources.FindObjectsOfTypeAll <Material>();

            bool VSCEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);

            foreach (var mat in materials)
            {
                if (mat.shader.name == "HDRenderPipeline/LayeredLit" || mat.shader.name == "HDRenderPipeline/LayeredLitTessellation")
                {
                    CoreUtils.CheckOutFile(VSCEnabled, mat);
                    LayeredLitGUI.SynchronizeAllLayers(mat);
                    EditorUtility.SetDirty(mat);
                }
            }
        }
        static void ResetAllMaterialKeywordsInProjectAndScenes()
        {
            var openedScenes = new string[EditorSceneManager.loadedSceneCount];

            for (var i = 0; i < openedScenes.Length; ++i)
            {
                openedScenes[i] = SceneManager.GetSceneAt(i).path;
            }

            bool VSCEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);

            try
            {
                var scenes = AssetDatabase.FindAssets("t:Scene");
                var scale  = 1f / Mathf.Max(1, scenes.Length);
                for (var i = 0; i < scenes.Length; ++i)
                {
                    var scenePath  = AssetDatabase.GUIDToAssetPath(scenes[i]);
                    var sceneAsset = AssetDatabase.LoadAssetAtPath <SceneAsset>(scenePath);
                    CoreUtils.CheckOutFile(VSCEnabled, sceneAsset);
                    EditorSceneManager.OpenScene(scenePath);

                    var sceneName   = Path.GetFileNameWithoutExtension(scenePath);
                    var description = string.Format("{0} {1}/{2} - ", sceneName, i + 1, scenes.Length);

                    if (ResetAllLoadedMaterialKeywords(description, scale, scale * i))
                    {
                        EditorSceneManager.SaveScene(EditorSceneManager.GetActiveScene());
                    }
                }

                ResetAllMaterialAssetsKeywords(scale, scale * (scenes.Length - 1));
            }
            finally
            {
                EditorUtility.ClearProgressBar();

                if (openedScenes.Length > 0)
                {
                    EditorSceneManager.OpenScene(openedScenes[0]);
                    for (var i = 1; i < openedScenes.Length; i++)
                    {
                        EditorSceneManager.OpenScene(openedScenes[i], OpenSceneMode.Additive);
                    }
                }
            }
        }
        static void ResetAllMaterialAssetsKeywords(float progressScale, float progressOffset)
        {
            var matIds = AssetDatabase.FindAssets("t:Material");

            bool VSCEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);

            for (int i = 0, length = matIds.Length; i < length; i++)
            {
                var path = AssetDatabase.GUIDToAssetPath(matIds[i]);
                var mat  = AssetDatabase.LoadAssetAtPath <Material>(path);

                EditorUtility.DisplayProgressBar(
                    "Setup material asset's Keywords...",
                    string.Format("{0} / {1} materials cleaned.", i, length),
                    (i / (float)(length - 1)) * progressScale + progressOffset);

                CoreUtils.CheckOutFile(VSCEnabled, mat);
                var h = Debug.unityLogger.logHandler;
                Debug.unityLogger.logHandler = new UnityContextualLogHandler(mat);
                HDEditorUtils.ResetMaterialKeywords(mat);
                Debug.unityLogger.logHandler = h;
            }
        }
        //[MenuItem("Internal/HDRenderPipeline/Update/Update material for subsurface")]
        static void UpdateMaterialForSubsurface()
        {
            try
            {
                var matIds = AssetDatabase.FindAssets("t:Material");

                for (int i = 0, length = matIds.Length; i < length; i++)
                {
                    var path = AssetDatabase.GUIDToAssetPath(matIds[i]);
                    var mat  = AssetDatabase.LoadAssetAtPath <Material>(path);

                    EditorUtility.DisplayProgressBar(
                        "Setup materials Keywords...",
                        string.Format("{0} / {1} materials subsurface updated.", i, length),
                        i / (float)(length - 1));

                    bool VSCEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);

                    if (mat.shader.name == "HDRenderPipeline/LitTessellation" ||
                        mat.shader.name == "HDRenderPipeline/Lit" ||
                        mat.shader.name == "HDRenderPipeline/LayeredLit" ||
                        mat.shader.name == "HDRenderPipeline/LayeredLitTessellation")
                    {
                        float materialID = mat.GetInt("_MaterialID");
                        if (materialID != 0.0)
                        {
                            continue;
                        }

                        if (mat.HasProperty("_SSSAndTransmissionType"))
                        {
                            CoreUtils.CheckOutFile(VSCEnabled, mat);

                            int materialSSSAndTransmissionID = mat.GetInt("_SSSAndTransmissionType");

                            // Both;, SSS only, Transmission only
                            if (materialSSSAndTransmissionID == 2.0)
                            {
                                mat.SetInt("_MaterialID", 5);
                            }
                            else
                            {
                                if (materialSSSAndTransmissionID == 0.0)
                                {
                                    mat.SetFloat("_TransmissionEnable", 1.0f);
                                }
                                else
                                {
                                    mat.SetFloat("_TransmissionEnable", 0.0f);
                                }
                            }

                            EditorUtility.SetDirty(mat);
                        }
                    }
                }
            }
            finally
            {
                EditorUtility.ClearProgressBar();
            }
        }
        static void UpdateMaterialToNewerVersion(string caption, UpdateMaterial updateMaterial, UpdateMaterialFile updateMaterialFile = null)
        {
            bool          VSCEnabled    = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);
            var           matIds        = AssetDatabase.FindAssets("t:Material");
            List <string> materialFiles = new List <string>(); // Contain the list dirty files

            try
            {
                for (int i = 0, length = matIds.Length; i < length; i++)
                {
                    var path = AssetDatabase.GUIDToAssetPath(matIds[i]);
                    var mat  = AssetDatabase.LoadAssetAtPath <Material>(path);

                    EditorUtility.DisplayProgressBar(
                        "Update material to new version " + caption + "...",
                        string.Format("{0} / {1} materials updated.", i, length),
                        i / (float)(length - 1));

                    if (mat.shader.name == "HDRenderPipeline/LitTessellation" ||
                        mat.shader.name == "HDRenderPipeline/Lit" ||
                        mat.shader.name == "HDRenderPipeline/LayeredLit" ||
                        mat.shader.name == "HDRenderPipeline/LayeredLitTessellation" ||
                        mat.shader.name == "HDRenderPipeline/StackLit" ||
                        mat.shader.name == "HDRenderPipeline/Unlit"
                        )
                    {
                        // Need to be processed in order - All function here should be re-entrant (i.e after upgrade it can be recall)
                        bool dirty = updateMaterial(path, mat);

                        if (dirty)
                        {
                            // Checkout the file and tag it as dirty
                            CoreUtils.CheckOutFile(VSCEnabled, mat);
                            EditorUtility.SetDirty(mat);
                            materialFiles.Add(path);
                        }
                    }
                }
            }
            finally
            {
                EditorUtility.ClearProgressBar();
                // Save all dirty assets
                AssetDatabase.SaveAssets();
            }

            if (updateMaterialFile == null)
            {
                return;
            }

            // Now that all the asset have been modified and save, we can safely update the .mat file and remove removed property
            try
            {
                for (int i = 0, length = materialFiles.Count; i < length; i++)
                {
                    string path = materialFiles[i];

                    EditorUtility.DisplayProgressBar(
                        "Update .mat files...",
                        string.Format("{0} / {1} materials .mat file updated.", i, length),
                        i / (float)(length - 1));

                    // Note: The file is supposed to be checkout by the previous loop
                    updateMaterialFile(path);
                }
            }
            finally
            {
                EditorUtility.ClearProgressBar();
                // No need to save in this case
            }
        }
        //[MenuItem("Internal/HDRenderPipeline/Update/Update Height Maps parametrization")]
        static void UpdateHeightMapParametrization()
        {
            try
            {
                var matIds = AssetDatabase.FindAssets("t:Material");

                for (int i = 0, length = matIds.Length; i < length; i++)
                {
                    var path = AssetDatabase.GUIDToAssetPath(matIds[i]);
                    var mat  = AssetDatabase.LoadAssetAtPath <Material>(path);

                    EditorUtility.DisplayProgressBar(
                        "Updating Materials...",
                        string.Format("{0} / {1} materials updated.", i, length),
                        i / (float)(length - 1));

                    bool VSCEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);

                    if (mat.shader.name == "HDRenderPipeline/LitTessellation" ||
                        mat.shader.name == "HDRenderPipeline/Lit")
                    {
                        // Need only test one of the new properties
                        if (mat.HasProperty("_HeightPoMAmplitude"))
                        {
                            CoreUtils.CheckOutFile(VSCEnabled, mat);

                            float valueMax  = mat.GetFloat("_HeightMax");
                            float valueMin  = mat.GetFloat("_HeightMin");
                            float center    = mat.GetFloat("_HeightCenter");
                            float amplitude = valueMax - valueMin;
                            mat.SetInt("_HeightMapParametrization", 1);
                            mat.SetFloat("_HeightPoMAmplitude", amplitude);
                            mat.SetFloat("_HeightTessAmplitude", amplitude);
                            mat.SetFloat("_HeightOffset", 0.0f);
                            mat.SetFloat("_HeightTessCenter", center);

                            BaseLitGUI.DisplacementMode displaceMode = (BaseLitGUI.DisplacementMode)mat.GetInt("_DisplacementMode");
                            if (displaceMode == BaseLitGUI.DisplacementMode.Pixel)
                            {
                                mat.SetFloat("_HeightCenter", 1.0f); // With PoM this is always 1.0f. We set it here to avoid having to open the UI to update it.
                            }

                            EditorUtility.SetDirty(mat);
                        }
                    }
                    else if (mat.shader.name == "HDRenderPipeline/LayeredLit" ||
                             mat.shader.name == "HDRenderPipeline/LayeredLitTessellation")
                    {
                        int numLayer = (int)mat.GetFloat("_LayerCount");

                        if (mat.HasProperty("_HeightPoMAmplitude0"))
                        {
                            CoreUtils.CheckOutFile(VSCEnabled, mat);

                            for (int x = 0; x < numLayer; ++x)
                            {
                                float valueMax  = mat.GetFloat("_HeightMax" + x);
                                float valueMin  = mat.GetFloat("_HeightMin" + x);
                                float center    = mat.GetFloat("_HeightCenter" + x);
                                float amplitude = valueMax - valueMin;
                                mat.SetInt("_HeightMapParametrization" + x, 1);
                                mat.SetFloat("_HeightPoMAmplitude" + x, amplitude);
                                mat.SetFloat("_HeightTessAmplitude" + x, amplitude);
                                mat.SetFloat("_HeightOffset" + x, 0.0f);
                                mat.SetFloat("_HeightTessCenter" + x, center);

                                BaseLitGUI.DisplacementMode displaceMode = (BaseLitGUI.DisplacementMode)mat.GetInt("_DisplacementMode");
                                if (displaceMode == BaseLitGUI.DisplacementMode.Pixel)
                                {
                                    mat.SetFloat("_HeightCenter" + x, 1.0f); // With PoM this is always 1.0f. We set it here to avoid having to open the UI to update it.
                                }
                            }

                            EditorUtility.SetDirty(mat);
                        }
                    }
                }
            }
            finally
            {
                EditorUtility.ClearProgressBar();
            }
        }