| | |
| | | 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 |
| | | } |
| | | } |
| | | 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
|
| | | }
|
| | | }
|