You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
193 lines
5.8 KiB
193 lines
5.8 KiB
|
6 years ago
|
using UnityEditor;
|
||
|
|
using UnityEngine;
|
||
|
|
|
||
|
|
namespace Klak.Chromatics
|
||
|
|
{
|
||
|
|
// Custom editor for cosine gradient object
|
||
|
|
[CustomEditor(typeof(CosineGradient))]
|
||
|
|
public class CosineGradientEditor : Editor
|
||
|
|
{
|
||
|
|
GraphDrawer _graph;
|
||
|
|
PreviewDrawer _preview;
|
||
|
|
|
||
|
|
SerializedProperty _redCoeffs;
|
||
|
|
SerializedProperty _greenCoeffs;
|
||
|
|
SerializedProperty _blueCoeffs;
|
||
|
|
|
||
|
|
[SerializeField] Shader _previewShader;
|
||
|
|
|
||
|
|
void OnEnable()
|
||
|
|
{
|
||
|
|
_graph = new GraphDrawer();
|
||
|
|
_preview = new PreviewDrawer(_previewShader);
|
||
|
|
|
||
|
|
_redCoeffs = serializedObject.FindProperty("_redCoeffs");
|
||
|
|
_greenCoeffs = serializedObject.FindProperty("_greenCoeffs");
|
||
|
|
_blueCoeffs = serializedObject.FindProperty("_blueCoeffs");
|
||
|
|
}
|
||
|
|
|
||
|
|
void OnDisable()
|
||
|
|
{
|
||
|
|
_preview.Cleanup();
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void OnInspectorGUI()
|
||
|
|
{
|
||
|
|
serializedObject.Update();
|
||
|
|
|
||
|
|
_graph.DrawGraph((CosineGradient)target);
|
||
|
|
|
||
|
|
EditorGUILayout.Space();
|
||
|
|
|
||
|
|
_preview.DrawPreview((CosineGradient)target);
|
||
|
|
|
||
|
|
EditorGUILayout.Space();
|
||
|
|
|
||
|
|
ShowSliders("Red", _redCoeffs);
|
||
|
|
ShowSliders("Green", _greenCoeffs);
|
||
|
|
ShowSliders("Blue", _blueCoeffs);
|
||
|
|
|
||
|
|
serializedObject.ApplyModifiedProperties();
|
||
|
|
}
|
||
|
|
|
||
|
|
void ShowSliders(string label, SerializedProperty prop)
|
||
|
|
{
|
||
|
|
var v = prop.vector4Value;
|
||
|
|
|
||
|
|
EditorGUILayout.LabelField(label);
|
||
|
|
EditorGUI.BeginChangeCheck();
|
||
|
|
|
||
|
|
EditorGUI.indentLevel++;
|
||
|
|
v.x = EditorGUILayout.Slider("Bias", v.x, 0, 1);
|
||
|
|
v.y = EditorGUILayout.Slider("Amplitude", v.y, 0, 1);
|
||
|
|
v.z = EditorGUILayout.Slider("Frequency", v.z, 0, 3);
|
||
|
|
v.w = EditorGUILayout.Slider("Phase", v.w, 0, 1);
|
||
|
|
EditorGUI.indentLevel--;
|
||
|
|
|
||
|
|
if (EditorGUI.EndChangeCheck())
|
||
|
|
prop.vector4Value = new Vector4(v.x, v.y, v.z, v.w);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// A utility class for drawing component curves.
|
||
|
|
public class GraphDrawer
|
||
|
|
{
|
||
|
|
#region Public Methods
|
||
|
|
|
||
|
|
public void DrawGraph(CosineGradient grad)
|
||
|
|
{
|
||
|
|
_rectGraph = GUILayoutUtility.GetRect(128, 80);
|
||
|
|
|
||
|
|
// Background
|
||
|
|
DrawRect(0, 0, 1, 1, 0.1f, 0.4f);
|
||
|
|
|
||
|
|
// Horizontal line
|
||
|
|
var lineColor = Color.white * 0.4f;
|
||
|
|
DrawLine(0, 0.5f, 1, 0.5f, lineColor);
|
||
|
|
|
||
|
|
// Vertical lines
|
||
|
|
DrawLine(0.25f, 0, 0.25f, 1, lineColor);
|
||
|
|
DrawLine(0.50f, 0, 0.50f, 1, lineColor);
|
||
|
|
DrawLine(0.75f, 0, 0.75f, 1, lineColor);
|
||
|
|
|
||
|
|
// R/G/B curves
|
||
|
|
DrawGradientCurve(grad.redCoeffs, Color.red);
|
||
|
|
DrawGradientCurve(grad.greenCoeffs, Color.green);
|
||
|
|
DrawGradientCurve(grad.blueCoeffs, Color.blue);
|
||
|
|
}
|
||
|
|
|
||
|
|
void DrawGradientCurve(Vector4 coeffs, Color color)
|
||
|
|
{
|
||
|
|
for (var i = 0; i < _curveResolution; i++)
|
||
|
|
{
|
||
|
|
var x = (float)i / (_curveResolution - 1);
|
||
|
|
var theta = (coeffs.z * x + coeffs.w) * Mathf.PI * 2;
|
||
|
|
var y = coeffs.x + coeffs.y * Mathf.Cos(theta);
|
||
|
|
_curveVertices[i] = PointInRect(x, Mathf.Clamp01(y));
|
||
|
|
}
|
||
|
|
|
||
|
|
Handles.color = color;
|
||
|
|
Handles.DrawAAPolyLine(2.0f, _curveResolution, _curveVertices);
|
||
|
|
}
|
||
|
|
|
||
|
|
#endregion
|
||
|
|
|
||
|
|
#region Graph Functions
|
||
|
|
|
||
|
|
// Number of vertices in curve
|
||
|
|
const int _curveResolution = 96;
|
||
|
|
|
||
|
|
// Vertex buffers
|
||
|
|
Vector3[] _rectVertices = new Vector3[4];
|
||
|
|
Vector3[] _lineVertices = new Vector3[2];
|
||
|
|
Vector3[] _curveVertices = new Vector3[_curveResolution];
|
||
|
|
|
||
|
|
Rect _rectGraph;
|
||
|
|
|
||
|
|
// Transform a point into the graph rect.
|
||
|
|
Vector3 PointInRect(float x, float y)
|
||
|
|
{
|
||
|
|
x = Mathf.Lerp(_rectGraph.x, _rectGraph.xMax, x);
|
||
|
|
y = Mathf.Lerp(_rectGraph.yMax, _rectGraph.y, y);
|
||
|
|
return new Vector3(x, y, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Draw a line in the graph rect.
|
||
|
|
void DrawLine(float x1, float y1, float x2, float y2, Color color)
|
||
|
|
{
|
||
|
|
_lineVertices[0] = PointInRect(x1, y1);
|
||
|
|
_lineVertices[1] = PointInRect(x2, y2);
|
||
|
|
Handles.color = color;
|
||
|
|
Handles.DrawAAPolyLine(2.0f, _lineVertices);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Draw a rect in the graph rect.
|
||
|
|
void DrawRect(float x1, float y1, float x2, float y2, float fill, float line)
|
||
|
|
{
|
||
|
|
_rectVertices[0] = PointInRect(x1, y1);
|
||
|
|
_rectVertices[1] = PointInRect(x2, y1);
|
||
|
|
_rectVertices[2] = PointInRect(x2, y2);
|
||
|
|
_rectVertices[3] = PointInRect(x1, y2);
|
||
|
|
|
||
|
|
Handles.DrawSolidRectangleWithOutline(
|
||
|
|
_rectVertices,
|
||
|
|
fill < 0 ? Color.clear : Color.white * fill,
|
||
|
|
line < 0 ? Color.clear : Color.white * line
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
#endregion
|
||
|
|
}
|
||
|
|
|
||
|
|
// A utility class for drawing a gradient preview area.
|
||
|
|
public class PreviewDrawer
|
||
|
|
{
|
||
|
|
Material _material;
|
||
|
|
|
||
|
|
public PreviewDrawer(Shader shader)
|
||
|
|
{
|
||
|
|
_material = new Material(Shader.Find("Hidden/Klak/Chromatics/CosineGradient/Preview"));
|
||
|
|
_material.hideFlags = HideFlags.DontSave;
|
||
|
|
}
|
||
|
|
|
||
|
|
public void Cleanup()
|
||
|
|
{
|
||
|
|
if (_material != null) Object.DestroyImmediate(_material);
|
||
|
|
_material = null;
|
||
|
|
}
|
||
|
|
|
||
|
|
public void DrawPreview(CosineGradient grad)
|
||
|
|
{
|
||
|
|
_material.SetVector("_CoeffsA", grad.coeffsA);
|
||
|
|
_material.SetVector("_CoeffsB", grad.coeffsB);
|
||
|
|
_material.SetVector("_CoeffsC", grad.coeffsC2);
|
||
|
|
_material.SetVector("_CoeffsD", grad.coeffsD2);
|
||
|
|
|
||
|
|
EditorGUI.DrawPreviewTexture(
|
||
|
|
GUILayoutUtility.GetRect(128, 32),
|
||
|
|
EditorGUIUtility.whiteTexture, _material
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|