public class GradientMapper_RT : MonoBehaviour
[Header("Gradient map parameters")]
public string mapperName;
public Vector2Int gradientMapDimensions = new Vector2Int(128, 32);
[GradientUsage(true)] public Gradient gradient;
[Header("Material parameters")]
public string texture_name;
public Texture2D preview_texture;
_propId = Shader.PropertyToID(string.IsNullOrEmpty(texture_name) ? "_MainTex" : texture_name);
// 1) Build/refresh the preview texture (runtime too!)
BuildPreviewTexture(); // <- was only in OnValidate before
// 2) Make sure the RT actually exists on the GPU
// 3) Blit the preview into the RT
Graphics.Blit(preview_texture, rt);
// 4) Push RT to the material
// Keep editor preview responsive
// If you want the material to show the RT in edit mode, you can also call PushToMaterial() here.
[ContextMenu("Rebuild Gradient Texture")]
void RebuildGradientTexture()
_propId = Shader.PropertyToID(string.IsNullOrEmpty(texture_name) ? "_MainTex" : texture_name);
Graphics.Blit(preview_texture, rt);
Debug.LogError("[GradientMapper_RT] Assign a RenderTexture.");
if (rt.format == RenderTextureFormat.Depth)
Debug.LogError("[GradientMapper_RT] Target RT is depth-only; use a color format.");
if (!rt.IsCreated()) rt.Create();
void BuildPreviewTexture()
// Always build the source texture; don't bail just because texture_name is empty.
int w = Mathf.Max(1, gradientMapDimensions.x);
int h = Mathf.Max(1, gradientMapDimensions.y);
// Prefer RGBA32 unless you truly need HDR
if (preview_texture == null || preview_texture.width != w || preview_texture.height != h)
if (preview_texture != null) DestroyImmediate(preview_texture);
preview_texture = new Texture2D(w, h, TextureFormat.RGBA32, false, true) // linear
name = (mat ? $"{mat.name}_Gradient_PREVIEW" : "Gradient_PREVIEW"),
wrapMode = TextureWrapMode.Clamp,
filterMode = FilterMode.Bilinear,
var pixels = new Color[w * h];
// Optional: ensure linear evaluation
gradient.colorSpace = ColorSpace.Linear;
gradient.mode = GradientMode.PerceptualBlend;
for (int x = 0; x < w; x++)
var c = gradient.Evaluate((float)x / (w - 1));
for (int y = 0; y < h; y++) pixels[y * w + x] = c;
preview_texture.SetPixels(pixels);
// If you want a live **editor** preview of the gradient (Texture2D) on the material slot:
if (mat && !string.IsNullOrEmpty(texture_name) && mat.HasProperty(texture_name))
// This is just for edit-time preview; Start()/Rebuild will overwrite with the RT.
mat.SetTexture(texture_name, preview_texture);
EditorUtility.SetDirty(mat);
if (mat.HasProperty(_propId)) mat.SetTexture(_propId, rt);
EditorUtility.SetDirty(mat);
AssetDatabase.SaveAssets();