#if UNITY_EDITOR using System.IO; using UnityEditor; using UnityEngine; // Bakes a Unity Gradient into a 1D ramp texture (width x 1) that can be assigned // to the Dissolve URP material's "Gradient Ramp" (_GradientTex) slot. The dissolve // edge value samples this ramp along its U axis, so the left of the gradient maps to // the inner edge and the right maps to the outer edge of the dissolve. public class DissolveGradientRampBaker : EditorWindow { [SerializeField] private Gradient gradient = CreateDefaultGradient(); [SerializeField] private int width = 256; [SerializeField] private bool hdr = true; [SerializeField] private string outputFolder = "Assets/Rainbow-Cats-Unity-Dissolve-HDR-Shaders-main/Materials"; [SerializeField] private string fileName = "DissolveGradientRamp"; private SerializedObject serialized; [MenuItem("Bansonic/Rendering/Dissolve Gradient Ramp Baker")] public static void Open() { GetWindow("Gradient Ramp Baker").minSize = new Vector2(360f, 260f); } private void OnEnable() { serialized = new SerializedObject(this); } private void OnGUI() { serialized.Update(); EditorGUILayout.LabelField("Bake a Gradient into a ramp texture", EditorStyles.boldLabel); EditorGUILayout.HelpBox( "Assign the baked texture to the material's 'Gradient Ramp' slot. " + "The dissolve edge samples it left-to-right.", MessageType.Info); EditorGUILayout.PropertyField(serialized.FindProperty(nameof(gradient))); EditorGUILayout.PropertyField(serialized.FindProperty(nameof(width))); EditorGUILayout.PropertyField(serialized.FindProperty(nameof(hdr)), new GUIContent("HDR (float texture)")); EditorGUILayout.PropertyField(serialized.FindProperty(nameof(outputFolder))); EditorGUILayout.PropertyField(serialized.FindProperty(nameof(fileName))); serialized.ApplyModifiedProperties(); EditorGUILayout.Space(); if (GUILayout.Button("Bake Ramp Texture", GUILayout.Height(32f))) Bake(); } private void Bake() { int w = Mathf.Clamp(width, 2, 4096); var format = hdr ? TextureFormat.RGBAFloat : TextureFormat.RGBA32; var tex = new Texture2D(w, 1, format, false, true) { wrapMode = TextureWrapMode.Clamp, filterMode = FilterMode.Bilinear }; var pixels = new Color[w]; for (int x = 0; x < w; x++) { float t = w == 1 ? 0f : (float)x / (w - 1); pixels[x] = gradient.Evaluate(t); } tex.SetPixels(pixels); tex.Apply(false, false); if (!AssetDatabase.IsValidFolder(outputFolder)) { Debug.LogError($"[DissolveGradientRampBaker] Output folder does not exist: {outputFolder}"); Object.DestroyImmediate(tex); return; } string extension = hdr ? "exr" : "png"; byte[] bytes = hdr ? tex.EncodeToEXR(Texture2D.EXRFlags.OutputAsFloat) : tex.EncodeToPNG(); string assetPath = $"{outputFolder}/{fileName}.{extension}"; assetPath = AssetDatabase.GenerateUniqueAssetPath(assetPath); File.WriteAllBytes(assetPath, bytes); Object.DestroyImmediate(tex); AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); ConfigureImporter(assetPath); var imported = AssetDatabase.LoadAssetAtPath(assetPath); EditorGUIUtility.PingObject(imported); Selection.activeObject = imported; Debug.Log($"[DissolveGradientRampBaker] Baked ramp to {assetPath}"); } private void ConfigureImporter(string assetPath) { if (AssetImporter.GetAtPath(assetPath) is not TextureImporter importer) return; importer.textureType = TextureImporterType.Default; importer.wrapMode = TextureWrapMode.Clamp; importer.filterMode = FilterMode.Bilinear; importer.mipmapEnabled = false; importer.sRGBTexture = !hdr; importer.alphaSource = TextureImporterAlphaSource.FromInput; importer.alphaIsTransparency = false; importer.SaveAndReimport(); } private static Gradient CreateDefaultGradient() { var g = new Gradient(); g.SetKeys( new[] { new GradientColorKey(new Color(1f, 0.35f, 0.1f), 0f), new GradientColorKey(new Color(1f, 0.9f, 0.3f), 0.5f), new GradientColorKey(new Color(0.3f, 0.7f, 1f), 1f) }, new[] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(1f, 1f) }); return g; } } #endif