Skip to content
This repository was archived by the owner on Nov 30, 2020. It is now read-only.

Commit 2d81752

Browse files
committed
Added runtime monitors and simple debug GUI component
Light meter, gamma histogram, waveform, vectorscope
1 parent 1ab2334 commit 2d81752

37 files changed

+1105
-217
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
using UnityEngine;
2+
using UnityEngine.Rendering.PostProcessing;
3+
4+
namespace UnityEditor.Rendering.PostProcessing
5+
{
6+
[CustomEditor(typeof(PostProcessDebug))]
7+
public sealed class PostProcessDebugEditor : BaseEditor<PostProcessDebug>
8+
{
9+
SerializedProperty m_PostProcessLayer;
10+
11+
SerializedObject m_Monitors;
12+
SerializedProperty m_LightMeterEnabled;
13+
SerializedProperty m_LightMeterShowCurves;
14+
SerializedProperty m_HistogramEnabled;
15+
SerializedProperty m_HistogramChannel;
16+
SerializedProperty m_WaveformEnabled;
17+
SerializedProperty m_WaveformExposure;
18+
SerializedProperty m_VectorscopeEnabled;
19+
SerializedProperty m_VectorscopeExposure;
20+
21+
void OnEnable()
22+
{
23+
m_PostProcessLayer = FindProperty(x => x.postProcessLayer);
24+
25+
if (m_PostProcessLayer.objectReferenceValue != null)
26+
RebuildProperties();
27+
}
28+
29+
void RebuildProperties()
30+
{
31+
if (m_PostProcessLayer.objectReferenceValue == null)
32+
return;
33+
34+
m_Monitors = new SerializedObject(m_Target.postProcessLayer);
35+
36+
m_LightMeterEnabled = m_Monitors.FindProperty("monitors.lightMeter.enabled");
37+
m_LightMeterShowCurves = m_Monitors.FindProperty("monitors.lightMeter.showCurves");
38+
39+
m_HistogramEnabled = m_Monitors.FindProperty("monitors.histogram.enabled");
40+
m_HistogramChannel = m_Monitors.FindProperty("monitors.histogram.channel");
41+
42+
m_WaveformEnabled = m_Monitors.FindProperty("monitors.waveform.enabled");
43+
m_WaveformExposure = m_Monitors.FindProperty("monitors.waveform.exposure");
44+
45+
m_VectorscopeEnabled = m_Monitors.FindProperty("monitors.vectorscope.enabled");
46+
m_VectorscopeExposure = m_Monitors.FindProperty("monitors.vectorscope.exposure");
47+
}
48+
49+
public override void OnInspectorGUI()
50+
{
51+
serializedObject.Update();
52+
53+
using (var changed = new EditorGUI.ChangeCheckScope())
54+
{
55+
EditorGUILayout.PropertyField(m_PostProcessLayer);
56+
57+
if (changed.changed)
58+
RebuildProperties();
59+
}
60+
61+
serializedObject.ApplyModifiedProperties();
62+
63+
if (m_PostProcessLayer.objectReferenceValue == null)
64+
return;
65+
66+
EditorGUILayout.Space();
67+
68+
m_Monitors.Update();
69+
70+
DoMonitorGUI(EditorUtilities.GetContent("Light Meter"), m_LightMeterEnabled, m_LightMeterShowCurves);
71+
DoMonitorGUI(EditorUtilities.GetContent("Histogram"), m_HistogramEnabled, m_HistogramChannel);
72+
DoMonitorGUI(EditorUtilities.GetContent("Waveform"), m_WaveformEnabled, m_WaveformExposure);
73+
DoMonitorGUI(EditorUtilities.GetContent("Vectoscope"), m_VectorscopeEnabled, m_VectorscopeExposure);
74+
75+
m_Monitors.ApplyModifiedProperties();
76+
}
77+
78+
void DoMonitorGUI(GUIContent content, SerializedProperty prop, params SerializedProperty[] settings)
79+
{
80+
EditorGUILayout.PropertyField(prop, content);
81+
82+
if (settings == null || settings.Length == 0)
83+
return;
84+
85+
if (prop.boolValue)
86+
{
87+
EditorGUI.indentLevel++;
88+
foreach (var p in settings)
89+
EditorGUILayout.PropertyField(p);
90+
EditorGUI.indentLevel--;
91+
EditorGUILayout.Space();
92+
}
93+
}
94+
}
95+
}

PostProcessing/Runtime/PostProcessDebugView.cs.meta renamed to PostProcessing/Editor/PostProcessDebugEditor.cs.meta

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

PostProcessing/Editor/PostProcessLayerEditor.cs

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,7 @@ public sealed class PostProcessLayerEditor : BaseEditor<PostProcessLayer>
3232

3333
SerializedProperty m_FogEnabled;
3434
SerializedProperty m_FogExcludeSkybox;
35-
36-
SerializedProperty m_DebugDisplay;
37-
SerializedProperty m_DebugMonitor;
38-
SerializedProperty m_DebugLightMeter;
3935

40-
SerializedProperty m_ShowDebugLayer;
4136
SerializedProperty m_ShowToolkit;
4237
SerializedProperty m_ShowCustomSorter;
4338

@@ -80,11 +75,6 @@ void OnEnable()
8075
m_FogEnabled = FindProperty(x => x.fog.enabled);
8176
m_FogExcludeSkybox = FindProperty(x => x.fog.excludeSkybox);
8277

83-
m_DebugDisplay = FindProperty(x => x.debugView.display);
84-
m_DebugMonitor = FindProperty(x => x.debugView.monitor);
85-
m_DebugLightMeter = FindProperty(x => x.debugView.lightMeter);
86-
87-
m_ShowDebugLayer = serializedObject.FindProperty("m_ShowDebugLayer");
8878
m_ShowToolkit = serializedObject.FindProperty("m_ShowToolkit");
8979
m_ShowCustomSorter = serializedObject.FindProperty("m_ShowCustomSorter");
9080

@@ -138,7 +128,6 @@ public override void OnInspectorGUI()
138128
DoAntialiasing();
139129
DoAmbientOcclusion(camera);
140130
DoFog(camera);
141-
DoDebugLayer();
142131
DoToolkit();
143132
DoCustomEffectSorter();
144133

@@ -263,36 +252,6 @@ void DoFog(Camera camera)
263252
EditorGUILayout.Space();
264253
}
265254

266-
void DoDebugLayer()
267-
{
268-
EditorUtilities.DrawSplitter();
269-
m_ShowDebugLayer.boolValue = EditorUtilities.DrawHeader("Debug Layer", m_ShowDebugLayer.boolValue);
270-
271-
if (m_ShowDebugLayer.boolValue)
272-
{
273-
GUILayout.Space(2);
274-
275-
EditorGUI.indentLevel++;
276-
{
277-
EditorGUILayout.PropertyField(m_DebugDisplay, EditorUtilities.GetContent("Display|Toggle visibility of the debug layer on & off in the Game View."));
278-
279-
using (new EditorGUI.DisabledScope(!m_DebugDisplay.boolValue))
280-
{
281-
EditorGUILayout.PropertyField(m_DebugMonitor, EditorUtilities.GetContent("Monitor|The real-time monitor to display on the debug layer."));
282-
EditorGUILayout.PropertyField(m_DebugLightMeter, EditorUtilities.GetContent("HDR Light Meter|Light metering utility used to setup auto exposure. Note that it will only display correct values when using a full-HDR workflow (HDR camera, HDR/Custom color grading)."));
283-
}
284-
285-
if (!SystemInfo.supportsComputeShaders)
286-
EditorGUILayout.HelpBox("The debug layer only works on compute-shader enabled platforms.", MessageType.Warning);
287-
288-
EditorGUILayout.HelpBox("This feature is still a work in progress.", MessageType.Info);
289-
}
290-
EditorGUI.indentLevel--;
291-
292-
GUILayout.Space(3);
293-
}
294-
}
295-
296255
void DoToolkit()
297256
{
298257
EditorUtilities.DrawSplitter();
@@ -389,7 +348,7 @@ void ExportFrameToExr(ExportMode mode)
389348
var h = camera.pixelHeight;
390349

391350
var texOut = new Texture2D(w, h, TextureFormat.RGBAFloat, false, true);
392-
var target = RenderTexture.GetTemporary(w, h, 24, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear, 1);
351+
var target = RenderTexture.GetTemporary(w, h, 24, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear);
393352

394353
var lastActive = RenderTexture.active;
395354
var lastTargetSet = camera.targetTexture;
664 Bytes
Binary file not shown.

PostProcessing/Runtime/Monitors.meta

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
using System;
2+
3+
namespace UnityEngine.Rendering.PostProcessing
4+
{
5+
[Serializable]
6+
public sealed class HistogramMonitor : Monitor
7+
{
8+
public enum Channel
9+
{
10+
Red,
11+
Green,
12+
Blue,
13+
Master
14+
}
15+
16+
public int width = 512;
17+
public int height = 256;
18+
public Channel channel = Channel.Master;
19+
20+
ComputeBuffer m_Data;
21+
const int k_Bins = 256;
22+
const int k_ThreadGroupSize = 16;
23+
24+
internal override void OnDisable()
25+
{
26+
base.OnDisable();
27+
28+
if (m_Data != null)
29+
m_Data.Release();
30+
31+
m_Data = null;
32+
}
33+
34+
internal override void Render(PostProcessRenderContext context)
35+
{
36+
CheckOutput(width, height);
37+
38+
if (m_Data == null)
39+
m_Data = new ComputeBuffer(k_Bins, sizeof(uint));
40+
41+
var compute = context.resources.computeShaders.gammaHistogram;
42+
var cmd = context.command;
43+
cmd.BeginSample("GammaHistogram");
44+
45+
// Clear the buffer on every frame as we use it to accumulate values on every frame
46+
int kernel = compute.FindKernel("KHistogramClear");
47+
cmd.SetComputeBufferParam(compute, kernel, "_HistogramBuffer", m_Data);
48+
cmd.DispatchCompute(compute, kernel, Mathf.CeilToInt(k_Bins / (float)k_ThreadGroupSize), 1, 1);
49+
50+
// Gather all pixels and fill in our histogram
51+
kernel = compute.FindKernel("KHistogramGather");
52+
var parameters = new Vector4(
53+
context.width / 2,
54+
context.height / 2,
55+
RuntimeUtilities.isLinearColorSpace ? 1 : 0,
56+
(int)channel
57+
);
58+
59+
cmd.SetComputeVectorParam(compute, "_Params", parameters);
60+
cmd.SetComputeTextureParam(compute, kernel, "_Source", ShaderIDs.HalfResFinalCopy);
61+
cmd.SetComputeBufferParam(compute, kernel, "_HistogramBuffer", m_Data);
62+
cmd.DispatchCompute(compute, kernel,
63+
Mathf.CeilToInt(parameters.x / k_ThreadGroupSize),
64+
Mathf.CeilToInt(parameters.y / k_ThreadGroupSize),
65+
1
66+
);
67+
68+
// Generate the histogram texture
69+
var sheet = context.propertySheets.Get(context.resources.shaders.gammaHistogram);
70+
sheet.properties.SetVector(ShaderIDs.Params, new Vector4(width, height, 0f, 0f));
71+
sheet.properties.SetBuffer(ShaderIDs.HistogramBuffer, m_Data);
72+
cmd.BlitFullscreenTriangle(BuiltinRenderTextureType.None, output, sheet, 0);
73+
74+
cmd.EndSample("GammaHistogram");
75+
}
76+
}
77+
}

PostProcessing/Runtime/Monitors/HistogramMonitor.cs.meta

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using System;
2+
3+
namespace UnityEngine.Rendering.PostProcessing
4+
{
5+
[Serializable]
6+
public sealed class LightMeterMonitor : Monitor
7+
{
8+
public int width = 512;
9+
public int height = 256;
10+
11+
// Note: only works with HDR grading, as this monitor only makes sense when working in HDR
12+
public bool showCurves = true;
13+
14+
internal override void Render(PostProcessRenderContext context)
15+
{
16+
CheckOutput(width, height);
17+
18+
var histogram = context.logHistogram;
19+
20+
var sheet = context.propertySheets.Get(context.resources.shaders.lightMeter);
21+
sheet.ClearKeywords();
22+
sheet.properties.SetBuffer(ShaderIDs.HistogramBuffer, histogram.data);
23+
24+
var scaleOffsetRes = histogram.GetHistogramScaleOffsetRes(context);
25+
scaleOffsetRes.z = 1f / width;
26+
scaleOffsetRes.w = 1f / height;
27+
28+
sheet.properties.SetVector(ShaderIDs.ScaleOffsetRes, scaleOffsetRes);
29+
30+
if (context.logLut != null && showCurves)
31+
{
32+
sheet.EnableKeyword("COLOR_GRADING_HDR");
33+
sheet.properties.SetTexture(ShaderIDs.Lut3D, context.logLut);
34+
}
35+
36+
var autoExpo = context.autoExposure;
37+
if (autoExpo != null)
38+
{
39+
// Make sure filtering values are correct to avoid apocalyptic consequences
40+
float lowPercent = autoExpo.filtering.value.x;
41+
float highPercent = autoExpo.filtering.value.y;
42+
const float kMinDelta = 1e-2f;
43+
highPercent = Mathf.Clamp(highPercent, 1f + kMinDelta, 99f);
44+
lowPercent = Mathf.Clamp(lowPercent, 1f, highPercent - kMinDelta);
45+
46+
var parameters = new Vector4(
47+
lowPercent * 0.01f,
48+
highPercent * 0.01f,
49+
RuntimeUtilities.Exp2(autoExpo.minLuminance.value),
50+
RuntimeUtilities.Exp2(autoExpo.maxLuminance.value)
51+
);
52+
53+
sheet.EnableKeyword("AUTO_EXPOSURE");
54+
sheet.properties.SetVector(ShaderIDs.Params, parameters);
55+
}
56+
57+
var cmd = context.command;
58+
cmd.BeginSample("LightMeter");
59+
cmd.BlitFullscreenTriangle(BuiltinRenderTextureType.None, output, sheet, 0);
60+
cmd.EndSample("LightMeter");
61+
}
62+
}
63+
}

PostProcessing/Runtime/Monitors/LightMeterMonitor.cs.meta

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)