/// <summary>
        /// Attempt to recompile MicroSplat shader, ensuring the name matches the landscape name
        /// USAGE:
        /// bool isSuccessful = MicroSplatCompileShader(landscape, customTerrainMaterial, true);
        /// </summary>
        /// <param name="landscape"></param>
        /// <param name="terrainMat"></param>
        /// <param name="showErrors"></param>
        /// <returns></returns>
        public static bool MicroSplatCompileShader(LBLandscape landscape, Material terrainMat, bool showErrors)
        {
            bool   isSuccessful = false;
            string methodName   = "LBEditorIntegration.MicroSplatCompileShader";

            //System.Type MicroSplatShaderGUIType = null;

            try
            {
                if (landscape == null)
                {
                    if (showErrors)
                    {
                        Debug.LogWarning("ERROR: " + methodName + " landscape is null. Please Report");
                    }
                }
                else if (terrainMat == null)
                {
                    if (showErrors)
                    {
                        Debug.LogWarning("ERROR: " + methodName + " terrainMat is null. Please Report");
                    }
                }
                else
                {
                    Shader shader = terrainMat.shader;

                    if (shader == null)
                    {
                        if (showErrors)
                        {
                            Debug.LogWarning(methodName + " - could not find MicroSplat shader. Please Report.");
                        }
                    }
                    else if (!shader.name.Contains("MicroSplat"))
                    {
                        if (showErrors)
                        {
                            Debug.LogWarning(methodName + " - terrain material is not using a MicroSplat shader. [" + shader.name + "]. Please Report");
                        }
                    }
                    else
                    {
                        // Create a new instance of the compiler class
                        MicroSplatShaderGUI.MicroSplatCompiler microSplatCompiler = new MicroSplatShaderGUI.MicroSplatCompiler();
                        string shaderPath     = AssetDatabase.GetAssetPath(shader);
                        string shaderBasePath = shaderPath.Replace(".shader", "_Base.shader");

                        if (microSplatCompiler == null)
                        {
                            if (showErrors)
                            {
                                Debug.LogWarning(methodName + " - could not create MicroSplatCompiler instance. Please Report.");
                            }
                        }
                        else
                        {
                            microSplatCompiler.Init();
                            string[] shaderFeatures = terrainMat.shaderKeywords;

                            // Ensure shader names match the landscape name
                            string baseName = "Hidden/MicroSplat/" + landscape.name + "_Base";

                            string baseShaderOutput    = microSplatCompiler.Compile(shaderFeatures, baseName);
                            string regularShaderOutput = microSplatCompiler.Compile(shaderFeatures, "MicroSplat/" + landscape.name, baseName);

                            //Debug.Log("[DEBUG] regularShaderOutput: " + regularShaderOutput);

                            // Copy the output back to the shader files in the project folder.
                            System.IO.File.WriteAllText(shaderPath, regularShaderOutput);
                            System.IO.File.WriteAllText(shaderBasePath, baseShaderOutput);

                            // Currently we don't use this but we "might" in the future
                            if (shaderFeatures.Contains("_MESHOVERLAYSPLATS"))
                            {
                                string meshOverlayShader = microSplatCompiler.Compile(shaderFeatures, "MicroSplat/" + landscape.name, null, true);
                                System.IO.File.WriteAllText(shaderPath.Replace(".shader", "_MeshOverlay.shader"), meshOverlayShader);
                            }
                            AssetDatabase.Refresh();

                            isSuccessful = !string.IsNullOrEmpty(baseShaderOutput) && !string.IsNullOrEmpty(regularShaderOutput);
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                if (showErrors)
                {
                    Debug.LogWarning("LBIntegration.MegaSplatCompileShader something has gone wrong. Please report. " + ex.Message);
                }
            }

            return(isSuccessful);
        }
        void DrawScatterGUI()
        {
            if (MicroSplatUtilities.DrawRollup("Brush Settings"))
            {
                brushSize    = EditorGUILayout.Slider("Brush Size", brushSize, 0.01f, 30.0f);
                brushFlow    = EditorGUILayout.Slider("Brush Flow", brushFlow, 0.1f, 128.0f);
                brushFalloff = EditorGUILayout.Slider("Brush Falloff", brushFalloff, 0.1f, 3.5f);


                Material tempMat = null;
                for (int i = 0; i < rawTerrains.Count; ++i)
                {
                    Terrain           t   = rawTerrains [i];
                    MicroSplatTerrain mst = t.GetComponent <MicroSplatTerrain> ();
                    if (mst != null)
                    {
                        if (mst.templateMaterial != null && mst.templateMaterial.HasProperty("_ScatterDiffuse"))
                        {
                            Texture2DArray diff = mst.templateMaterial.GetTexture("_ScatterDiffuse") as Texture2DArray;
                            scatterIndex = MicroSplatUtilities.DrawTextureSelector(scatterIndex, diff, false);
                            tempMat      = mst.templateMaterial;
                        }
                        else
                        {
                            scatterIndex = EditorGUILayout.IntField("Scatter Index", scatterIndex);
                        }
                    }
                    else
                    {
                        scatterIndex = EditorGUILayout.IntField("Scatter Index", scatterIndex);
                    }
                }


                //EditorGUILayout.MinMaxSlider (CSlopeRange, ref slopeRange.x, ref slopeRange.y, 0.0f, 1.0f);

                paintValue = EditorGUILayout.Slider("Target Opacity", paintValue, 0.0f, 1.0f);



#if __MICROSPLAT_SCATTER__
                if (tempMat != null)
                {
                    scatterLayer = (ScatterLayer)EditorGUILayout.EnumPopup(CScatterLayer, scatterLayer);
                    EditorGUILayout.Separator();

                    using (new GUILayout.VerticalScope(GUI.skin.box))
                    {
                        EditorGUI.BeginChangeCheck();
                        EditorGUILayout.LabelField("Per Texture Properties");
                        bool changed = MicroSplatScatter.DrawPerTexExternal(tempMat, scatterIndex);
                        EditorGUILayout.Separator();
                        // sync compile changes
                        if (changed)
                        {
                            MicroSplatShaderGUI.MicroSplatCompiler comp = new MicroSplatShaderGUI.MicroSplatCompiler();
                            comp.Init();
                            comp.Compile(tempMat);
                        }
                        // sync property changes
                        if (EditorGUI.EndChangeCheck())
                        {
                            MicroSplatObject.SyncAll();
                        }
                    }
                }
#endif
                GUILayout.Box("", new GUILayoutOption [] { GUILayout.ExpandWidth(true), GUILayout.Height(1) });
                EditorGUILayout.Separator();
            }
            DrawFillGUI();
        }