BloomGraphDrawer.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // Copyright (C) 2015, 2016 Keijiro Takahashi
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE.
  20. //
  21. using UnityEngine;
  22. using UnityEditor;
  23. namespace Max820
  24. {
  25. // Class used for drawing the brightness response curve
  26. public class BloomGraphDrawer
  27. {
  28. #region Public Methods
  29. // Update internal state with a given bloom instance.
  30. public void Prepare(Bloom bloom)
  31. {
  32. #if UNITY_5_6_OR_NEWER
  33. if (bloom.GetComponent<Camera>().allowHDR)
  34. #else
  35. if (bloom.GetComponent<Camera>().hdr)
  36. #endif
  37. {
  38. _rangeX = 6;
  39. _rangeY = 1.5f;
  40. }
  41. else
  42. {
  43. _rangeX = 1;
  44. _rangeY = 1;
  45. }
  46. _threshold = bloom.thresholdLinear;
  47. _knee = bloom.softKnee * _threshold + 1e-5f;
  48. // Intensity is capped to prevent sampling errors.
  49. _intensity = Mathf.Min(bloom.intensity, 10);
  50. }
  51. // Draw the graph at the current position.
  52. public void DrawGraph()
  53. {
  54. _rectGraph = GUILayoutUtility.GetRect(128, 80);
  55. // Background
  56. DrawRect(0, 0, _rangeX, _rangeY, 0.1f, 0.4f);
  57. // Soft-knee range
  58. DrawRect(_threshold - _knee, 0, _threshold + _knee, _rangeY, 0.25f, -1);
  59. // Horizontal lines
  60. for (var i = 1; i < _rangeY; i++)
  61. DrawLine(0, i, _rangeX, i, 0.4f);
  62. // Vertical lines
  63. for (var i = 1; i < _rangeX; i++)
  64. DrawLine(i, 0, i, _rangeY, 0.4f);
  65. // Label
  66. Handles.Label(
  67. PointInRect(0, _rangeY) + Vector3.right,
  68. "Brightness Response (linear)", EditorStyles.miniLabel
  69. );
  70. // Threshold line
  71. DrawLine(_threshold, 0, _threshold, _rangeY, 0.6f);
  72. // Response curve
  73. var vcount = 0;
  74. while (vcount < _curveResolution)
  75. {
  76. var x = _rangeX * vcount / (_curveResolution - 1);
  77. var y = ResponseFunction(x);
  78. if (y < _rangeY)
  79. {
  80. _curveVertices[vcount++] = PointInRect(x, y);
  81. }
  82. else
  83. {
  84. if (vcount > 1)
  85. {
  86. // Extend the last segment to the top edge of the rect.
  87. var v1 = _curveVertices[vcount - 2];
  88. var v2 = _curveVertices[vcount - 1];
  89. var clip = (_rectGraph.y - v1.y) / (v2.y - v1.y);
  90. _curveVertices[vcount - 1] = v1 + (v2 - v1) * clip;
  91. }
  92. break;
  93. }
  94. }
  95. if (vcount > 1)
  96. {
  97. Handles.color = Color.white * 0.9f;
  98. Handles.DrawAAPolyLine(2.0f, vcount, _curveVertices);
  99. }
  100. }
  101. #endregion
  102. #region Response Function
  103. float _threshold;
  104. float _knee;
  105. float _intensity;
  106. float ResponseFunction(float x)
  107. {
  108. var rq = Mathf.Clamp(x - _threshold + _knee, 0, _knee * 2);
  109. rq = rq * rq * 0.25f / _knee;
  110. return Mathf.Max(rq, x - _threshold) * _intensity;
  111. }
  112. #endregion
  113. #region Graph Functions
  114. // Number of vertices in curve
  115. const int _curveResolution = 96;
  116. // Vertex buffers
  117. Vector3[] _rectVertices = new Vector3[4];
  118. Vector3[] _lineVertices = new Vector3[2];
  119. Vector3[] _curveVertices = new Vector3[_curveResolution];
  120. Rect _rectGraph;
  121. float _rangeX;
  122. float _rangeY;
  123. // Transform a point into the graph rect.
  124. Vector3 PointInRect(float x, float y)
  125. {
  126. x = Mathf.Lerp(_rectGraph.x, _rectGraph.xMax, x / _rangeX);
  127. y = Mathf.Lerp(_rectGraph.yMax, _rectGraph.y, y / _rangeY);
  128. return new Vector3(x, y, 0);
  129. }
  130. // Draw a line in the graph rect.
  131. void DrawLine(float x1, float y1, float x2, float y2, float grayscale)
  132. {
  133. _lineVertices[0] = PointInRect(x1, y1);
  134. _lineVertices[1] = PointInRect(x2, y2);
  135. Handles.color = Color.white * grayscale;
  136. Handles.DrawAAPolyLine(2.0f, _lineVertices);
  137. }
  138. // Draw a rect in the graph rect.
  139. void DrawRect(float x1, float y1, float x2, float y2, float fill, float line)
  140. {
  141. _rectVertices[0] = PointInRect(x1, y1);
  142. _rectVertices[1] = PointInRect(x2, y1);
  143. _rectVertices[2] = PointInRect(x2, y2);
  144. _rectVertices[3] = PointInRect(x1, y2);
  145. Handles.DrawSolidRectangleWithOutline(
  146. _rectVertices,
  147. fill < 0 ? Color.clear : Color.white * fill,
  148. line < 0 ? Color.clear : Color.white * line
  149. );
  150. }
  151. #endregion
  152. }
  153. }