diff --git a/com.unity.shadergraph/CHANGELOG.md b/com.unity.shadergraph/CHANGELOG.md index cbc0eb9b6c4..fca95cb4101 100644 --- a/com.unity.shadergraph/CHANGELOG.md +++ b/com.unity.shadergraph/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Added subshadergraphs for SpeedTree 8 shadergraph support: SpeedTree8Wind, SpeedTree8ColorAlpha, SpeedTree8Billboard. - Added an HLSL file implementing a version of the Unity core LODDitheringTransition function which can be used in a Shader Graph\ - Added View Vector Node doc +- Added a ShaderGraph animated preview framerate throttle. ### Changed - Only ShaderGraph keywords count towards the shader permutation variant limit, SubGraph keywords do not. diff --git a/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs b/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs index dc6c4d689fa..928364752b3 100644 --- a/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs +++ b/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs @@ -37,6 +37,8 @@ class PreviewManager : IDisposable HashSet m_PreviewsToDraw = new HashSet(); // previews to re-render the texture (either because shader compile changed or property changed) HashSet m_TimedPreviews = new HashSet(); // previews that are dependent on a time node -- i.e. animated / need to redraw every frame + double m_LastTimedUpdateTime = 0.0f; + bool m_TopologyDirty; // indicates topology changed, used to rebuild timed node list and preview type (2D/3D) inheritance. HashSet m_MasterNodeTempBlocks = new HashSet(); // temp blocks used by the most recent master node preview generation. @@ -420,8 +422,36 @@ void AssignPerMaterialPreviewProperties(Material mat, List perM } } + bool TimedNodesShouldUpdate(EditorWindow editorWindow) + { + // get current screen FPS, clamp to what we consider a valid range + // this is probably not accurate for multi-monitor.. but should be relevant to at least one of the monitors + double monitorFPS = Screen.currentResolution.refreshRate + 1.0; // +1 to round up, since it is an integer and rounded down + if (Double.IsInfinity(monitorFPS) || Double.IsNaN(monitorFPS)) + monitorFPS = 60.0f; + monitorFPS = Math.Min(monitorFPS, 144.0); + monitorFPS = Math.Max(monitorFPS, 30.0); + + var curTime = EditorApplication.timeSinceStartup; + var deltaTime = curTime - m_LastTimedUpdateTime; + bool isFocusedWindow = (EditorWindow.focusedWindow == editorWindow); + + // we throttle the update rate, based on whether the window is focused and if unity is active + const double k_AnimatedFPS_WhenNotFocused = 10.0; + const double k_AnimatedFPS_WhenInactive = 2.0; + double maxAnimatedFPS = + (UnityEditorInternal.InternalEditorUtility.isApplicationActive ? + (isFocusedWindow ? monitorFPS : k_AnimatedFPS_WhenNotFocused) : + k_AnimatedFPS_WhenInactive); + + bool update = (deltaTime > (1.0 / maxAnimatedFPS)); + if (update) + m_LastTimedUpdateTime = curTime; + return update; + } + private static readonly ProfilerMarker RenderPreviewsMarker = new ProfilerMarker("RenderPreviews"); - public void RenderPreviews(bool requestShaders = true) + public void RenderPreviews(EditorWindow editorWindow, bool requestShaders = true) { using (RenderPreviewsMarker.Auto()) using (var renderList2D = PooledList.Get()) @@ -445,10 +475,11 @@ public void RenderPreviews(bool requestShaders = true) CollectPreviewProperties(m_NodesPropertyChanged, perMaterialPreviewProperties); m_NodesPropertyChanged.Clear(); - // timed nodes change every frame, so must be drawn + // timed nodes are animated, so they should be updated regularly (but not necessarily on every update) // (m_TimedPreviews has been pre-propagated downstream) // HOWEVER they do not need to collect properties. (the only property changing is time..) - m_PreviewsToDraw.UnionWith(m_TimedPreviews); + if (TimedNodesShouldUpdate(editorWindow)) + m_PreviewsToDraw.UnionWith(m_TimedPreviews); ForEachNodesPreview(nodesToDraw, p => m_PreviewsToDraw.Add(p)); diff --git a/com.unity.shadergraph/Editor/Drawing/PreviewRate.cs b/com.unity.shadergraph/Editor/Drawing/PreviewRate.cs deleted file mode 100644 index 6ffcb3e0a69..00000000000 --- a/com.unity.shadergraph/Editor/Drawing/PreviewRate.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace UnityEditor.ShaderGraph.Drawing -{ - enum PreviewRate - { - Full, - Throttled, - Off - } -} diff --git a/com.unity.shadergraph/Editor/Drawing/PreviewRate.cs.meta b/com.unity.shadergraph/Editor/Drawing/PreviewRate.cs.meta deleted file mode 100644 index d91be546579..00000000000 --- a/com.unity.shadergraph/Editor/Drawing/PreviewRate.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: fa070520993a4b839e705dcd7f22e4d6 -timeCreated: 1506421104 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs b/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs index 64a39258586..0c514099d2a 100644 --- a/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs +++ b/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs @@ -121,7 +121,7 @@ public GraphEditorView(EditorWindow editorWindow, GraphData graph, MessageManage m_Graph = graph; m_MessageManager = messageManager; previewManager = new PreviewManager(graph, messageManager); - previewManager.RenderPreviews(false); + previewManager.RenderPreviews(m_EditorWindow, false); styleSheets.Add(Resources.Load("Styles/GraphEditorView")); @@ -648,7 +648,7 @@ public void HandleGraphChanges(bool wasUndoRedoPerformed) m_ColorManager.UpdateNodeViews(nodeList); } - previewManager.RenderPreviews(); + previewManager.RenderPreviews(m_EditorWindow); m_BlackboardProvider.HandleGraphChanges(wasUndoRedoPerformed); if (wasUndoRedoPerformed || m_InspectorView.DoesInspectorNeedUpdate()) m_InspectorView.Update();