private void BlendPass2D(Texture2D tex, INoisCreater creater, Color mask, int width, int height, Vector3 offset, int octave, float a, float f, bool isSeamless)
 {
     if (creater != null)
     {
         Texture2D targetTex = null;
         if (!isSeamless)
         {
             targetTex = NoiseGenerate.ShowNoise2D(width, height, offset, octave, f, a, creater);
         }
         else
         {
             targetTex = NoiseGenerate.ShowNoise2DSeamless(width, height, offset, octave, f, a, creater);
         }
         BlendPassColorTexture2D(tex, targetTex, mask);
     }
 }
 private void BlendPass3D(Texture3D tex, INoisCreater creater, Color mask, int width, int height, int depth, Vector3 offset, int octave, float a, float f, bool isSeamless)
 {
     if (creater != null)
     {
         Texture3D targetTex = null;
         if (!isSeamless)
         {
             targetTex = NoiseGenerate.ShowNoise3D(width, height, depth, offset, octave, f, a, creater);
             //BlendPassColorTexture3D(tex, targetTex, mask);
         }
         else
         {
             targetTex = NoiseGenerate.ShowNoise3DSeamless(width, height, depth, offset, octave, f, a, creater);
             //NoiseGenerate.ShowNoise3DSeamlessAsync(width, height, depth, offset, octave, f, a, creater, (t) => {
             //    BlendPassColorTexture3D(tex, t, mask);
             //    seamlessAsyncTex3D = true;
             //});
         }
         BlendPassColorTexture3D(tex, targetTex, mask);
     }
 }
        private void OnGUI()
        {
            scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
            id        = EditorGUILayout.TextField("纹理ID", id);

            width  = EditorGUILayout.IntField("宽", width);
            height = EditorGUILayout.IntField("高", height);
            depth  = EditorGUILayout.IntField("厚", depth);

            openR = EditorGUILayout.Toggle("开启R通道", openR);
            openG = EditorGUILayout.Toggle("开启G通道", openG);
            openB = EditorGUILayout.Toggle("开启B通道", openB);
            openA = EditorGUILayout.Toggle("开启A通道", openA);

            if (openR)
            {
                EditorGUILayout.Space(10);
                EditorGUILayout.LabelField("-------------------------------------------------");
                rType       = (NoiseType)EditorGUILayout.EnumPopup("R通道噪声类型:", rType);
                rIsSeamless = EditorGUILayout.Toggle("无缝图", rIsSeamless);
                rOctave     = EditorGUILayout.IntSlider("R通道 octave:", rOctave, 1, 10);
                rA          = EditorGUILayout.Slider("R通道 a:", rA, 0, 5);
                rF          = EditorGUILayout.Slider("R通道 f:", rF, 0, 3);
                rOffsets    = EditorGUILayout.Vector3Field("R通道 偏移:", rOffsets);
                EditorGUILayout.LabelField("-------------------------------------------------");
            }
            if (openG)
            {
                gType       = (NoiseType)EditorGUILayout.EnumPopup("G通道噪声类型:", gType);
                gIsSeamless = EditorGUILayout.Toggle("无缝图", gIsSeamless);
                gOctave     = EditorGUILayout.IntSlider("G通道 octave:", gOctave, 1, 10);
                gA          = EditorGUILayout.Slider("G通道 a:", gA, 0, 5);
                gF          = EditorGUILayout.Slider("G通道 f:", gF, 0, 3);
                gOffsets    = EditorGUILayout.Vector3Field("G通道 偏移:", gOffsets);
                EditorGUILayout.LabelField("-------------------------------------------------");
            }
            if (openB)
            {
                bType       = (NoiseType)EditorGUILayout.EnumPopup("B通道噪声类型:", bType);
                bIsSeamless = EditorGUILayout.Toggle("无缝图", bIsSeamless);
                bOctave     = EditorGUILayout.IntSlider("B通道 octave:", bOctave, 1, 10);
                bA          = EditorGUILayout.Slider("B通道 a:", bA, 0, 5);
                bF          = EditorGUILayout.Slider("B通道 f:", bF, 0, 3);
                bOffsets    = EditorGUILayout.Vector3Field("B通道 偏移:", bOffsets);
                EditorGUILayout.LabelField("-------------------------------------------------");
            }
            if (openA)
            {
                aType       = (NoiseType)EditorGUILayout.EnumPopup("A通道噪声类型:", aType);
                aIsSeamless = EditorGUILayout.Toggle("无缝图", aIsSeamless);
                aOctave     = EditorGUILayout.IntSlider("A通道 octave:", aOctave, 1, 10);
                aA          = EditorGUILayout.Slider("A通道 a:", aA, 0, 5);
                aF          = EditorGUILayout.Slider("A通道 f:", aF, 0, 3);
                aOffsets    = EditorGUILayout.Vector3Field("A通道 偏移:", aOffsets);
                EditorGUILayout.LabelField("-------------------------------------------------");
            }

            rCreater = createrDic[rType];
            gCreater = createrDic[gType];
            bCreater = createrDic[bType];
            aCreater = createrDic[aType];


            if (GUILayout.Button("生成 2D Blend Noise 纹理"))
            {
                tex2D     = ShowBlendNoiseTex2D();
                tex2dPath = "Assets/Temp/" + id + "_BlendTex2D.asset";
                AssetDatabase.CreateAsset(tex2D, tex2dPath);
                AssetDatabase.SaveAssets();
            }

            if (GUILayout.Button("生成 3D Blend Noise 纹理"))
            {
                tex3D     = ShowBlendNoise3D();
                tex3dPath = "Assets/Temp/" + id + "_BlendTex3D.asset";
                AssetDatabase.CreateAsset(tex3D, tex3dPath);
                AssetDatabase.SaveAssets();
            }

            //if(seamlessAsyncTex3D)
            //{
            //    string path = "Assets/Temp/" + id + "_Async_BlendTex3D.asset";
            //    AssetDatabase.CreateAsset(tex3D, path);
            //    AssetDatabase.SaveAssets();
            //    seamlessAsyncTex3D = false;
            //}

            EditorGUILayout.LabelField("2D 纹理路径:" + tex2dPath);
            EditorGUILayout.ObjectField("2D 纹理预览:", tex2D, typeof(Texture), false);

            EditorGUILayout.LabelField("3D 纹理路径:" + tex3dPath);
            EditorGUILayout.ObjectField("3D 纹理预览:", tex3D, typeof(Texture), false);

            EditorGUILayout.EndScrollView();
        }
        public static Texture2D ShowNoise2DSeamless(int width, int height, Vector3 offset, int octave, float f, float a, INoisCreater creater)
        {
            //Texture3D uperTex = ShowNoise3D(width, width, height, offset, octave, f, a, creater);

            Texture2D tex = new Texture2D(width, height);

            float theta   = 2 * Mathf.PI / (float)width;
            float width3D = width / (2 * Mathf.PI);
            int   halfW   = (int)width3D / 2;

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    float nx = halfW + Mathf.Sin(x * theta) * width3D;
                    float ny = halfW + Mathf.Cos(x * theta) * width3D;
                    int   fx = (int)nx;
                    int   fy = (int)ny;

                    float frequency = 1;
                    float ambitient = 1;


                    for (int i = 0; i < octave; i++)
                    {
                        frequency *= f;
                        ambitient *= a;
                    }


                    float noise = ambitient * creater.Get3D((fx + offset.x) * frequency, (fy + offset.y) * frequency, (y + offset.z) * frequency);
                    tex.SetPixel(x, y, new Color(0.5f * noise, 0.5f * noise, 0.5f * noise, 0.5f * noise));
                }
            }

            //tex.wrapMode = TextureWrapMode.Repeat;
            tex.Apply();
            return(tex);
        }
        public static Texture3D ShowNoise3D(int width, int height, int depth, Vector3 offset, int octave, float f, float a, INoisCreater creater)
        {
            Texture3D tex = new Texture3D(width, height, depth, TextureFormat.RGBA32, false);

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int z = 0; z < depth; z++)
                    {
                        float frequency = 1;
                        float ambitient = 1;


                        for (int i = 0; i < octave; i++)
                        {
                            frequency *= f;
                            ambitient *= a;
                        }

                        float noise = creater.Get3D((x + offset.x) * frequency, (y + offset.y) * frequency, (z + offset.z) * frequency) * ambitient;
                        tex.SetPixel(x, y, z, new Color(0.5f * noise, 0.5f * noise, 0.5f * noise, 0.5f * noise));
                    }
                }
            }
            tex.Apply();
            return(tex);
        }
        //public async static Task<Texture3D> ShowNoise3DSeamlessAsync(int width, int height, int depth, Vector3 offset, int octave, float f, float a, INoisCreater creater)
        //{
        //    Texture3D[] tex4D = new Texture3D[depth];

        //    await Task.Run(() =>
        //    {
        //        for (int i = 0; i < depth; i++)
        //        {
        //            tex4D[i] = ShowNoise3D(width, height, depth, offset, octave, f, a, creater);
        //        }
        //    });

        //    Texture3D tex = new Texture3D(width, height, depth, TextureFormat.RGBA32, false);

        //    float halfW = width / 2f;
        //    float theta = 2 * Mathf.PI / (float)width;

        //    await Task.Run(() =>
        //    {
        //        for (int x = 0; x < width; x++)
        //        {
        //            for (int y = 0; y < height; y++)
        //            {
        //                for (int z = 0; z < depth; z++)
        //                {
        //                    float nx = halfW + Mathf.Cos(x * theta) * halfW;
        //                    float ny = halfW + Mathf.Sin(y * theta) * halfW;
        //                    int fx = (int)nx;
        //                    int fy = (int)ny;
        //                    Color col = tex4D[z].GetPixel(fx, fy, y);
        //                    tex.SetPixel(x, y, z, col);
        //                }
        //            }
        //        }
        //    });

        //    tex.Apply();
        //    return tex;
        //}
        #endregion

        //private static IEnumerator ShowNoise3DSeamlessCor(int width, int height, int depth, Vector3 offset, int octave, float f, float a, INoisCreater creater, Action<Texture3D> callback)
        //{
        //    Texture3D tex = null;
        //    yield return tex = ShowNoise3DSeamless(width, height, depth, offset, octave, f, a, creater);
        //    if (tex != null) callback.Invoke(tex);
        //    else Debug.LogError("3D 无缝纹理 生成失败!");
        //}

        public static Texture3D ShowNoise3DSeamless(int width, int height, int depth, Vector3 offset, int octave, float f, float a, INoisCreater creater)
        {
            //Texture3D tex4D = null;
            Vector3 offset4D = Vector3.zero;
            int     width4D  = (int)(width / (2 * Mathf.PI) + 2);
            //for(int i = 0; i < depth; i++)
            //{
            //    offset4D += Vector3.one * depth;
            //    tex4D = ShowNoise3D(width4D, width4D, height, offset4D, octave, f, a, creater);
            //    AssetDatabase.CreateAsset(tex4D, "Assets/Temp/Temp/" + i + ".asset");
            //}
            //AssetDatabase.SaveAssets();

            Texture3D tex = new Texture3D(width, height, depth, TextureFormat.RGBA32, false);

            float halfW = width4D / 2f;
            float theta = 2 * Mathf.PI / (float)width;

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int z = 0; z < depth; z++)
                    {
                        float nx = halfW + Mathf.Cos(x * theta) * width4D;
                        float ny = halfW + Mathf.Sin(y * theta) * width4D;
                        int   fx = (int)nx;
                        int   fy = (int)ny;

                        float frequency = 1;
                        float ambitient = 1;


                        for (int i = 0; i < octave; i++)
                        {
                            frequency *= f;
                            ambitient *= a;
                        }

                        float noise1 = creater.Get3D((fx + offset.x) * frequency, (fy + offset.y) * frequency, (y + offset.z) * frequency);
                        float noise2 = creater.Get3D((fx + offset.x) * frequency, (fy + offset.y) * frequency, (z + offset.z) * frequency);
                        float noise  = ambitient * (noise1 + noise2) / 2f;
                        tex.SetPixel(x, y, z, new Color(0.5f * noise, 0.5f * noise, 0.5f * noise, 0.5f * noise));
                        //AssetDatabase.DeleteAsset("Assets/Resources/Temp/" + z + ".asset");
                    }
                }
            }

            tex.Apply();

            //for (int z = 0; z < depth; z++)
            //{
            //    AssetDatabase.DeleteAsset("Assets/Temp/Temp/" + z + ".asset");
            //}

            return(tex);
        }
        public static Texture2D ShowNoise2D(int width, int height, Vector3 offset, int octave, float f, float a, INoisCreater creater)
        {
            Texture2D tex = new Texture2D(width, height);

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    float frequency = 1;
                    float ambitient = 1;

                    for (int i = 0; i < octave; i++)
                    {
                        frequency *= f;
                        ambitient *= a;
                    }

                    float noise = creater.Get2D((x + offset.x) * frequency, (y + offset.y) * frequency) * ambitient;
                    tex.SetPixel(x, y, new Color(0.5f * noise, 0.5f * noise, 0.5f * noise, 0.5f * noise));
                }
            }

            //tex.wrapMode = TextureWrapMode.Repeat;
            tex.Apply();
            return(tex);
        }