#if UNITY_EDITOR using UnityEngine; using UnityEditor; using System.IO; public class CreatePerlinFogAsset : EditorWindow { public int size = 64; public float scale = 0.05f; public int seed = 1337; public string assetPath = "Assets/FogNoise.asset"; [MenuItem("Tools/Generate Fog Texture3D")] static void OpenWindow() => GetWindow("Generate Fog 3D"); void OnGUI() { GUILayout.Label("Generate 3D Perlin Fog Texture", EditorStyles.boldLabel); size = EditorGUILayout.IntField("Size", size); scale = EditorGUILayout.FloatField("Scale", scale); seed = EditorGUILayout.IntField("Seed", seed); assetPath = EditorGUILayout.TextField("Asset Path", assetPath); if (GUILayout.Button("Generate and Save")) { var tex = CreatePerlin3D(size, scale, seed); tex.wrapMode = TextureWrapMode.Repeat; tex.filterMode = FilterMode.Trilinear; tex.Apply(); // ensure directory exists var dir = Path.GetDirectoryName(assetPath); if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir)) Directory.CreateDirectory(dir); AssetDatabase.CreateAsset(tex, assetPath); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); EditorUtility.FocusProjectWindow(); Selection.activeObject = AssetDatabase.LoadAssetAtPath(assetPath); Debug.Log($"Texture3D saved to {assetPath}"); } } static Texture3D CreatePerlin3D(int size, float scale, int seed) { var tex = new Texture3D(size, size, size, TextureFormat.RGBA32, false); var colors = new Color[size * size * size]; System.Random rng = new System.Random(seed); float offsetX = (float)rng.NextDouble() * 10000f; float offsetY = (float)rng.NextDouble() * 10000f; float offsetZ = (float)rng.NextDouble() * 10000f; int idx = 0; for (int z = 0; z < size; z++) { float wz = (z + offsetZ) * scale; for (int y = 0; y < size; y++) { float wy = (y + offsetY) * scale; for (int x = 0; x < size; x++) { float wx = (x + offsetX) * scale; float n = FractalPerlin(wx, wy, wz, 3); colors[idx++] = new Color(n, n, n, n); } } } tex.SetPixels(colors); tex.Apply(); return tex; } static float FractalPerlin(float x, float y, float z, int octaves) { float amp = 1f; float freq = 1f; float sum = 0f; float max = 0f; for (int i = 0; i < octaves; i++) { sum += amp * Mathf.PerlinNoise(x * freq, y * freq); sum += amp * Mathf.PerlinNoise(y * freq, z * freq); sum += amp * Mathf.PerlinNoise(z * freq, x * freq); max += 3f * amp; amp *= 0.5f; freq *= 2f; } return Mathf.Clamp01(sum / max); } } #endif