public static Texture2D RenderNormalMap(Material targetMaterial, int waveStyle, bool useCompression = false, Texture2D customNormalTex = null)
        {
            //If a custom texture is assigned, return that
            if (customNormalTex)
            {
                return(customNormalTex);
            }

            StylizedWaterResources r = StylizedWaterResources.Instance;

            //Set compression setting
            TexturePacker.useCompression = useCompression;

            Texture2D heightmap = r.waveStyles[waveStyle];

            Texture2D normalTexture = new Texture2D(NORMAL_RESOLUTION, NORMAL_RESOLUTION, TextureFormat.ARGB32, true)
            {
                name       = "_normal",
                filterMode = FilterMode.Trilinear,
                wrapMode   = TextureWrapMode.Repeat
            };

            RenderTexture rt = new RenderTexture(normalTexture.width, normalTexture.height, 0);

            RenderTexture.active = rt;

            //Constants
            NormalRenderMat.SetFloat("_Offset", NORMAL_OFFSET);
            NormalRenderMat.SetFloat("_Strength", NORMAL_STRENGTH);

            //Convert heightmap to normal on GPU
            Graphics.Blit(heightmap, rt, NormalRenderMat);

            //Copy result into texture
            normalTexture.ReadPixels(new Rect(0, 0, normalTexture.width, normalTexture.height), 0, 0);
            normalTexture.Apply();

            //Cleanup
            RenderTexture.active = null;

            normalTexture = SaveAndGetTexture(targetMaterial, normalTexture);

            return(normalTexture);
        }
        //TODO (Polish): Use a struct
        public static Texture2D RenderShaderMap(Material targetMaterial, int intersectionStyle, int waveStyle, int heightmapStyle, bool useCompression = false, Texture2D customIntersectionTex = null, Texture2D customHeightmapTex = null)
        {
            StylizedWaterResources r = StylizedWaterResources.Instance;

            //Set compression setting
            TexturePacker.useCompression = useCompression;

            //Intersection
            Texture2D intersectionTex;

            if (customIntersectionTex)
            {
                intersectionTex = customIntersectionTex;
            }
            else
            {
                intersectionTex = r.intersectionStyles[intersectionStyle];
            }

            //Foam
            Texture2D foamTex;

            //When a custom normal map is used, force the usage of the intersection texture for foam
            if (waveStyle == r.waveStyles.Length)
            {
                foamTex = Texture2D.blackTexture;
            }
            else
            {
                foamTex = r.waveStyles[waveStyle];
            }

            //Heightmap
            Texture2D heightmapTex;

            if (customHeightmapTex)
            {
                heightmapTex = customHeightmapTex;
            }
            else
            {
                heightmapTex = r.heightmapStyles[heightmapStyle];
            }

            Texture2D shadermap = new Texture2D(SHADERMAP_RESOLUTION, SHADERMAP_RESOLUTION, TextureFormat.RGB24, true)
            {
                name       = "_shadermap", //Prefix and suffix to be appended upon saving
                anisoLevel = 2,
                filterMode = FilterMode.Bilinear,
                wrapMode   = TextureWrapMode.Repeat
            };

            RenderTexture rt = new RenderTexture(shadermap.width, shadermap.width, 0);

            RenderTexture.active = rt;

            //Constants
            ShaderMapRenderMat.SetTexture("_RedInput", foamTex);
            ShaderMapRenderMat.SetTexture("_GreenInput", heightmapTex);
            ShaderMapRenderMat.SetTexture("_BlueInput", intersectionTex);
            //ShaderMapRenderMat.SetTexture("_AlphaInput", null);

            //Pack textures on GPU
            Graphics.Blit(null, rt, ShaderMapRenderMat);

            //Copy result into texture
            shadermap.ReadPixels(new Rect(0, 0, shadermap.width, shadermap.height), 0, 0);
            shadermap.Apply();

            //Cleanup
            RenderTexture.active = null;

            shadermap = SaveAndGetTexture(targetMaterial, shadermap);

            return(shadermap);
        }