PostProcessDebug.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. namespace UnityEngine.Rendering.PostProcessing
  2. {
  3. /// <summary>
  4. /// This component holds a set of debugging utilities related to post-processing.
  5. /// </summary>
  6. /// <remarks>
  7. /// These utilities can be used at runtime to debug on device.
  8. /// </remarks>
  9. #if UNITY_2018_3_OR_NEWER
  10. [ExecuteAlways]
  11. #else
  12. [ExecuteInEditMode]
  13. #endif
  14. [AddComponentMenu("Rendering/Post-process Debug", 1002)]
  15. public sealed class PostProcessDebug : MonoBehaviour
  16. {
  17. /// <summary>
  18. /// A reference to a <see cref="PostProcessLayer"/> to debug.
  19. /// </summary>
  20. public PostProcessLayer postProcessLayer;
  21. PostProcessLayer m_PreviousPostProcessLayer;
  22. /// <summary>
  23. /// Holds settings for the light meter.
  24. /// </summary>
  25. public bool lightMeter;
  26. /// <summary>
  27. /// Holds settings for the histogram.
  28. /// </summary>
  29. public bool histogram;
  30. /// <summary>
  31. /// Holds settings for the waveform.
  32. /// </summary>
  33. public bool waveform;
  34. /// <summary>
  35. /// Holds settings for the vectorscope.
  36. /// </summary>
  37. public bool vectorscope;
  38. /// <summary>
  39. /// The currently set overlay.
  40. /// </summary>
  41. public DebugOverlay debugOverlay = DebugOverlay.None;
  42. Camera m_CurrentCamera;
  43. CommandBuffer m_CmdAfterEverything;
  44. void OnEnable()
  45. {
  46. m_CmdAfterEverything = new CommandBuffer { name = "Post-processing Debug Overlay" };
  47. #if UNITY_EDITOR
  48. // Update is only called on object change when ExecuteInEditMode is set, but we need it
  49. // to execute on every frame no matter what when not in play mode, so we'll use the
  50. // editor update loop instead...
  51. UnityEditor.EditorApplication.update += UpdateStates;
  52. #endif
  53. }
  54. void OnDisable()
  55. {
  56. #if UNITY_EDITOR
  57. UnityEditor.EditorApplication.update -= UpdateStates;
  58. #endif
  59. if (m_CurrentCamera != null)
  60. m_CurrentCamera.RemoveCommandBuffer(CameraEvent.AfterImageEffects, m_CmdAfterEverything);
  61. m_CurrentCamera = null;
  62. m_PreviousPostProcessLayer = null;
  63. }
  64. #if !UNITY_EDITOR
  65. void Update()
  66. {
  67. UpdateStates();
  68. }
  69. #endif
  70. void Reset()
  71. {
  72. postProcessLayer = GetComponent<PostProcessLayer>();
  73. }
  74. void UpdateStates()
  75. {
  76. if (m_PreviousPostProcessLayer != postProcessLayer)
  77. {
  78. // Remove cmdbuffer from previously set camera
  79. if (m_CurrentCamera != null)
  80. {
  81. m_CurrentCamera.RemoveCommandBuffer(CameraEvent.AfterImageEffects, m_CmdAfterEverything);
  82. m_CurrentCamera = null;
  83. }
  84. m_PreviousPostProcessLayer = postProcessLayer;
  85. // Add cmdbuffer to the currently set camera
  86. if (postProcessLayer != null)
  87. {
  88. m_CurrentCamera = postProcessLayer.GetComponent<Camera>();
  89. m_CurrentCamera.AddCommandBuffer(CameraEvent.AfterImageEffects, m_CmdAfterEverything);
  90. }
  91. }
  92. if (postProcessLayer == null || !postProcessLayer.enabled)
  93. return;
  94. // Monitors
  95. if (lightMeter) postProcessLayer.debugLayer.RequestMonitorPass(MonitorType.LightMeter);
  96. if (histogram) postProcessLayer.debugLayer.RequestMonitorPass(MonitorType.Histogram);
  97. if (waveform) postProcessLayer.debugLayer.RequestMonitorPass(MonitorType.Waveform);
  98. if (vectorscope) postProcessLayer.debugLayer.RequestMonitorPass(MonitorType.Vectorscope);
  99. // Overlay
  100. postProcessLayer.debugLayer.RequestDebugOverlay(debugOverlay);
  101. }
  102. void OnPostRender()
  103. {
  104. m_CmdAfterEverything.Clear();
  105. if (postProcessLayer == null || !postProcessLayer.enabled || !postProcessLayer.debugLayer.debugOverlayActive)
  106. return;
  107. m_CmdAfterEverything.Blit(postProcessLayer.debugLayer.debugOverlayTarget, BuiltinRenderTextureType.CameraTarget);
  108. }
  109. void OnGUI()
  110. {
  111. if (postProcessLayer == null || !postProcessLayer.enabled)
  112. return;
  113. // Some SRPs don't unbind render targets and leave them as-is
  114. RenderTexture.active = null;
  115. var rect = new Rect(5, 5, 0, 0);
  116. var debugLayer = postProcessLayer.debugLayer;
  117. DrawMonitor(ref rect, debugLayer.lightMeter, lightMeter);
  118. DrawMonitor(ref rect, debugLayer.histogram, histogram);
  119. DrawMonitor(ref rect, debugLayer.waveform, waveform);
  120. DrawMonitor(ref rect, debugLayer.vectorscope, vectorscope);
  121. }
  122. void DrawMonitor(ref Rect rect, Monitor monitor, bool enabled)
  123. {
  124. if (!enabled || monitor.output == null)
  125. return;
  126. rect.width = monitor.output.width;
  127. rect.height = monitor.output.height;
  128. GUI.DrawTexture(rect, monitor.output);
  129. rect.x += monitor.output.width + 5f;
  130. }
  131. }
  132. }