[Add] All in one shader
This commit is contained in:
@@ -0,0 +1,332 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AllIn13DShader
|
||||
{
|
||||
public class GradientEditorDrawer
|
||||
{
|
||||
private const float OFFSET = 5f;
|
||||
|
||||
private Gradient gradient;
|
||||
private Rect lastRect;
|
||||
private Texture2D previewTex;
|
||||
private GradientCreatorTool gradientCreatorTool;
|
||||
|
||||
private bool createGradientToggle;
|
||||
private bool textureSaved;
|
||||
private bool usingPreviewTex;
|
||||
private bool isModifyingExistingTexture;
|
||||
|
||||
private Texture lastSavedTexture;
|
||||
private Gradient lastGradient;
|
||||
|
||||
private GradientTexture gradientTextureAsset;
|
||||
|
||||
private void RefreshReferences(Texture lastTexture)
|
||||
{
|
||||
if (gradient == null)
|
||||
{
|
||||
gradient = new Gradient();
|
||||
}
|
||||
|
||||
if (previewTex == null)
|
||||
{
|
||||
previewTex = new Texture2D(128, 128);
|
||||
}
|
||||
|
||||
if (gradientCreatorTool == null)
|
||||
{
|
||||
gradientCreatorTool = new GradientCreatorTool();
|
||||
}
|
||||
|
||||
if (lastSavedTexture == null)
|
||||
{
|
||||
lastSavedTexture = lastTexture;
|
||||
}
|
||||
|
||||
if (lastGradient == null)
|
||||
{
|
||||
lastGradient = new Gradient();
|
||||
}
|
||||
}
|
||||
|
||||
private Texture RefreshGradientState(Texture texValue)
|
||||
{
|
||||
Texture res = texValue;
|
||||
|
||||
if (createGradientToggle)
|
||||
{
|
||||
lastSavedTexture = texValue;
|
||||
|
||||
isModifyingExistingTexture = EditorUtils.IsProjectAsset(lastSavedTexture);
|
||||
|
||||
this.gradientTextureAsset = GradientCreatorTool.FindGradientTexureByTex(texValue);
|
||||
if (this.gradientTextureAsset != null)
|
||||
{
|
||||
GradientCreatorTool.CopyGradient(gradientTextureAsset.gradient, gradient);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (texValue != null)
|
||||
{
|
||||
gradient = CreateGradientFromTexture(texValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
gradient = new Gradient();
|
||||
}
|
||||
}
|
||||
|
||||
previewTex = gradientCreatorTool.CreateGradientTexture(gradient);
|
||||
res = previewTex;
|
||||
}
|
||||
else
|
||||
{
|
||||
GradientCreatorTool.CopyGradient(gradient, lastGradient);
|
||||
previewTex = null;
|
||||
res = lastSavedTexture;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private Gradient CreateGradientFromTexture(Texture texSource)
|
||||
{
|
||||
int width = texSource.width;
|
||||
int height = texSource.height;
|
||||
|
||||
RenderTexture renderTex = RenderTexture.GetTemporary(
|
||||
width,
|
||||
height,
|
||||
0,
|
||||
RenderTextureFormat.Default,
|
||||
RenderTextureReadWrite.Linear);
|
||||
|
||||
Graphics.Blit(texSource, renderTex);
|
||||
RenderTexture previous = RenderTexture.active;
|
||||
RenderTexture.active = renderTex;
|
||||
Texture2D readableText = new Texture2D(texSource.width, texSource.height);
|
||||
readableText.filterMode = texSource.filterMode;
|
||||
readableText.wrapMode = texSource.wrapMode;
|
||||
readableText.ReadPixels(new Rect(0, 0, renderTex.width, renderTex.height), 0, 0);
|
||||
readableText.Apply();
|
||||
RenderTexture.active = previous;
|
||||
RenderTexture.ReleaseTemporary(renderTex);
|
||||
|
||||
|
||||
Gradient res = new Gradient();
|
||||
List<GradientColorKey> gradientColorKeys = new List<GradientColorKey>();
|
||||
|
||||
int numSamples = 5;
|
||||
float step = (((float)width) / numSamples) / width;
|
||||
|
||||
Vector2 sampleUV = Vector2.zero;
|
||||
sampleUV.y = renderTex.height * 0.5f;
|
||||
for (int i = 0; i < numSamples; i++)
|
||||
{
|
||||
Color col = readableText.GetPixelBilinear(sampleUV.x, sampleUV.y);
|
||||
gradientColorKeys.Add(new GradientColorKey(col, sampleUV.x));
|
||||
|
||||
sampleUV.x += step;
|
||||
}
|
||||
|
||||
Color lastCol = readableText.GetPixelBilinear(sampleUV.x, sampleUV.y);
|
||||
gradientColorKeys.Add(new GradientColorKey(lastCol, sampleUV.x));
|
||||
|
||||
res.colorKeys = gradientColorKeys.ToArray();
|
||||
res.mode = GradientMode.Blend;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public Texture Draw(Rect position, Texture gradientTexture)
|
||||
{
|
||||
RefreshReferences(gradientTexture);
|
||||
|
||||
lastRect = position;
|
||||
|
||||
Texture texValue = gradientTexture;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
if (createGradientToggle && texValue == null)
|
||||
{
|
||||
texValue = lastSavedTexture;
|
||||
createGradientToggle = false;
|
||||
}
|
||||
|
||||
texValue = DrawTextureField(texValue, 60f, "Color ramp texture");
|
||||
bool changes = EditorGUI.EndChangeCheck();
|
||||
if (changes)
|
||||
{
|
||||
createGradientToggle = false;
|
||||
lastSavedTexture = texValue;
|
||||
}
|
||||
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
DrawCreateGradientToggle(15f, "Create Gradient");
|
||||
bool createGradientToggleChanged = EditorGUI.EndChangeCheck();
|
||||
if (createGradientToggleChanged)
|
||||
{
|
||||
texValue = RefreshGradientState(texValue);
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
if (createGradientToggle)
|
||||
{
|
||||
texValue = DrawGradientField(40f, "Gradient", texValue);
|
||||
}
|
||||
|
||||
EditorGUI.showMixedValue = false;
|
||||
bool gradientFieldChanged = EditorGUI.EndChangeCheck();
|
||||
if (gradientFieldChanged && !textureSaved)
|
||||
{
|
||||
previewTex = gradientCreatorTool.CreateGradientTexture(TextureSizes._256, FilterMode.Bilinear, gradient);
|
||||
texValue = previewTex;
|
||||
|
||||
usingPreviewTex = true;
|
||||
}
|
||||
|
||||
textureSaved = false;
|
||||
|
||||
return texValue;
|
||||
}
|
||||
|
||||
private Texture DrawTextureField(Texture tex, float height, string label)
|
||||
{
|
||||
Rect rect = new Rect(lastRect);
|
||||
rect.height = height;
|
||||
|
||||
GUIStyle labelStyle = EditorStyles.label;
|
||||
labelStyle.alignment = TextAnchor.UpperLeft;
|
||||
|
||||
Rect labelRect = new Rect(rect);
|
||||
labelRect.width = 200f;
|
||||
EditorGUI.LabelField(labelRect, new GUIContent(label), labelStyle);
|
||||
|
||||
GUIStyle textureStyle = EditorStyles.objectField;
|
||||
textureStyle.alignment = TextAnchor.MiddleLeft;
|
||||
|
||||
Rect textureRect = new Rect(rect);
|
||||
textureRect.width = height;
|
||||
textureRect.height = height;
|
||||
textureRect.x = rect.width - textureRect.width - 10f;
|
||||
|
||||
Texture res = (Texture)EditorGUI.ObjectField(textureRect, tex, typeof(Texture), false);
|
||||
lastRect.y += height;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private Texture DrawGradientField(float height, string label, Texture texValue)
|
||||
{
|
||||
Texture res = texValue;
|
||||
|
||||
Rect rect = new Rect(lastRect);
|
||||
rect.height = height;
|
||||
rect.y += height * 0.5f;
|
||||
|
||||
float createButtonWidth = 100f;
|
||||
|
||||
GUIStyle labelStyle = EditorStyles.label;
|
||||
labelStyle.alignment = TextAnchor.UpperLeft;
|
||||
Rect labelRect = new Rect(rect);
|
||||
labelRect.width = 200f;
|
||||
EditorGUI.LabelField(labelRect, new GUIContent(label), labelStyle);
|
||||
|
||||
GUIStyle textureStyle = EditorStyles.objectField;
|
||||
textureStyle.alignment = TextAnchor.MiddleLeft;
|
||||
|
||||
Rect gradientAndButtonRect = new Rect(rect);
|
||||
gradientAndButtonRect.width = rect.width - labelRect.width;
|
||||
gradientAndButtonRect.height = rect.height;
|
||||
gradientAndButtonRect.x = labelRect.x + labelRect.width;
|
||||
|
||||
Rect gradientRect = new Rect(gradientAndButtonRect);
|
||||
gradientRect.width = gradientAndButtonRect.width * 0.5f;
|
||||
gradientRect.height = rect.height * 0.5f;
|
||||
gradientRect.x = rect.x + rect.width - gradientRect.width - (createButtonWidth * 2f) - 10f;
|
||||
gradient = EditorGUI.GradientField(gradientRect, gradient);
|
||||
|
||||
Rect createButtonRect = new Rect(gradientAndButtonRect);
|
||||
createButtonRect.width = createButtonWidth;
|
||||
createButtonRect.height = gradientRect.height;
|
||||
createButtonRect.x = gradientRect.x + gradientRect.width + 10f;
|
||||
|
||||
Rect modifyButtonRect = new Rect(createButtonRect);
|
||||
modifyButtonRect.x = createButtonRect.x + createButtonRect.width + 10f;
|
||||
|
||||
if (GUI.Button(createButtonRect, "Save Texture"))
|
||||
{
|
||||
res = ChangeTextureOnDisk(true);
|
||||
}
|
||||
|
||||
EditorGUI.BeginDisabledGroup(!isModifyingExistingTexture || gradientTextureAsset == null);
|
||||
if (GUI.Button(modifyButtonRect, "Overwrite"))
|
||||
{
|
||||
res = ChangeTextureOnDisk(false);
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
lastRect.y += height + OFFSET;
|
||||
|
||||
if (usingPreviewTex && !textureSaved)
|
||||
{
|
||||
Rect helpBoxRect = new Rect(lastRect);
|
||||
helpBoxRect.height = 40f;
|
||||
EditorGUI.HelpBox(helpBoxRect, "Texture is not saved! Click on Save Texture to save it", MessageType.Warning);
|
||||
|
||||
lastRect.y += helpBoxRect.height + OFFSET;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private Texture ChangeTextureOnDisk(bool createNew)
|
||||
{
|
||||
gradientCreatorTool.CreateGradientTexture(gradient);
|
||||
Texture savedTex = gradientCreatorTool.SaveGradientTexture(gradientTextureAsset, createNew);
|
||||
|
||||
Texture res = savedTex;
|
||||
lastSavedTexture = savedTex;
|
||||
|
||||
textureSaved = true;
|
||||
usingPreviewTex = false;
|
||||
createGradientToggle = false;
|
||||
|
||||
gradientTextureAsset = null;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private void DrawCreateGradientToggle(float height, string label)
|
||||
{
|
||||
Rect rect = new Rect(lastRect);
|
||||
rect.height = height;
|
||||
|
||||
Rect toggleRect = new Rect(rect);
|
||||
|
||||
createGradientToggle = EditorGUI.ToggleLeft(toggleRect, label, createGradientToggle);
|
||||
|
||||
lastRect.y += height;
|
||||
}
|
||||
|
||||
public float GetPropertyHeight()
|
||||
{
|
||||
float res = 80f;
|
||||
|
||||
if (createGradientToggle)
|
||||
{
|
||||
res += 45f;
|
||||
if (usingPreviewTex)
|
||||
{
|
||||
res += 40f;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user