private void TextureSettings()
        {
            if (grassObject == null)
            {
                EditorGUILayout.LabelField("No grass object selected. Select a grass object in the scene Hierarchy.");
                return;
            }

            EditorGUILayout.LabelField("Current object: " + grassObject.name);
            EditorGUILayout.Space();

            if (GrassEditorUtility.GetDensityMode(grassMaterial) != DensityMode.Texture)
            {
                EditorGUILayout.LabelField("The grass material is not in texture density mode.", EditorStyles.boldLabel);
                if (GUILayout.Button("Change material to texture density"))
                {
                    GrassEditorUtility.SetDensityMode(grassMaterial, DensityMode.Texture);
                }

                EditorGUILayout.Space();
            }

            if (grassMaterial.GetTexture("_ColorMap") == null || grassMaterial.GetTexture("_Density") == null)
            {
                EditorGUILayout.LabelField("Create new texture", EditorStyles.boldLabel);
                EditorGUILayout.Space();

                textureSize = EditorGUILayout.IntField("Texture Size", textureSize);

                if (grassMaterial.GetTexture("_ColorMap") == null && GUILayout.Button("Create color height texture"))
                {
                    //Select the path and return on cancel
                    string path = EditorUtility.SaveFilePanelInProject("Create color height texture",
                                                                       "newColorHeightTexture", "png", "Choose where to save the new color height texture");

                    if (path == null)
                    {
                        return;
                    }

                    CreateTexture(path, TextureTarget.ColorHeight);
                }

                if (grassMaterial.GetTexture("_Density") == null && GUILayout.Button("Create density texture"))
                {
                    //Select the path and return on cancel
                    string path = EditorUtility.SaveFilePanelInProject("Create density texture", "newDensityTexture",
                                                                       "png", "Choose where to save the new density texture");

                    if (path == null)
                    {
                        return;
                    }

                    CreateTexture(path, TextureTarget.Density);
                }

                EditorGUILayout.Space();
            }
        }
        private void ExtractDetailTextures(Terrain terrain)
        {
            var data = terrain.terrainData;

            var detailCount = data.detailPrototypes.Length;

            for (int i = 0; i < detailCount; i += 4)
            {
                string title = "Extract terrain detail textures " + (i + 1) + "-" + Mathf.Min(i + 4, detailCount);
                string path  = EditorUtility.SaveFilePanelInProject(title, "extractedDensityTexture",
                                                                    "png", "Choose where to save the extracted density texture");

                if (path == null)
                {
                    return;
                }

                var details = new int[4][, ];
                for (int j = 0; j < 4; j++)
                {
                    if (i + j < detailCount)
                    {
                        details[j] = data.GetDetailLayer(0, 0, data.detailWidth, data.detailHeight, i + j);
                    }
                    else
                    {
                        details[j] = new int[data.detailWidth, data.detailHeight];
                    }
                }

                var colors = new Color[data.detailWidth * data.detailHeight];
                for (int x = 0; x < data.detailWidth; x++)
                {
                    for (int y = 0; y < data.detailHeight; y++)
                    {
                        //The shader uses different UV's than Unity terrain.. or I f****d up the conversion to terrain...
                        var index = x * data.detailHeight + y;
                        colors[index] = new Color(details[0][x, y], details[1][x, y], details[2][x, y], details[3][x, y]) / 16;
                    }
                }

                var tex = new Texture2D(data.detailWidth, data.detailHeight, TextureFormat.ARGB32, false, true);
                tex.SetPixels(colors);

                GrassEditorUtility.SaveTextureToFile(path, tex);
            }
        }
        private void CreateTexture(string path, TextureTarget target)
        {
            //Create the new texture and save it at the selected path
            grassPainter.CurrentTexture = new Texture2D(textureSize, textureSize, TextureFormat.ARGB32, false, true);

            Color[] colors    = new Color[textureSize * textureSize];
            var     initColor = target == TextureTarget.Density ? new Color(0, 0, 0, 0) : Color.white;

            for (int i = 0; i < colors.Length; i++)
            {
                colors[i] = initColor;
            }

            grassPainter.CurrentTexture.SetPixels(colors);
            grassPainter.CurrentTexture.Apply();

            var workingTex = grassPainter.CurrentTexture;
            var texture    = GrassEditorUtility.SaveTextureToFile(path, workingTex);

            Destroy(workingTex);
            grassPainter.CurrentTexture = texture;

            switch (target)
            {
            case TextureTarget.ColorHeight:
                grassMaterial.SetTexture("_ColorMap", texture);
                break;

            case TextureTarget.Density:
                grassMaterial.SetTexture("_Density", texture);
                break;

            default:
                throw new ArgumentOutOfRangeException("target", target, null);
            }
        }