Files

133 lines
4.7 KiB
C#

#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<DissolveGradientRampBaker>("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<Texture2D>(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