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