| | |
| | | using UnityEngine; |
| | | using UnityEngine.PostProcessing; |
| | | |
| | | namespace UnityEditor.PostProcessing |
| | | { |
| | | using Settings = MotionBlurModel.Settings; |
| | | |
| | | [PostProcessingModelEditor(typeof(MotionBlurModel))] |
| | | public class MotionBlurModelEditor : PostProcessingModelEditor |
| | | { |
| | | SerializedProperty m_ShutterAngle; |
| | | SerializedProperty m_SampleCount; |
| | | SerializedProperty m_FrameBlending; |
| | | |
| | | GraphDrawer m_GraphDrawer; |
| | | |
| | | class GraphDrawer |
| | | { |
| | | const float k_Height = 32f; |
| | | |
| | | Texture m_BlendingIcon; |
| | | |
| | | GUIStyle m_LowerCenterStyle; |
| | | GUIStyle m_MiddleCenterStyle; |
| | | |
| | | Color m_ColorDark; |
| | | Color m_ColorGray; |
| | | |
| | | Vector3[] m_RectVertices = new Vector3[4]; |
| | | |
| | | public GraphDrawer() |
| | | { |
| | | m_BlendingIcon = EditorResources.Load<Texture>("UI/MotionBlendingIcon.png"); |
| | | |
| | | m_LowerCenterStyle = new GUIStyle(EditorStyles.miniLabel) { alignment = TextAnchor.LowerCenter }; |
| | | m_MiddleCenterStyle = new GUIStyle(EditorStyles.miniLabel) { alignment = TextAnchor.MiddleCenter }; |
| | | |
| | | if (EditorGUIUtility.isProSkin) |
| | | { |
| | | m_ColorDark = new Color(0.18f, 0.18f, 0.18f); |
| | | m_ColorGray = new Color(0.43f, 0.43f, 0.43f); |
| | | } |
| | | else |
| | | { |
| | | m_ColorDark = new Color(0.64f, 0.64f, 0.64f); |
| | | m_ColorGray = new Color(0.92f, 0.92f, 0.92f); |
| | | } |
| | | } |
| | | |
| | | public void DrawShutterGraph(float angle) |
| | | { |
| | | var center = GUILayoutUtility.GetRect(128, k_Height).center; |
| | | |
| | | // Parameters used to make transitions smooth. |
| | | var zeroWhenOff = Mathf.Min(1f, angle * 0.1f); |
| | | var zeroWhenFull = Mathf.Min(1f, (360f - angle) * 0.02f); |
| | | |
| | | // Shutter angle graph |
| | | var discCenter = center - new Vector2(k_Height * 2.4f, 0f); |
| | | // - exposure duration indicator |
| | | DrawDisc(discCenter, k_Height * Mathf.Lerp(0.5f, 0.38f, zeroWhenFull), m_ColorGray); |
| | | // - shutter disc |
| | | DrawDisc(discCenter, k_Height * 0.16f * zeroWhenFull, m_ColorDark); |
| | | // - shutter blade |
| | | DrawArc(discCenter, k_Height * 0.5f, 360f - angle, m_ColorDark); |
| | | // - shutter axis |
| | | DrawDisc(discCenter, zeroWhenOff, m_ColorGray); |
| | | |
| | | // Shutter label (off/full) |
| | | var labelSize = new Vector2(k_Height, k_Height); |
| | | var labelOrigin = discCenter - labelSize * 0.5f; |
| | | var labelRect = new Rect(labelOrigin, labelSize); |
| | | |
| | | if (Mathf.Approximately(angle, 0f)) |
| | | GUI.Label(labelRect, "Off", m_MiddleCenterStyle); |
| | | else if (Mathf.Approximately(angle, 360f)) |
| | | GUI.Label(labelRect, "Full", m_MiddleCenterStyle); |
| | | |
| | | // Exposure time bar graph |
| | | var outerBarSize = new Vector2(4.75f, 0.5f) * k_Height; |
| | | var innerBarSize = outerBarSize; |
| | | innerBarSize.x *= angle / 360f; |
| | | |
| | | var barCenter = center + new Vector2(k_Height * 0.9f, 0f); |
| | | var barOrigin = barCenter - outerBarSize * 0.5f; |
| | | |
| | | DrawRect(barOrigin, outerBarSize, m_ColorDark); |
| | | DrawRect(barOrigin, innerBarSize, m_ColorGray); |
| | | |
| | | var barText = "Exposure time = " + (angle / 3.6f).ToString("0") + "% of ΔT"; |
| | | GUI.Label(new Rect(barOrigin, outerBarSize), barText, m_MiddleCenterStyle); |
| | | } |
| | | |
| | | public void DrawBlendingGraph(float strength) |
| | | { |
| | | var center = GUILayoutUtility.GetRect(128, k_Height).center; |
| | | |
| | | var iconSize = new Vector2(k_Height, k_Height); |
| | | var iconStride = new Vector2(k_Height * 0.9f, 0f); |
| | | var iconOrigin = center - iconSize * 0.5f - iconStride * 2f; |
| | | |
| | | for (var i = 0; i < 5; i++) |
| | | { |
| | | var weight = BlendingWeight(strength, i / 60f); |
| | | var rect = new Rect(iconOrigin + iconStride * i, iconSize); |
| | | |
| | | var color = m_ColorGray; |
| | | color.a = weight; |
| | | |
| | | GUI.color = color; |
| | | GUI.Label(rect, m_BlendingIcon); |
| | | |
| | | GUI.color = Color.white; |
| | | GUI.Label(rect, (weight * 100).ToString("0") + "%", m_LowerCenterStyle); |
| | | } |
| | | // EditorGUIUtility.isProSkin |
| | | } |
| | | |
| | | // Weight function for multi frame blending |
| | | float BlendingWeight(float strength, float time) |
| | | { |
| | | if (strength > 0f || Mathf.Approximately(time, 0f)) |
| | | return Mathf.Exp(-time * Mathf.Lerp(80f, 10f, strength)); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | // Draw a solid disc in the graph rect. |
| | | void DrawDisc(Vector2 center, float radius, Color fill) |
| | | { |
| | | Handles.color = fill; |
| | | Handles.DrawSolidDisc(center, Vector3.forward, radius); |
| | | } |
| | | |
| | | // Draw an arc in the graph rect. |
| | | void DrawArc(Vector2 center, float radius, float angle, Color fill) |
| | | { |
| | | var start = new Vector2( |
| | | -Mathf.Cos(Mathf.Deg2Rad * angle / 2f), |
| | | Mathf.Sin(Mathf.Deg2Rad * angle / 2f) |
| | | ); |
| | | |
| | | Handles.color = fill; |
| | | Handles.DrawSolidArc(center, Vector3.forward, start, angle, radius); |
| | | } |
| | | |
| | | // Draw a rectangle in the graph rect. |
| | | void DrawRect(Vector2 origin, Vector2 size, Color color) |
| | | { |
| | | var p0 = origin; |
| | | var p1 = origin + size; |
| | | |
| | | m_RectVertices[0] = p0; |
| | | m_RectVertices[1] = new Vector2(p1.x, p0.y); |
| | | m_RectVertices[2] = p1; |
| | | m_RectVertices[3] = new Vector2(p0.x, p1.y); |
| | | |
| | | Handles.color = Color.white; |
| | | Handles.DrawSolidRectangleWithOutline(m_RectVertices, color, Color.clear); |
| | | } |
| | | } |
| | | |
| | | public override void OnEnable() |
| | | { |
| | | m_ShutterAngle = FindSetting((Settings x) => x.shutterAngle); |
| | | m_SampleCount = FindSetting((Settings x) => x.sampleCount); |
| | | m_FrameBlending = FindSetting((Settings x) => x.frameBlending); |
| | | } |
| | | |
| | | public override void OnInspectorGUI() |
| | | { |
| | | if (m_GraphDrawer == null) |
| | | m_GraphDrawer = new GraphDrawer(); |
| | | |
| | | EditorGUILayout.LabelField("Shutter Speed Simulation", EditorStyles.boldLabel); |
| | | EditorGUI.indentLevel++; |
| | | m_GraphDrawer.DrawShutterGraph(m_ShutterAngle.floatValue); |
| | | EditorGUILayout.PropertyField(m_ShutterAngle); |
| | | EditorGUILayout.PropertyField(m_SampleCount); |
| | | EditorGUI.indentLevel--; |
| | | EditorGUILayout.Space(); |
| | | |
| | | EditorGUILayout.LabelField("Multiple Frame Blending", EditorStyles.boldLabel); |
| | | EditorGUI.indentLevel++; |
| | | |
| | | float fbValue = m_FrameBlending.floatValue; |
| | | m_GraphDrawer.DrawBlendingGraph(fbValue); |
| | | EditorGUILayout.PropertyField(m_FrameBlending); |
| | | |
| | | if (fbValue > 0f) |
| | | EditorGUILayout.HelpBox("Multi-Frame Blending lowers precision of the final picture for optimization purposes.", MessageType.Info); |
| | | |
| | | |
| | | EditorGUI.indentLevel--; |
| | | } |
| | | } |
| | | } |
| | | using UnityEngine;
|
| | | using UnityEngine.PostProcessing;
|
| | |
|
| | | namespace UnityEditor.PostProcessing
|
| | | {
|
| | | using Settings = MotionBlurModel.Settings;
|
| | |
|
| | | [PostProcessingModelEditor(typeof(MotionBlurModel))]
|
| | | public class MotionBlurModelEditor : PostProcessingModelEditor
|
| | | {
|
| | | SerializedProperty m_ShutterAngle;
|
| | | SerializedProperty m_SampleCount;
|
| | | SerializedProperty m_FrameBlending;
|
| | |
|
| | | GraphDrawer m_GraphDrawer;
|
| | |
|
| | | class GraphDrawer
|
| | | {
|
| | | const float k_Height = 32f;
|
| | |
|
| | | Texture m_BlendingIcon;
|
| | |
|
| | | GUIStyle m_LowerCenterStyle;
|
| | | GUIStyle m_MiddleCenterStyle;
|
| | |
|
| | | Color m_ColorDark;
|
| | | Color m_ColorGray;
|
| | |
|
| | | Vector3[] m_RectVertices = new Vector3[4];
|
| | |
|
| | | public GraphDrawer()
|
| | | {
|
| | | m_BlendingIcon = EditorResources.Load<Texture>("UI/MotionBlendingIcon.png");
|
| | |
|
| | | m_LowerCenterStyle = new GUIStyle(EditorStyles.miniLabel) { alignment = TextAnchor.LowerCenter };
|
| | | m_MiddleCenterStyle = new GUIStyle(EditorStyles.miniLabel) { alignment = TextAnchor.MiddleCenter };
|
| | |
|
| | | if (EditorGUIUtility.isProSkin)
|
| | | {
|
| | | m_ColorDark = new Color(0.18f, 0.18f, 0.18f);
|
| | | m_ColorGray = new Color(0.43f, 0.43f, 0.43f);
|
| | | }
|
| | | else
|
| | | {
|
| | | m_ColorDark = new Color(0.64f, 0.64f, 0.64f);
|
| | | m_ColorGray = new Color(0.92f, 0.92f, 0.92f);
|
| | | }
|
| | | }
|
| | |
|
| | | public void DrawShutterGraph(float angle)
|
| | | {
|
| | | var center = GUILayoutUtility.GetRect(128, k_Height).center;
|
| | |
|
| | | // Parameters used to make transitions smooth.
|
| | | var zeroWhenOff = Mathf.Min(1f, angle * 0.1f);
|
| | | var zeroWhenFull = Mathf.Min(1f, (360f - angle) * 0.02f);
|
| | |
|
| | | // Shutter angle graph
|
| | | var discCenter = center - new Vector2(k_Height * 2.4f, 0f);
|
| | | // - exposure duration indicator
|
| | | DrawDisc(discCenter, k_Height * Mathf.Lerp(0.5f, 0.38f, zeroWhenFull), m_ColorGray);
|
| | | // - shutter disc
|
| | | DrawDisc(discCenter, k_Height * 0.16f * zeroWhenFull, m_ColorDark);
|
| | | // - shutter blade
|
| | | DrawArc(discCenter, k_Height * 0.5f, 360f - angle, m_ColorDark);
|
| | | // - shutter axis
|
| | | DrawDisc(discCenter, zeroWhenOff, m_ColorGray);
|
| | |
|
| | | // Shutter label (off/full)
|
| | | var labelSize = new Vector2(k_Height, k_Height);
|
| | | var labelOrigin = discCenter - labelSize * 0.5f;
|
| | | var labelRect = new Rect(labelOrigin, labelSize);
|
| | |
|
| | | if (Mathf.Approximately(angle, 0f))
|
| | | GUI.Label(labelRect, "Off", m_MiddleCenterStyle);
|
| | | else if (Mathf.Approximately(angle, 360f))
|
| | | GUI.Label(labelRect, "Full", m_MiddleCenterStyle);
|
| | |
|
| | | // Exposure time bar graph
|
| | | var outerBarSize = new Vector2(4.75f, 0.5f) * k_Height;
|
| | | var innerBarSize = outerBarSize;
|
| | | innerBarSize.x *= angle / 360f;
|
| | |
|
| | | var barCenter = center + new Vector2(k_Height * 0.9f, 0f);
|
| | | var barOrigin = barCenter - outerBarSize * 0.5f;
|
| | |
|
| | | DrawRect(barOrigin, outerBarSize, m_ColorDark);
|
| | | DrawRect(barOrigin, innerBarSize, m_ColorGray);
|
| | |
|
| | | var barText = "Exposure time = " + (angle / 3.6f).ToString("0") + "% of ΔT";
|
| | | GUI.Label(new Rect(barOrigin, outerBarSize), barText, m_MiddleCenterStyle);
|
| | | }
|
| | |
|
| | | public void DrawBlendingGraph(float strength)
|
| | | {
|
| | | var center = GUILayoutUtility.GetRect(128, k_Height).center;
|
| | |
|
| | | var iconSize = new Vector2(k_Height, k_Height);
|
| | | var iconStride = new Vector2(k_Height * 0.9f, 0f);
|
| | | var iconOrigin = center - iconSize * 0.5f - iconStride * 2f;
|
| | |
|
| | | for (var i = 0; i < 5; i++)
|
| | | {
|
| | | var weight = BlendingWeight(strength, i / 60f);
|
| | | var rect = new Rect(iconOrigin + iconStride * i, iconSize);
|
| | |
|
| | | var color = m_ColorGray;
|
| | | color.a = weight;
|
| | |
|
| | | GUI.color = color;
|
| | | GUI.Label(rect, m_BlendingIcon);
|
| | |
|
| | | GUI.color = Color.white;
|
| | | GUI.Label(rect, (weight * 100).ToString("0") + "%", m_LowerCenterStyle);
|
| | | }
|
| | | // EditorGUIUtility.isProSkin
|
| | | }
|
| | |
|
| | | // Weight function for multi frame blending
|
| | | float BlendingWeight(float strength, float time)
|
| | | {
|
| | | if (strength > 0f || Mathf.Approximately(time, 0f))
|
| | | return Mathf.Exp(-time * Mathf.Lerp(80f, 10f, strength));
|
| | |
|
| | | return 0;
|
| | | }
|
| | |
|
| | | // Draw a solid disc in the graph rect.
|
| | | void DrawDisc(Vector2 center, float radius, Color fill)
|
| | | {
|
| | | Handles.color = fill;
|
| | | Handles.DrawSolidDisc(center, Vector3.forward, radius);
|
| | | }
|
| | |
|
| | | // Draw an arc in the graph rect.
|
| | | void DrawArc(Vector2 center, float radius, float angle, Color fill)
|
| | | {
|
| | | var start = new Vector2(
|
| | | -Mathf.Cos(Mathf.Deg2Rad * angle / 2f),
|
| | | Mathf.Sin(Mathf.Deg2Rad * angle / 2f)
|
| | | );
|
| | |
|
| | | Handles.color = fill;
|
| | | Handles.DrawSolidArc(center, Vector3.forward, start, angle, radius);
|
| | | }
|
| | |
|
| | | // Draw a rectangle in the graph rect.
|
| | | void DrawRect(Vector2 origin, Vector2 size, Color color)
|
| | | {
|
| | | var p0 = origin;
|
| | | var p1 = origin + size;
|
| | |
|
| | | m_RectVertices[0] = p0;
|
| | | m_RectVertices[1] = new Vector2(p1.x, p0.y);
|
| | | m_RectVertices[2] = p1;
|
| | | m_RectVertices[3] = new Vector2(p0.x, p1.y);
|
| | |
|
| | | Handles.color = Color.white;
|
| | | Handles.DrawSolidRectangleWithOutline(m_RectVertices, color, Color.clear);
|
| | | }
|
| | | }
|
| | |
|
| | | public override void OnEnable()
|
| | | {
|
| | | m_ShutterAngle = FindSetting((Settings x) => x.shutterAngle);
|
| | | m_SampleCount = FindSetting((Settings x) => x.sampleCount);
|
| | | m_FrameBlending = FindSetting((Settings x) => x.frameBlending);
|
| | | }
|
| | |
|
| | | public override void OnInspectorGUI()
|
| | | {
|
| | | if (m_GraphDrawer == null)
|
| | | m_GraphDrawer = new GraphDrawer();
|
| | |
|
| | | EditorGUILayout.LabelField("Shutter Speed Simulation", EditorStyles.boldLabel);
|
| | | EditorGUI.indentLevel++;
|
| | | m_GraphDrawer.DrawShutterGraph(m_ShutterAngle.floatValue);
|
| | | EditorGUILayout.PropertyField(m_ShutterAngle);
|
| | | EditorGUILayout.PropertyField(m_SampleCount);
|
| | | EditorGUI.indentLevel--;
|
| | | EditorGUILayout.Space();
|
| | |
|
| | | EditorGUILayout.LabelField("Multiple Frame Blending", EditorStyles.boldLabel);
|
| | | EditorGUI.indentLevel++;
|
| | |
|
| | | float fbValue = m_FrameBlending.floatValue;
|
| | | m_GraphDrawer.DrawBlendingGraph(fbValue);
|
| | | EditorGUILayout.PropertyField(m_FrameBlending);
|
| | |
|
| | | if (fbValue > 0f)
|
| | | EditorGUILayout.HelpBox("Multi-Frame Blending lowers precision of the final picture for optimization purposes.", MessageType.Info);
|
| | |
|
| | |
|
| | | EditorGUI.indentLevel--;
|
| | | }
|
| | | }
|
| | | }
|