@@ -8,6 +8,7 @@ namespace UnityEditor.PostProcessing
88{
99 using Settings = ColorGradingModel . Settings ;
1010 using Tonemapper = ColorGradingModel . Tonemapper ;
11+ using ColorWheelMode = ColorGradingModel . ColorWheelMode ;
1112
1213 [ PostProcessingModelEditor ( typeof ( ColorGradingModel ) ) ]
1314 public class ColorGradingModelEditor : PostProcessingModelEditor
@@ -48,6 +49,7 @@ struct ChannelMixerSettings
4849
4950 struct ColorWheelsSettings
5051 {
52+ public SerializedProperty mode ;
5153 public SerializedProperty log ;
5254 public SerializedProperty linear ;
5355 }
@@ -89,6 +91,15 @@ struct CurvesSettings
8991 CurveEditor m_CurveEditor ;
9092 Dictionary < SerializedProperty , Color > m_CurveDict ;
9193
94+ // Neutral tonemapping curve helper
95+ const int k_CurveResolution = 24 ;
96+ const float k_NeutralRangeX = 2f ;
97+ const float k_NeutralRangeY = 1f ;
98+ Vector3 [ ] m_RectVertices = new Vector3 [ 4 ] ;
99+ Vector3 [ ] m_LineVertices = new Vector3 [ 2 ] ;
100+ Vector3 [ ] m_CurveVertices = new Vector3 [ k_CurveResolution ] ;
101+ Rect m_NeutralCurveRect ;
102+
92103 public override void OnEnable ( )
93104 {
94105 // Tonemapping settings
@@ -129,6 +140,7 @@ public override void OnEnable()
129140 // Color wheels
130141 m_ColorWheels = new ColorWheelsSettings
131142 {
143+ mode = FindSetting ( ( Settings x ) => x . colorWheels . mode ) ,
132144 log = FindSetting ( ( Settings x ) => x . colorWheels . log ) ,
133145 linear = FindSetting ( ( Settings x ) => x . colorWheels . linear )
134146 } ;
@@ -214,6 +226,8 @@ void DoTonemappingGUI()
214226
215227 if ( tid == ( int ) Tonemapper . Neutral )
216228 {
229+ DrawNeutralTonemappingCurve ( ) ;
230+
217231 EditorGUILayout . PropertyField ( m_Tonemapping . neutralBlackIn , EditorGUIHelper . GetContent ( "Black In" ) ) ;
218232 EditorGUILayout . PropertyField ( m_Tonemapping . neutralWhiteIn , EditorGUIHelper . GetContent ( "White In" ) ) ;
219233 EditorGUILayout . PropertyField ( m_Tonemapping . neutralBlackOut , EditorGUIHelper . GetContent ( "Black Out" ) ) ;
@@ -225,6 +239,129 @@ void DoTonemappingGUI()
225239 m_Tonemapping . tonemapper . intValue = tid ;
226240 }
227241
242+ void DrawNeutralTonemappingCurve ( )
243+ {
244+ using ( new GUILayout . HorizontalScope ( ) )
245+ {
246+ GUILayout . Space ( EditorGUI . indentLevel * 15f ) ;
247+ m_NeutralCurveRect = GUILayoutUtility . GetRect ( 128 , 80 ) ;
248+ }
249+
250+ // Background
251+ m_RectVertices [ 0 ] = PointInRect ( 0f , 0f ) ;
252+ m_RectVertices [ 1 ] = PointInRect ( k_NeutralRangeX , 0f ) ;
253+ m_RectVertices [ 2 ] = PointInRect ( k_NeutralRangeX , k_NeutralRangeY ) ;
254+ m_RectVertices [ 3 ] = PointInRect ( 0f , k_NeutralRangeY ) ;
255+
256+ Handles . DrawSolidRectangleWithOutline (
257+ m_RectVertices ,
258+ Color . white * 0.1f ,
259+ Color . white * 0.4f
260+ ) ;
261+
262+ // Horizontal lines
263+ for ( var i = 1 ; i < k_NeutralRangeY ; i ++ )
264+ DrawLine ( 0 , i , k_NeutralRangeX , i , 0.4f ) ;
265+
266+ // Vertical lines
267+ for ( var i = 1 ; i < k_NeutralRangeX ; i ++ )
268+ DrawLine ( i , 0 , i , k_NeutralRangeY , 0.4f ) ;
269+
270+ // Label
271+ Handles . Label (
272+ PointInRect ( 0 , k_NeutralRangeY ) + Vector3 . right ,
273+ "Neutral Tonemapper" , EditorStyles . miniLabel
274+ ) ;
275+
276+ // Precompute some values
277+ var tonemap = ( ( ColorGradingModel ) target ) . settings . tonemapping ;
278+
279+ const float scaleFactor = 20f ;
280+ const float scaleFactorHalf = scaleFactor * 0.5f ;
281+
282+ float inBlack = tonemap . neutralBlackIn * scaleFactor + 1f ;
283+ float outBlack = tonemap . neutralBlackOut * scaleFactorHalf + 1f ;
284+ float inWhite = tonemap . neutralWhiteIn / scaleFactor ;
285+ float outWhite = 1f - tonemap . neutralWhiteOut / scaleFactor ;
286+ float blackRatio = inBlack / outBlack ;
287+ float whiteRatio = inWhite / outWhite ;
288+
289+ const float a = 0.2f ;
290+ float b = Mathf . Max ( 0f , Mathf . LerpUnclamped ( 0.57f , 0.37f , blackRatio ) ) ;
291+ float c = Mathf . LerpUnclamped ( 0.01f , 0.24f , whiteRatio ) ;
292+ float d = Mathf . Max ( 0f , Mathf . LerpUnclamped ( 0.02f , 0.20f , blackRatio ) ) ;
293+ const float e = 0.02f ;
294+ const float f = 0.30f ;
295+ float whiteLevel = tonemap . neutralWhiteLevel ;
296+ float whiteClip = tonemap . neutralWhiteClip / scaleFactorHalf ;
297+
298+ // Tonemapping curve
299+ var vcount = 0 ;
300+ while ( vcount < k_CurveResolution )
301+ {
302+ float x = k_NeutralRangeX * vcount / ( k_CurveResolution - 1 ) ;
303+ float y = NeutralTonemap ( x , a , b , c , d , e , f , whiteLevel , whiteClip ) ;
304+
305+ if ( y < k_NeutralRangeY )
306+ {
307+ m_CurveVertices [ vcount ++ ] = PointInRect ( x , y ) ;
308+ }
309+ else
310+ {
311+ if ( vcount > 1 )
312+ {
313+ // Extend the last segment to the top edge of the rect.
314+ var v1 = m_CurveVertices [ vcount - 2 ] ;
315+ var v2 = m_CurveVertices [ vcount - 1 ] ;
316+ var clip = ( m_NeutralCurveRect . y - v1 . y ) / ( v2 . y - v1 . y ) ;
317+ m_CurveVertices [ vcount - 1 ] = v1 + ( v2 - v1 ) * clip ;
318+ }
319+ break ;
320+ }
321+ }
322+
323+ if ( vcount > 1 )
324+ {
325+ Handles . color = Color . white * 0.9f ;
326+ Handles . DrawAAPolyLine ( 2.0f , vcount , m_CurveVertices ) ;
327+ }
328+ }
329+
330+ void DrawLine ( float x1 , float y1 , float x2 , float y2 , float grayscale )
331+ {
332+ m_LineVertices [ 0 ] = PointInRect ( x1 , y1 ) ;
333+ m_LineVertices [ 1 ] = PointInRect ( x2 , y2 ) ;
334+ Handles . color = Color . white * grayscale ;
335+ Handles . DrawAAPolyLine ( 2f , m_LineVertices ) ;
336+ }
337+
338+ Vector3 PointInRect ( float x , float y )
339+ {
340+ x = Mathf . Lerp ( m_NeutralCurveRect . x , m_NeutralCurveRect . xMax , x / k_NeutralRangeX ) ;
341+ y = Mathf . Lerp ( m_NeutralCurveRect . yMax , m_NeutralCurveRect . y , y / k_NeutralRangeY ) ;
342+ return new Vector3 ( x , y , 0 ) ;
343+ }
344+
345+ float NeutralCurve ( float x , float a , float b , float c , float d , float e , float f )
346+ {
347+ return ( ( x * ( a * x + c * b ) + d * e ) / ( x * ( a * x + b ) + d * f ) ) - e / f ;
348+ }
349+
350+ float NeutralTonemap ( float x , float a , float b , float c , float d , float e , float f , float whiteLevel , float whiteClip )
351+ {
352+ x = Mathf . Max ( 0f , x ) ;
353+
354+ // Tonemap
355+ float whiteScale = 1f / NeutralCurve ( whiteLevel , a , b , c , d , e , f ) ;
356+ x = NeutralCurve ( x * whiteScale , a , b , c , d , e , f ) ;
357+ x *= whiteScale ;
358+
359+ // Post-curve white point adjustment
360+ x /= whiteClip ;
361+
362+ return x ;
363+ }
364+
228365 void DoBasicGUI ( )
229366 {
230367 EditorGUILayout . PropertyField ( m_Basic . exposure , EditorGUIHelper . GetContent ( "Post Exposure (EV)" ) ) ;
@@ -266,15 +403,28 @@ void DoChannelMixerGUI()
266403
267404 void DoColorWheelsGUI ( )
268405 {
269- EditorGUILayout . Space ( ) ;
270- EditorGUILayout . PropertyField ( m_ColorWheels . linear ) ;
271- var rect = GUILayoutUtility . GetLastRect ( ) ;
272- WheelSetTitle ( rect , "Linear Controls" ) ;
273-
274- EditorGUILayout . Space ( ) ;
275- EditorGUILayout . PropertyField ( m_ColorWheels . log ) ;
276- rect = GUILayoutUtility . GetLastRect ( ) ;
277- WheelSetTitle ( rect , "Log Controls" ) ;
406+ int wheelMode = m_ColorWheels . mode . intValue ;
407+
408+ using ( new EditorGUILayout . HorizontalScope ( ) )
409+ {
410+ GUILayout . Space ( 15 ) ;
411+ if ( GUILayout . Toggle ( wheelMode == ( int ) ColorWheelMode . Linear , "Linear" , EditorStyles . miniButtonLeft ) ) wheelMode = ( int ) ColorWheelMode . Linear ;
412+ if ( GUILayout . Toggle ( wheelMode == ( int ) ColorWheelMode . Log , "Log" , EditorStyles . miniButtonRight ) ) wheelMode = ( int ) ColorWheelMode . Log ;
413+ }
414+
415+ m_ColorWheels . mode . intValue = wheelMode ;
416+ EditorGUILayout . Space ( ) ;
417+
418+ if ( wheelMode == ( int ) ColorWheelMode . Linear )
419+ {
420+ EditorGUILayout . PropertyField ( m_ColorWheels . linear ) ;
421+ WheelSetTitle ( GUILayoutUtility . GetLastRect ( ) , "Linear Controls" ) ;
422+ }
423+ else if ( wheelMode == ( int ) ColorWheelMode . Log )
424+ {
425+ EditorGUILayout . PropertyField ( m_ColorWheels . log ) ;
426+ WheelSetTitle ( GUILayoutUtility . GetLastRect ( ) , "Log Controls" ) ;
427+ }
278428 }
279429
280430 static void WheelSetTitle ( Rect position , string label )
0 commit comments