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.
204 lines
6.9 KiB
204 lines
6.9 KiB
using UnityEngine; |
|
using UnityEngine.PostProcessing; |
|
|
|
namespace UnityEditor.PostProcessing |
|
{ |
|
using Settings = BloomModel.Settings; |
|
|
|
[PostProcessingModelEditor(typeof(BloomModel))] |
|
public class BloomModelEditor : PostProcessingModelEditor |
|
{ |
|
struct BloomSettings |
|
{ |
|
public SerializedProperty intensity; |
|
public SerializedProperty threshold; |
|
public SerializedProperty softKnee; |
|
public SerializedProperty radius; |
|
public SerializedProperty antiFlicker; |
|
} |
|
|
|
struct LensDirtSettings |
|
{ |
|
public SerializedProperty texture; |
|
public SerializedProperty intensity; |
|
} |
|
|
|
BloomSettings m_Bloom; |
|
LensDirtSettings m_LensDirt; |
|
|
|
public override void OnEnable() |
|
{ |
|
m_Bloom = new BloomSettings |
|
{ |
|
intensity = FindSetting((Settings x) => x.bloom.intensity), |
|
threshold = FindSetting((Settings x) => x.bloom.threshold), |
|
softKnee = FindSetting((Settings x) => x.bloom.softKnee), |
|
radius = FindSetting((Settings x) => x.bloom.radius), |
|
antiFlicker = FindSetting((Settings x) => x.bloom.antiFlicker) |
|
}; |
|
|
|
m_LensDirt = new LensDirtSettings |
|
{ |
|
texture = FindSetting((Settings x) => x.lensDirt.texture), |
|
intensity = FindSetting((Settings x) => x.lensDirt.intensity) |
|
}; |
|
} |
|
|
|
public override void OnInspectorGUI() |
|
{ |
|
EditorGUILayout.Space(); |
|
PrepareGraph(); |
|
DrawGraph(); |
|
EditorGUILayout.Space(); |
|
|
|
EditorGUILayout.PropertyField(m_Bloom.intensity); |
|
EditorGUILayout.PropertyField(m_Bloom.threshold, EditorGUIHelper.GetContent("Threshold (Gamma)")); |
|
EditorGUILayout.PropertyField(m_Bloom.softKnee); |
|
EditorGUILayout.PropertyField(m_Bloom.radius); |
|
EditorGUILayout.PropertyField(m_Bloom.antiFlicker); |
|
|
|
EditorGUILayout.Space(); |
|
EditorGUILayout.LabelField("Dirt", EditorStyles.boldLabel); |
|
EditorGUI.indentLevel++; |
|
EditorGUILayout.PropertyField(m_LensDirt.texture); |
|
EditorGUILayout.PropertyField(m_LensDirt.intensity); |
|
EditorGUI.indentLevel--; |
|
} |
|
|
|
#region Graph |
|
|
|
float m_GraphThreshold; |
|
float m_GraphKnee; |
|
float m_GraphIntensity; |
|
|
|
// Number of vertices in curve |
|
const int k_CurveResolution = 48; |
|
|
|
// Vertex buffers |
|
Vector3[] m_RectVertices = new Vector3[4]; |
|
Vector3[] m_LineVertices = new Vector3[2]; |
|
Vector3[] m_CurveVertices = new Vector3[k_CurveResolution]; |
|
|
|
Rect m_RectGraph; |
|
float m_RangeX; |
|
float m_RangeY; |
|
|
|
float ResponseFunction(float x) |
|
{ |
|
var rq = Mathf.Clamp(x - m_GraphThreshold + m_GraphKnee, 0, m_GraphKnee * 2); |
|
rq = rq * rq * 0.25f / m_GraphKnee; |
|
return Mathf.Max(rq, x - m_GraphThreshold) * m_GraphIntensity; |
|
} |
|
|
|
// Transform a point into the graph rect |
|
Vector3 PointInRect(float x, float y) |
|
{ |
|
x = Mathf.Lerp(m_RectGraph.x, m_RectGraph.xMax, x / m_RangeX); |
|
y = Mathf.Lerp(m_RectGraph.yMax, m_RectGraph.y, y / m_RangeY); |
|
return new Vector3(x, y, 0); |
|
} |
|
|
|
// Draw a line in the graph rect |
|
void DrawLine(float x1, float y1, float x2, float y2, float grayscale) |
|
{ |
|
m_LineVertices[0] = PointInRect(x1, y1); |
|
m_LineVertices[1] = PointInRect(x2, y2); |
|
Handles.color = Color.white * grayscale; |
|
Handles.DrawAAPolyLine(2.0f, m_LineVertices); |
|
} |
|
|
|
// Draw a rect in the graph rect |
|
void DrawRect(float x1, float y1, float x2, float y2, float fill, float line) |
|
{ |
|
m_RectVertices[0] = PointInRect(x1, y1); |
|
m_RectVertices[1] = PointInRect(x2, y1); |
|
m_RectVertices[2] = PointInRect(x2, y2); |
|
m_RectVertices[3] = PointInRect(x1, y2); |
|
|
|
Handles.DrawSolidRectangleWithOutline( |
|
m_RectVertices, |
|
fill < 0 ? Color.clear : Color.white * fill, |
|
line < 0 ? Color.clear : Color.white * line |
|
); |
|
} |
|
|
|
// Update internal state with a given bloom instance |
|
public void PrepareGraph() |
|
{ |
|
var bloom = (BloomModel)target; |
|
m_RangeX = 5f; |
|
m_RangeY = 2f; |
|
|
|
m_GraphThreshold = bloom.settings.bloom.thresholdLinear; |
|
m_GraphKnee = bloom.settings.bloom.softKnee * m_GraphThreshold + 1e-5f; |
|
|
|
// Intensity is capped to prevent sampling errors |
|
m_GraphIntensity = Mathf.Min(bloom.settings.bloom.intensity, 10f); |
|
} |
|
|
|
// Draw the graph at the current position |
|
public void DrawGraph() |
|
{ |
|
using (new GUILayout.HorizontalScope()) |
|
{ |
|
GUILayout.Space(EditorGUI.indentLevel * 15f); |
|
m_RectGraph = GUILayoutUtility.GetRect(128, 80); |
|
} |
|
|
|
// Background |
|
DrawRect(0, 0, m_RangeX, m_RangeY, 0.1f, 0.4f); |
|
|
|
// Soft-knee range |
|
DrawRect(m_GraphThreshold - m_GraphKnee, 0, m_GraphThreshold + m_GraphKnee, m_RangeY, 0.25f, -1); |
|
|
|
// Horizontal lines |
|
for (var i = 1; i < m_RangeY; i++) |
|
DrawLine(0, i, m_RangeX, i, 0.4f); |
|
|
|
// Vertical lines |
|
for (var i = 1; i < m_RangeX; i++) |
|
DrawLine(i, 0, i, m_RangeY, 0.4f); |
|
|
|
// Label |
|
Handles.Label( |
|
PointInRect(0, m_RangeY) + Vector3.right, |
|
"Brightness Response (linear)", EditorStyles.miniLabel |
|
); |
|
|
|
// Threshold line |
|
DrawLine(m_GraphThreshold, 0, m_GraphThreshold, m_RangeY, 0.6f); |
|
|
|
// Response curve |
|
var vcount = 0; |
|
while (vcount < k_CurveResolution) |
|
{ |
|
var x = m_RangeX * vcount / (k_CurveResolution - 1); |
|
var y = ResponseFunction(x); |
|
if (y < m_RangeY) |
|
{ |
|
m_CurveVertices[vcount++] = PointInRect(x, y); |
|
} |
|
else |
|
{ |
|
if (vcount > 1) |
|
{ |
|
// Extend the last segment to the top edge of the rect. |
|
var v1 = m_CurveVertices[vcount - 2]; |
|
var v2 = m_CurveVertices[vcount - 1]; |
|
var clip = (m_RectGraph.y - v1.y) / (v2.y - v1.y); |
|
m_CurveVertices[vcount - 1] = v1 + (v2 - v1) * clip; |
|
} |
|
break; |
|
} |
|
} |
|
|
|
if (vcount > 1) |
|
{ |
|
Handles.color = Color.white * 0.9f; |
|
Handles.DrawAAPolyLine(2.0f, vcount, m_CurveVertices); |
|
} |
|
} |
|
|
|
#endregion |
|
} |
|
}
|
|
|