111
This commit is contained in:
338
Assets/ThirdParty/PostProcessing/Editor/Monitors/HistogramMonitor.cs
vendored
Normal file
338
Assets/ThirdParty/PostProcessing/Editor/Monitors/HistogramMonitor.cs
vendored
Normal file
@@ -0,0 +1,338 @@
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.PostProcessing;
|
||||
|
||||
namespace UnityEditor.PostProcessing
|
||||
{
|
||||
using HistogramMode = PostProcessingProfile.MonitorSettings.HistogramMode;
|
||||
|
||||
public class HistogramMonitor : PostProcessingMonitor
|
||||
{
|
||||
static GUIContent s_MonitorTitle = new GUIContent("Histogram");
|
||||
|
||||
ComputeShader m_ComputeShader;
|
||||
ComputeBuffer m_Buffer;
|
||||
Material m_Material;
|
||||
RenderTexture m_HistogramTexture;
|
||||
Rect m_MonitorAreaRect;
|
||||
|
||||
public HistogramMonitor()
|
||||
{
|
||||
m_ComputeShader = EditorResources.Load<ComputeShader>("Monitors/HistogramCompute.compute");
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
GraphicsUtils.Destroy(m_Material);
|
||||
GraphicsUtils.Destroy(m_HistogramTexture);
|
||||
|
||||
if (m_Buffer != null)
|
||||
m_Buffer.Release();
|
||||
|
||||
m_Material = null;
|
||||
m_HistogramTexture = null;
|
||||
m_Buffer = null;
|
||||
}
|
||||
|
||||
public override bool IsSupported()
|
||||
{
|
||||
return m_ComputeShader != null && GraphicsUtils.supportsDX11;
|
||||
}
|
||||
|
||||
public override GUIContent GetMonitorTitle()
|
||||
{
|
||||
return s_MonitorTitle;
|
||||
}
|
||||
|
||||
public override void OnMonitorSettings()
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
bool refreshOnPlay = m_MonitorSettings.refreshOnPlay;
|
||||
var mode = m_MonitorSettings.histogramMode;
|
||||
|
||||
refreshOnPlay = GUILayout.Toggle(refreshOnPlay, new GUIContent(FxStyles.playIcon, "Keep refreshing the histogram in play mode; this may impact performances."), FxStyles.preButton);
|
||||
mode = (HistogramMode)EditorGUILayout.EnumPopup(mode, FxStyles.preDropdown, GUILayout.MaxWidth(100f));
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(m_BaseEditor.serializedObject.targetObject, "Histogram Settings Changed");
|
||||
m_MonitorSettings.refreshOnPlay = refreshOnPlay;
|
||||
m_MonitorSettings.histogramMode = mode;
|
||||
InternalEditorUtility.RepaintAllViews();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnMonitorGUI(Rect r)
|
||||
{
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
// If m_MonitorAreaRect isn't set the preview was just opened so refresh the render to get the histogram data
|
||||
if (Mathf.Approximately(m_MonitorAreaRect.width, 0) && Mathf.Approximately(m_MonitorAreaRect.height, 0))
|
||||
InternalEditorUtility.RepaintAllViews();
|
||||
|
||||
// Sizing
|
||||
float width = m_HistogramTexture != null
|
||||
? Mathf.Min(m_HistogramTexture.width, r.width - 65f)
|
||||
: r.width;
|
||||
float height = m_HistogramTexture != null
|
||||
? Mathf.Min(m_HistogramTexture.height, r.height - 45f)
|
||||
: r.height;
|
||||
|
||||
m_MonitorAreaRect = new Rect(
|
||||
Mathf.Floor(r.x + r.width / 2f - width / 2f),
|
||||
Mathf.Floor(r.y + r.height / 2f - height / 2f - 5f),
|
||||
width, height
|
||||
);
|
||||
|
||||
if (m_HistogramTexture != null)
|
||||
{
|
||||
Graphics.DrawTexture(m_MonitorAreaRect, m_HistogramTexture);
|
||||
|
||||
var color = Color.white;
|
||||
const float kTickSize = 5f;
|
||||
|
||||
// Rect, lines & ticks points
|
||||
if (m_MonitorSettings.histogramMode == HistogramMode.RGBSplit)
|
||||
{
|
||||
// A B C D E
|
||||
// N F
|
||||
// M G
|
||||
// L K J I H
|
||||
|
||||
var A = new Vector3(m_MonitorAreaRect.x - 1f, m_MonitorAreaRect.y - 1f);
|
||||
var E = new Vector3(A.x + m_MonitorAreaRect.width + 2f, m_MonitorAreaRect.y - 1f);
|
||||
var H = new Vector3(E.x, E.y + m_MonitorAreaRect.height + 2f);
|
||||
var L = new Vector3(A.x, H.y);
|
||||
|
||||
var N = new Vector3(A.x, A.y + (L.y - A.y) / 3f);
|
||||
var M = new Vector3(A.x, A.y + (L.y - A.y) * 2f / 3f);
|
||||
var F = new Vector3(E.x, E.y + (H.y - E.y) / 3f);
|
||||
var G = new Vector3(E.x, E.y + (H.y - E.y) * 2f / 3f);
|
||||
|
||||
var C = new Vector3(A.x + (E.x - A.x) / 2f, A.y);
|
||||
var J = new Vector3(L.x + (H.x - L.x) / 2f, L.y);
|
||||
|
||||
var B = new Vector3(A.x + (C.x - A.x) / 2f, A.y);
|
||||
var D = new Vector3(C.x + (E.x - C.x) / 2f, C.y);
|
||||
var I = new Vector3(J.x + (H.x - J.x) / 2f, J.y);
|
||||
var K = new Vector3(L.x + (J.x - L.x) / 2f, L.y);
|
||||
|
||||
// Borders
|
||||
Handles.color = color;
|
||||
Handles.DrawLine(A, E);
|
||||
Handles.DrawLine(E, H);
|
||||
Handles.DrawLine(H, L);
|
||||
Handles.DrawLine(L, new Vector3(A.x, A.y - 1f));
|
||||
|
||||
// Vertical ticks
|
||||
Handles.DrawLine(A, new Vector3(A.x - kTickSize, A.y));
|
||||
Handles.DrawLine(N, new Vector3(N.x - kTickSize, N.y));
|
||||
Handles.DrawLine(M, new Vector3(M.x - kTickSize, M.y));
|
||||
Handles.DrawLine(L, new Vector3(L.x - kTickSize, L.y));
|
||||
|
||||
Handles.DrawLine(E, new Vector3(E.x + kTickSize, E.y));
|
||||
Handles.DrawLine(F, new Vector3(F.x + kTickSize, F.y));
|
||||
Handles.DrawLine(G, new Vector3(G.x + kTickSize, G.y));
|
||||
Handles.DrawLine(H, new Vector3(H.x + kTickSize, H.y));
|
||||
|
||||
// Horizontal ticks
|
||||
Handles.DrawLine(A, new Vector3(A.x, A.y - kTickSize));
|
||||
Handles.DrawLine(B, new Vector3(B.x, B.y - kTickSize));
|
||||
Handles.DrawLine(C, new Vector3(C.x, C.y - kTickSize));
|
||||
Handles.DrawLine(D, new Vector3(D.x, D.y - kTickSize));
|
||||
Handles.DrawLine(E, new Vector3(E.x, E.y - kTickSize));
|
||||
|
||||
Handles.DrawLine(L, new Vector3(L.x, L.y + kTickSize));
|
||||
Handles.DrawLine(K, new Vector3(K.x, K.y + kTickSize));
|
||||
Handles.DrawLine(J, new Vector3(J.x, J.y + kTickSize));
|
||||
Handles.DrawLine(I, new Vector3(I.x, I.y + kTickSize));
|
||||
Handles.DrawLine(H, new Vector3(H.x, H.y + kTickSize));
|
||||
|
||||
// Separators
|
||||
Handles.DrawLine(N, F);
|
||||
Handles.DrawLine(M, G);
|
||||
|
||||
// Labels
|
||||
GUI.color = color;
|
||||
GUI.Label(new Rect(L.x - 15f, L.y + kTickSize - 4f, 30f, 30f), "0.0", FxStyles.tickStyleCenter);
|
||||
GUI.Label(new Rect(J.x - 15f, J.y + kTickSize - 4f, 30f, 30f), "0.5", FxStyles.tickStyleCenter);
|
||||
GUI.Label(new Rect(H.x - 15f, H.y + kTickSize - 4f, 30f, 30f), "1.0", FxStyles.tickStyleCenter);
|
||||
}
|
||||
else
|
||||
{
|
||||
// A B C D E
|
||||
// P F
|
||||
// O G
|
||||
// N H
|
||||
// M L K J I
|
||||
|
||||
var A = new Vector3(m_MonitorAreaRect.x, m_MonitorAreaRect.y);
|
||||
var E = new Vector3(A.x + m_MonitorAreaRect.width + 1f, m_MonitorAreaRect.y);
|
||||
var I = new Vector3(E.x, E.y + m_MonitorAreaRect.height + 1f);
|
||||
var M = new Vector3(A.x, I.y);
|
||||
|
||||
var C = new Vector3(A.x + (E.x - A.x) / 2f, A.y);
|
||||
var G = new Vector3(E.x, E.y + (I.y - E.y) / 2f);
|
||||
var K = new Vector3(M.x + (I.x - M.x) / 2f, M.y);
|
||||
var O = new Vector3(A.x, A.y + (M.y - A.y) / 2f);
|
||||
|
||||
var P = new Vector3(A.x, A.y + (O.y - A.y) / 2f);
|
||||
var F = new Vector3(E.x, E.y + (G.y - E.y) / 2f);
|
||||
var N = new Vector3(A.x, O.y + (M.y - O.y) / 2f);
|
||||
var H = new Vector3(E.x, G.y + (I.y - G.y) / 2f);
|
||||
|
||||
var B = new Vector3(A.x + (C.x - A.x) / 2f, A.y);
|
||||
var L = new Vector3(M.x + (K.x - M.x) / 2f, M.y);
|
||||
var D = new Vector3(C.x + (E.x - C.x) / 2f, A.y);
|
||||
var J = new Vector3(K.x + (I.x - K.x) / 2f, M.y);
|
||||
|
||||
// Borders
|
||||
Handles.color = color;
|
||||
Handles.DrawLine(A, E);
|
||||
Handles.DrawLine(E, I);
|
||||
Handles.DrawLine(I, M);
|
||||
Handles.DrawLine(M, new Vector3(A.x, A.y - 1f));
|
||||
|
||||
// Vertical ticks
|
||||
Handles.DrawLine(A, new Vector3(A.x - kTickSize, A.y));
|
||||
Handles.DrawLine(P, new Vector3(P.x - kTickSize, P.y));
|
||||
Handles.DrawLine(O, new Vector3(O.x - kTickSize, O.y));
|
||||
Handles.DrawLine(N, new Vector3(N.x - kTickSize, N.y));
|
||||
Handles.DrawLine(M, new Vector3(M.x - kTickSize, M.y));
|
||||
|
||||
Handles.DrawLine(E, new Vector3(E.x + kTickSize, E.y));
|
||||
Handles.DrawLine(F, new Vector3(F.x + kTickSize, F.y));
|
||||
Handles.DrawLine(G, new Vector3(G.x + kTickSize, G.y));
|
||||
Handles.DrawLine(H, new Vector3(H.x + kTickSize, H.y));
|
||||
Handles.DrawLine(I, new Vector3(I.x + kTickSize, I.y));
|
||||
|
||||
// Horizontal ticks
|
||||
Handles.DrawLine(A, new Vector3(A.x, A.y - kTickSize));
|
||||
Handles.DrawLine(B, new Vector3(B.x, B.y - kTickSize));
|
||||
Handles.DrawLine(C, new Vector3(C.x, C.y - kTickSize));
|
||||
Handles.DrawLine(D, new Vector3(D.x, D.y - kTickSize));
|
||||
Handles.DrawLine(E, new Vector3(E.x, E.y - kTickSize));
|
||||
|
||||
Handles.DrawLine(M, new Vector3(M.x, M.y + kTickSize));
|
||||
Handles.DrawLine(L, new Vector3(L.x, L.y + kTickSize));
|
||||
Handles.DrawLine(K, new Vector3(K.x, K.y + kTickSize));
|
||||
Handles.DrawLine(J, new Vector3(J.x, J.y + kTickSize));
|
||||
Handles.DrawLine(I, new Vector3(I.x, I.y + kTickSize));
|
||||
|
||||
// Labels
|
||||
GUI.color = color;
|
||||
GUI.Label(new Rect(A.x - kTickSize - 34f, A.y - 15f, 30f, 30f), "1.0", FxStyles.tickStyleRight);
|
||||
GUI.Label(new Rect(O.x - kTickSize - 34f, O.y - 15f, 30f, 30f), "0.5", FxStyles.tickStyleRight);
|
||||
GUI.Label(new Rect(M.x - kTickSize - 34f, M.y - 15f, 30f, 30f), "0.0", FxStyles.tickStyleRight);
|
||||
|
||||
GUI.Label(new Rect(E.x + kTickSize + 4f, E.y - 15f, 30f, 30f), "1.0", FxStyles.tickStyleLeft);
|
||||
GUI.Label(new Rect(G.x + kTickSize + 4f, G.y - 15f, 30f, 30f), "0.5", FxStyles.tickStyleLeft);
|
||||
GUI.Label(new Rect(I.x + kTickSize + 4f, I.y - 15f, 30f, 30f), "0.0", FxStyles.tickStyleLeft);
|
||||
|
||||
GUI.Label(new Rect(M.x - 15f, M.y + kTickSize - 4f, 30f, 30f), "0.0", FxStyles.tickStyleCenter);
|
||||
GUI.Label(new Rect(K.x - 15f, K.y + kTickSize - 4f, 30f, 30f), "0.5", FxStyles.tickStyleCenter);
|
||||
GUI.Label(new Rect(I.x - 15f, I.y + kTickSize - 4f, 30f, 30f), "1.0", FxStyles.tickStyleCenter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnFrameData(RenderTexture source)
|
||||
{
|
||||
if (Application.isPlaying && !m_MonitorSettings.refreshOnPlay)
|
||||
return;
|
||||
|
||||
if (Mathf.Approximately(m_MonitorAreaRect.width, 0) || Mathf.Approximately(m_MonitorAreaRect.height, 0))
|
||||
return;
|
||||
|
||||
float ratio = (float)source.width / (float)source.height;
|
||||
int h = 512;
|
||||
int w = Mathf.FloorToInt(h * ratio);
|
||||
|
||||
var rt = RenderTexture.GetTemporary(w, h, 0, source.format);
|
||||
Graphics.Blit(source, rt);
|
||||
ComputeHistogram(rt);
|
||||
m_BaseEditor.Repaint();
|
||||
RenderTexture.ReleaseTemporary(rt);
|
||||
}
|
||||
|
||||
void CreateBuffer(int width, int height)
|
||||
{
|
||||
m_Buffer = new ComputeBuffer(width * height, sizeof(uint) << 2);
|
||||
}
|
||||
|
||||
void ComputeHistogram(RenderTexture source)
|
||||
{
|
||||
if (m_Buffer == null)
|
||||
{
|
||||
CreateBuffer(256, 1);
|
||||
}
|
||||
else if (m_Buffer.count != 256)
|
||||
{
|
||||
m_Buffer.Release();
|
||||
CreateBuffer(256, 1);
|
||||
}
|
||||
|
||||
if (m_Material == null)
|
||||
{
|
||||
m_Material = new Material(Shader.Find("Hidden/Post FX/Monitors/Histogram Render")) { hideFlags = HideFlags.DontSave };
|
||||
}
|
||||
|
||||
var channels = Vector4.zero;
|
||||
switch (m_MonitorSettings.histogramMode)
|
||||
{
|
||||
case HistogramMode.Red: channels.x = 1f; break;
|
||||
case HistogramMode.Green: channels.y = 1f; break;
|
||||
case HistogramMode.Blue: channels.z = 1f; break;
|
||||
case HistogramMode.Luminance: channels.w = 1f; break;
|
||||
default: channels = new Vector4(1f, 1f, 1f, 0f); break;
|
||||
}
|
||||
|
||||
var cs = m_ComputeShader;
|
||||
|
||||
int kernel = cs.FindKernel("KHistogramClear");
|
||||
cs.SetBuffer(kernel, "_Histogram", m_Buffer);
|
||||
cs.Dispatch(kernel, 1, 1, 1);
|
||||
|
||||
kernel = cs.FindKernel("KHistogramGather");
|
||||
cs.SetBuffer(kernel, "_Histogram", m_Buffer);
|
||||
cs.SetTexture(kernel, "_Source", source);
|
||||
cs.SetInt("_IsLinear", GraphicsUtils.isLinearColorSpace ? 1 : 0);
|
||||
cs.SetVector("_Res", new Vector4(source.width, source.height, 0f, 0f));
|
||||
cs.SetVector("_Channels", channels);
|
||||
cs.Dispatch(kernel, Mathf.CeilToInt(source.width / 16f), Mathf.CeilToInt(source.height / 16f), 1);
|
||||
|
||||
kernel = cs.FindKernel("KHistogramScale");
|
||||
cs.SetBuffer(kernel, "_Histogram", m_Buffer);
|
||||
cs.Dispatch(kernel, 1, 1, 1);
|
||||
|
||||
if (m_HistogramTexture == null || m_HistogramTexture.width != source.width || m_HistogramTexture.height != source.height)
|
||||
{
|
||||
GraphicsUtils.Destroy(m_HistogramTexture);
|
||||
m_HistogramTexture = new RenderTexture(source.width, source.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear)
|
||||
{
|
||||
hideFlags = HideFlags.DontSave,
|
||||
wrapMode = TextureWrapMode.Clamp,
|
||||
filterMode = FilterMode.Bilinear
|
||||
};
|
||||
}
|
||||
|
||||
m_Material.SetBuffer("_Histogram", m_Buffer);
|
||||
m_Material.SetVector("_Size", new Vector2(m_HistogramTexture.width, m_HistogramTexture.height));
|
||||
m_Material.SetColor("_ColorR", new Color(1f, 0f, 0f, 1f));
|
||||
m_Material.SetColor("_ColorG", new Color(0f, 1f, 0f, 1f));
|
||||
m_Material.SetColor("_ColorB", new Color(0f, 0f, 1f, 1f));
|
||||
m_Material.SetColor("_ColorL", new Color(1f, 1f, 1f, 1f));
|
||||
m_Material.SetInt("_Channel", (int)m_MonitorSettings.histogramMode);
|
||||
|
||||
int pass = 0;
|
||||
if (m_MonitorSettings.histogramMode == HistogramMode.RGBMerged)
|
||||
pass = 1;
|
||||
else if (m_MonitorSettings.histogramMode == HistogramMode.RGBSplit)
|
||||
pass = 2;
|
||||
|
||||
Graphics.Blit(null, m_HistogramTexture, m_Material, pass);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/ThirdParty/PostProcessing/Editor/Monitors/HistogramMonitor.cs.meta
vendored
Normal file
12
Assets/ThirdParty/PostProcessing/Editor/Monitors/HistogramMonitor.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4581c45ac4aa2264187087659a4cc252
|
||||
timeCreated: 1460031632
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
257
Assets/ThirdParty/PostProcessing/Editor/Monitors/ParadeMonitor.cs
vendored
Normal file
257
Assets/ThirdParty/PostProcessing/Editor/Monitors/ParadeMonitor.cs
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.PostProcessing;
|
||||
|
||||
namespace UnityEditor.PostProcessing
|
||||
{
|
||||
public class ParadeMonitor : PostProcessingMonitor
|
||||
{
|
||||
static GUIContent s_MonitorTitle = new GUIContent("Parade");
|
||||
|
||||
ComputeShader m_ComputeShader;
|
||||
ComputeBuffer m_Buffer;
|
||||
Material m_Material;
|
||||
RenderTexture m_WaveformTexture;
|
||||
Rect m_MonitorAreaRect;
|
||||
|
||||
public ParadeMonitor()
|
||||
{
|
||||
m_ComputeShader = EditorResources.Load<ComputeShader>("Monitors/WaveformCompute.compute");
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
GraphicsUtils.Destroy(m_Material);
|
||||
GraphicsUtils.Destroy(m_WaveformTexture);
|
||||
|
||||
if (m_Buffer != null)
|
||||
m_Buffer.Release();
|
||||
|
||||
m_Material = null;
|
||||
m_WaveformTexture = null;
|
||||
m_Buffer = null;
|
||||
}
|
||||
|
||||
public override bool IsSupported()
|
||||
{
|
||||
return m_ComputeShader != null && GraphicsUtils.supportsDX11;
|
||||
}
|
||||
|
||||
public override GUIContent GetMonitorTitle()
|
||||
{
|
||||
return s_MonitorTitle;
|
||||
}
|
||||
|
||||
public override void OnMonitorSettings()
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
bool refreshOnPlay = m_MonitorSettings.refreshOnPlay;
|
||||
float exposure = m_MonitorSettings.paradeExposure;
|
||||
|
||||
refreshOnPlay = GUILayout.Toggle(refreshOnPlay, new GUIContent(FxStyles.playIcon, "Keep refreshing the parade in play mode; this may impact performances."), FxStyles.preButton);
|
||||
exposure = GUILayout.HorizontalSlider(exposure, 0.05f, 0.3f, FxStyles.preSlider, FxStyles.preSliderThumb, GUILayout.Width(40f));
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(m_BaseEditor.serializedObject.targetObject, "Parade Settings Changed");
|
||||
m_MonitorSettings.refreshOnPlay = refreshOnPlay;
|
||||
m_MonitorSettings.paradeExposure = exposure;
|
||||
InternalEditorUtility.RepaintAllViews();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnMonitorGUI(Rect r)
|
||||
{
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
// If m_MonitorAreaRect isn't set the preview was just opened so refresh the render to get the waveform data
|
||||
if (Mathf.Approximately(m_MonitorAreaRect.width, 0) && Mathf.Approximately(m_MonitorAreaRect.height, 0))
|
||||
InternalEditorUtility.RepaintAllViews();
|
||||
|
||||
// Sizing
|
||||
float width = m_WaveformTexture != null
|
||||
? Mathf.Min(m_WaveformTexture.width, r.width - 65f)
|
||||
: r.width;
|
||||
float height = m_WaveformTexture != null
|
||||
? Mathf.Min(m_WaveformTexture.height, r.height - 45f)
|
||||
: r.height;
|
||||
|
||||
m_MonitorAreaRect = new Rect(
|
||||
Mathf.Floor(r.x + r.width / 2f - width / 2f),
|
||||
Mathf.Floor(r.y + r.height / 2f - height / 2f - 5f),
|
||||
width, height
|
||||
);
|
||||
|
||||
if (m_WaveformTexture != null)
|
||||
{
|
||||
m_Material.SetFloat("_Exposure", m_MonitorSettings.paradeExposure);
|
||||
|
||||
var oldActive = RenderTexture.active;
|
||||
Graphics.Blit(null, m_WaveformTexture, m_Material, 0);
|
||||
RenderTexture.active = oldActive;
|
||||
|
||||
Graphics.DrawTexture(m_MonitorAreaRect, m_WaveformTexture);
|
||||
|
||||
var color = Color.white;
|
||||
const float kTickSize = 5f;
|
||||
|
||||
// Rect, lines & ticks points
|
||||
// A O B P C Q D
|
||||
// N E
|
||||
// M F
|
||||
// L G
|
||||
// K T J S I R H
|
||||
|
||||
var A = new Vector3(m_MonitorAreaRect.x, m_MonitorAreaRect.y);
|
||||
var D = new Vector3(A.x + m_MonitorAreaRect.width + 1f, m_MonitorAreaRect.y);
|
||||
var H = new Vector3(D.x, D.y + m_MonitorAreaRect.height + 1f);
|
||||
var K = new Vector3(A.x, H.y);
|
||||
|
||||
var F = new Vector3(D.x, D.y + (H.y - D.y) / 2f);
|
||||
var M = new Vector3(A.x, A.y + (K.y - A.y) / 2f);
|
||||
|
||||
var B = new Vector3(A.x + (D.x - A.x) / 3f, A.y);
|
||||
var C = new Vector3(A.x + (D.x - A.x) * 2f / 3f, A.y);
|
||||
var I = new Vector3(K.x + (H.x - K.x) * 2f / 3f, K.y);
|
||||
var J = new Vector3(K.x + (H.x - K.x) / 3f, K.y);
|
||||
|
||||
var N = new Vector3(A.x, A.y + (M.y - A.y) / 2f);
|
||||
var L = new Vector3(A.x, M.y + (K.y - M.y) / 2f);
|
||||
var E = new Vector3(D.x, D.y + (F.y - D.y) / 2f);
|
||||
var G = new Vector3(D.x, F.y + (H.y - F.y) / 2f);
|
||||
|
||||
var O = new Vector3(A.x + (B.x - A.x) / 2f, A.y);
|
||||
var P = new Vector3(B.x + (C.x - B.x) / 2f, B.y);
|
||||
var Q = new Vector3(C.x + (D.x - C.x) / 2f, C.y);
|
||||
|
||||
var R = new Vector3(I.x + (H.x - I.x) / 2f, I.y);
|
||||
var S = new Vector3(J.x + (I.x - J.x) / 2f, J.y);
|
||||
var T = new Vector3(K.x + (J.x - K.x) / 2f, K.y);
|
||||
|
||||
// Borders
|
||||
Handles.color = color;
|
||||
Handles.DrawLine(A, D);
|
||||
Handles.DrawLine(D, H);
|
||||
Handles.DrawLine(H, K);
|
||||
Handles.DrawLine(K, new Vector3(A.x, A.y - 1f));
|
||||
|
||||
Handles.DrawLine(B, J);
|
||||
Handles.DrawLine(C, I);
|
||||
|
||||
// Vertical ticks
|
||||
Handles.DrawLine(A, new Vector3(A.x - kTickSize, A.y));
|
||||
Handles.DrawLine(N, new Vector3(N.x - kTickSize, N.y));
|
||||
Handles.DrawLine(M, new Vector3(M.x - kTickSize, M.y));
|
||||
Handles.DrawLine(L, new Vector3(L.x - kTickSize, L.y));
|
||||
Handles.DrawLine(K, new Vector3(K.x - kTickSize, K.y));
|
||||
|
||||
Handles.DrawLine(D, new Vector3(D.x + kTickSize, D.y));
|
||||
Handles.DrawLine(E, new Vector3(E.x + kTickSize, E.y));
|
||||
Handles.DrawLine(F, new Vector3(F.x + kTickSize, F.y));
|
||||
Handles.DrawLine(G, new Vector3(G.x + kTickSize, G.y));
|
||||
Handles.DrawLine(H, new Vector3(H.x + kTickSize, H.y));
|
||||
|
||||
// Horizontal ticks
|
||||
Handles.DrawLine(A, new Vector3(A.x, A.y - kTickSize));
|
||||
Handles.DrawLine(B, new Vector3(B.x, B.y - kTickSize));
|
||||
Handles.DrawLine(C, new Vector3(C.x, C.y - kTickSize));
|
||||
Handles.DrawLine(D, new Vector3(D.x, D.y - kTickSize));
|
||||
Handles.DrawLine(O, new Vector3(O.x, O.y - kTickSize));
|
||||
Handles.DrawLine(P, new Vector3(P.x, P.y - kTickSize));
|
||||
Handles.DrawLine(Q, new Vector3(Q.x, Q.y - kTickSize));
|
||||
|
||||
Handles.DrawLine(H, new Vector3(H.x, H.y + kTickSize));
|
||||
Handles.DrawLine(I, new Vector3(I.x, I.y + kTickSize));
|
||||
Handles.DrawLine(J, new Vector3(J.x, J.y + kTickSize));
|
||||
Handles.DrawLine(K, new Vector3(K.x, K.y + kTickSize));
|
||||
Handles.DrawLine(R, new Vector3(R.x, R.y + kTickSize));
|
||||
Handles.DrawLine(S, new Vector3(S.x, S.y + kTickSize));
|
||||
Handles.DrawLine(T, new Vector3(T.x, T.y + kTickSize));
|
||||
|
||||
// Labels
|
||||
GUI.color = color;
|
||||
GUI.Label(new Rect(A.x - kTickSize - 34f, A.y - 15f, 30f, 30f), "1.0", FxStyles.tickStyleRight);
|
||||
GUI.Label(new Rect(M.x - kTickSize - 34f, M.y - 15f, 30f, 30f), "0.5", FxStyles.tickStyleRight);
|
||||
GUI.Label(new Rect(K.x - kTickSize - 34f, K.y - 15f, 30f, 30f), "0.0", FxStyles.tickStyleRight);
|
||||
|
||||
GUI.Label(new Rect(D.x + kTickSize + 4f, D.y - 15f, 30f, 30f), "1.0", FxStyles.tickStyleLeft);
|
||||
GUI.Label(new Rect(F.x + kTickSize + 4f, F.y - 15f, 30f, 30f), "0.5", FxStyles.tickStyleLeft);
|
||||
GUI.Label(new Rect(H.x + kTickSize + 4f, H.y - 15f, 30f, 30f), "0.0", FxStyles.tickStyleLeft);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnFrameData(RenderTexture source)
|
||||
{
|
||||
if (Application.isPlaying && !m_MonitorSettings.refreshOnPlay)
|
||||
return;
|
||||
|
||||
if (Mathf.Approximately(m_MonitorAreaRect.width, 0) || Mathf.Approximately(m_MonitorAreaRect.height, 0))
|
||||
return;
|
||||
|
||||
float ratio = ((float)source.width / (float)source.height) / 3f;
|
||||
int h = 384;
|
||||
int w = Mathf.FloorToInt(h * ratio);
|
||||
|
||||
var rt = RenderTexture.GetTemporary(w, h, 0, source.format);
|
||||
Graphics.Blit(source, rt);
|
||||
ComputeWaveform(rt);
|
||||
m_BaseEditor.Repaint();
|
||||
RenderTexture.ReleaseTemporary(rt);
|
||||
}
|
||||
|
||||
void CreateBuffer(int width, int height)
|
||||
{
|
||||
m_Buffer = new ComputeBuffer(width * height, sizeof(uint) << 2);
|
||||
}
|
||||
|
||||
void ComputeWaveform(RenderTexture source)
|
||||
{
|
||||
if (m_Buffer == null)
|
||||
{
|
||||
CreateBuffer(source.width, source.height);
|
||||
}
|
||||
else if (m_Buffer.count != (source.width * source.height))
|
||||
{
|
||||
m_Buffer.Release();
|
||||
CreateBuffer(source.width, source.height);
|
||||
}
|
||||
|
||||
var channels = m_MonitorSettings.waveformY
|
||||
? new Vector4(0f, 0f, 0f, 1f)
|
||||
: new Vector4(m_MonitorSettings.waveformR ? 1f : 0f, m_MonitorSettings.waveformG ? 1f : 0f, m_MonitorSettings.waveformB ? 1f : 0f, 0f);
|
||||
|
||||
var cs = m_ComputeShader;
|
||||
|
||||
int kernel = cs.FindKernel("KWaveformClear");
|
||||
cs.SetBuffer(kernel, "_Waveform", m_Buffer);
|
||||
cs.Dispatch(kernel, source.width, 1, 1);
|
||||
|
||||
kernel = cs.FindKernel("KWaveform");
|
||||
cs.SetBuffer(kernel, "_Waveform", m_Buffer);
|
||||
cs.SetTexture(kernel, "_Source", source);
|
||||
cs.SetInt("_IsLinear", GraphicsUtils.isLinearColorSpace ? 1 : 0);
|
||||
cs.SetVector("_Channels", channels);
|
||||
cs.Dispatch(kernel, source.width, 1, 1);
|
||||
|
||||
if (m_WaveformTexture == null || m_WaveformTexture.width != (source.width * 3) || m_WaveformTexture.height != source.height)
|
||||
{
|
||||
GraphicsUtils.Destroy(m_WaveformTexture);
|
||||
m_WaveformTexture = new RenderTexture(source.width * 3, source.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear)
|
||||
{
|
||||
hideFlags = HideFlags.DontSave,
|
||||
wrapMode = TextureWrapMode.Clamp,
|
||||
filterMode = FilterMode.Bilinear
|
||||
};
|
||||
}
|
||||
|
||||
if (m_Material == null)
|
||||
m_Material = new Material(Shader.Find("Hidden/Post FX/Monitors/Parade Render")) { hideFlags = HideFlags.DontSave };
|
||||
|
||||
m_Material.SetBuffer("_Waveform", m_Buffer);
|
||||
m_Material.SetVector("_Size", new Vector2(m_WaveformTexture.width, m_WaveformTexture.height));
|
||||
m_Material.SetVector("_Channels", channels);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/ThirdParty/PostProcessing/Editor/Monitors/ParadeMonitor.cs.meta
vendored
Normal file
12
Assets/ThirdParty/PostProcessing/Editor/Monitors/ParadeMonitor.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1f878f3742072e40a280683573bd0ee
|
||||
timeCreated: 1460031643
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
241
Assets/ThirdParty/PostProcessing/Editor/Monitors/VectorscopeMonitor.cs
vendored
Normal file
241
Assets/ThirdParty/PostProcessing/Editor/Monitors/VectorscopeMonitor.cs
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.PostProcessing;
|
||||
|
||||
namespace UnityEditor.PostProcessing
|
||||
{
|
||||
public class VectorscopeMonitor : PostProcessingMonitor
|
||||
{
|
||||
static GUIContent s_MonitorTitle = new GUIContent("Vectorscope");
|
||||
|
||||
ComputeShader m_ComputeShader;
|
||||
ComputeBuffer m_Buffer;
|
||||
Material m_Material;
|
||||
RenderTexture m_VectorscopeTexture;
|
||||
Rect m_MonitorAreaRect;
|
||||
|
||||
public VectorscopeMonitor()
|
||||
{
|
||||
m_ComputeShader = EditorResources.Load<ComputeShader>("Monitors/VectorscopeCompute.compute");
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
GraphicsUtils.Destroy(m_Material);
|
||||
GraphicsUtils.Destroy(m_VectorscopeTexture);
|
||||
|
||||
if (m_Buffer != null)
|
||||
m_Buffer.Release();
|
||||
|
||||
m_Material = null;
|
||||
m_VectorscopeTexture = null;
|
||||
m_Buffer = null;
|
||||
}
|
||||
|
||||
public override bool IsSupported()
|
||||
{
|
||||
return m_ComputeShader != null && GraphicsUtils.supportsDX11;
|
||||
}
|
||||
|
||||
public override GUIContent GetMonitorTitle()
|
||||
{
|
||||
return s_MonitorTitle;
|
||||
}
|
||||
|
||||
public override void OnMonitorSettings()
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
bool refreshOnPlay = m_MonitorSettings.refreshOnPlay;
|
||||
float exposure = m_MonitorSettings.vectorscopeExposure;
|
||||
bool showBackground = m_MonitorSettings.vectorscopeShowBackground;
|
||||
|
||||
refreshOnPlay = GUILayout.Toggle(refreshOnPlay, new GUIContent(FxStyles.playIcon, "Keep refreshing the vectorscope in play mode; this may impact performances."), FxStyles.preButton);
|
||||
exposure = GUILayout.HorizontalSlider(exposure, 0.05f, 0.3f, FxStyles.preSlider, FxStyles.preSliderThumb, GUILayout.Width(40f));
|
||||
showBackground = GUILayout.Toggle(showBackground, new GUIContent(FxStyles.checkerIcon, "Show an YUV background in the vectorscope."), FxStyles.preButton);
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(m_BaseEditor.serializedObject.targetObject, "Vectorscope Settings Changed");
|
||||
m_MonitorSettings.refreshOnPlay = refreshOnPlay;
|
||||
m_MonitorSettings.vectorscopeExposure = exposure;
|
||||
m_MonitorSettings.vectorscopeShowBackground = showBackground;
|
||||
InternalEditorUtility.RepaintAllViews();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnMonitorGUI(Rect r)
|
||||
{
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
// If m_MonitorAreaRect isn't set the preview was just opened so refresh the render to get the vectoscope data
|
||||
if (Mathf.Approximately(m_MonitorAreaRect.width, 0) && Mathf.Approximately(m_MonitorAreaRect.height, 0))
|
||||
InternalEditorUtility.RepaintAllViews();
|
||||
|
||||
// Sizing
|
||||
float size = 0f;
|
||||
|
||||
if (r.width < r.height)
|
||||
{
|
||||
size = m_VectorscopeTexture != null
|
||||
? Mathf.Min(m_VectorscopeTexture.width, r.width - 35f)
|
||||
: r.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = m_VectorscopeTexture != null
|
||||
? Mathf.Min(m_VectorscopeTexture.height, r.height - 25f)
|
||||
: r.height;
|
||||
}
|
||||
|
||||
m_MonitorAreaRect = new Rect(
|
||||
Mathf.Floor(r.x + r.width / 2f - size / 2f),
|
||||
Mathf.Floor(r.y + r.height / 2f - size / 2f - 5f),
|
||||
size, size
|
||||
);
|
||||
|
||||
if (m_VectorscopeTexture != null)
|
||||
{
|
||||
m_Material.SetFloat("_Exposure", m_MonitorSettings.vectorscopeExposure);
|
||||
|
||||
var oldActive = RenderTexture.active;
|
||||
Graphics.Blit(null, m_VectorscopeTexture, m_Material, m_MonitorSettings.vectorscopeShowBackground ? 0 : 1);
|
||||
RenderTexture.active = oldActive;
|
||||
|
||||
Graphics.DrawTexture(m_MonitorAreaRect, m_VectorscopeTexture);
|
||||
|
||||
var color = Color.white;
|
||||
const float kTickSize = 10f;
|
||||
const int kTickCount = 24;
|
||||
|
||||
float radius = m_MonitorAreaRect.width / 2f;
|
||||
float midX = m_MonitorAreaRect.x + radius;
|
||||
float midY = m_MonitorAreaRect.y + radius;
|
||||
var center = new Vector2(midX, midY);
|
||||
|
||||
// Cross
|
||||
color.a *= 0.5f;
|
||||
Handles.color = color;
|
||||
Handles.DrawLine(new Vector2(midX, m_MonitorAreaRect.y), new Vector2(midX, m_MonitorAreaRect.y + m_MonitorAreaRect.height));
|
||||
Handles.DrawLine(new Vector2(m_MonitorAreaRect.x, midY), new Vector2(m_MonitorAreaRect.x + m_MonitorAreaRect.width, midY));
|
||||
|
||||
if (m_MonitorAreaRect.width > 100f)
|
||||
{
|
||||
color.a = 1f;
|
||||
|
||||
// Ticks
|
||||
Handles.color = color;
|
||||
for (int i = 0; i < kTickCount; i++)
|
||||
{
|
||||
float a = (float)i / (float)kTickCount;
|
||||
float theta = a * (Mathf.PI * 2f);
|
||||
float tx = Mathf.Cos(theta + (Mathf.PI / 2f));
|
||||
float ty = Mathf.Sin(theta - (Mathf.PI / 2f));
|
||||
var innerVec = center + new Vector2(tx, ty) * (radius - kTickSize);
|
||||
var outerVec = center + new Vector2(tx, ty) * radius;
|
||||
Handles.DrawAAPolyLine(3f, innerVec, outerVec);
|
||||
}
|
||||
|
||||
// Labels (where saturation reaches 75%)
|
||||
color.a = 1f;
|
||||
var oldColor = GUI.color;
|
||||
GUI.color = color * 2f;
|
||||
|
||||
var point = new Vector2(-0.254f, -0.750f) * radius + center;
|
||||
var rect = new Rect(point.x - 10f, point.y - 10f, 20f, 20f);
|
||||
GUI.Label(rect, "[R]", FxStyles.tickStyleCenter);
|
||||
|
||||
point = new Vector2(-0.497f, 0.629f) * radius + center;
|
||||
rect = new Rect(point.x - 10f, point.y - 10f, 20f, 20f);
|
||||
GUI.Label(rect, "[G]", FxStyles.tickStyleCenter);
|
||||
|
||||
point = new Vector2(0.750f, 0.122f) * radius + center;
|
||||
rect = new Rect(point.x - 10f, point.y - 10f, 20f, 20f);
|
||||
GUI.Label(rect, "[B]", FxStyles.tickStyleCenter);
|
||||
|
||||
point = new Vector2(-0.750f, -0.122f) * radius + center;
|
||||
rect = new Rect(point.x - 10f, point.y - 10f, 20f, 20f);
|
||||
GUI.Label(rect, "[Y]", FxStyles.tickStyleCenter);
|
||||
|
||||
point = new Vector2(0.254f, 0.750f) * radius + center;
|
||||
rect = new Rect(point.x - 10f, point.y - 10f, 20f, 20f);
|
||||
GUI.Label(rect, "[C]", FxStyles.tickStyleCenter);
|
||||
|
||||
point = new Vector2(0.497f, -0.629f) * radius + center;
|
||||
rect = new Rect(point.x - 10f, point.y - 10f, 20f, 20f);
|
||||
GUI.Label(rect, "[M]", FxStyles.tickStyleCenter);
|
||||
GUI.color = oldColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnFrameData(RenderTexture source)
|
||||
{
|
||||
if (Application.isPlaying && !m_MonitorSettings.refreshOnPlay)
|
||||
return;
|
||||
|
||||
if (Mathf.Approximately(m_MonitorAreaRect.width, 0) || Mathf.Approximately(m_MonitorAreaRect.height, 0))
|
||||
return;
|
||||
|
||||
float ratio = (float)source.width / (float)source.height;
|
||||
int h = 384;
|
||||
int w = Mathf.FloorToInt(h * ratio);
|
||||
|
||||
var rt = RenderTexture.GetTemporary(w, h, 0, source.format);
|
||||
Graphics.Blit(source, rt);
|
||||
ComputeVectorscope(rt);
|
||||
m_BaseEditor.Repaint();
|
||||
RenderTexture.ReleaseTemporary(rt);
|
||||
}
|
||||
|
||||
void CreateBuffer(int width, int height)
|
||||
{
|
||||
m_Buffer = new ComputeBuffer(width * height, sizeof(uint));
|
||||
}
|
||||
|
||||
void ComputeVectorscope(RenderTexture source)
|
||||
{
|
||||
if (m_Buffer == null)
|
||||
{
|
||||
CreateBuffer(source.width, source.height);
|
||||
}
|
||||
else if (m_Buffer.count != (source.width * source.height))
|
||||
{
|
||||
m_Buffer.Release();
|
||||
CreateBuffer(source.width, source.height);
|
||||
}
|
||||
|
||||
var cs = m_ComputeShader;
|
||||
|
||||
int kernel = cs.FindKernel("KVectorscopeClear");
|
||||
cs.SetBuffer(kernel, "_Vectorscope", m_Buffer);
|
||||
cs.SetVector("_Res", new Vector4(source.width, source.height, 0f, 0f));
|
||||
cs.Dispatch(kernel, Mathf.CeilToInt(source.width / 32f), Mathf.CeilToInt(source.height / 32f), 1);
|
||||
|
||||
kernel = cs.FindKernel("KVectorscope");
|
||||
cs.SetBuffer(kernel, "_Vectorscope", m_Buffer);
|
||||
cs.SetTexture(kernel, "_Source", source);
|
||||
cs.SetInt("_IsLinear", GraphicsUtils.isLinearColorSpace ? 1 : 0);
|
||||
cs.SetVector("_Res", new Vector4(source.width, source.height, 0f, 0f));
|
||||
cs.Dispatch(kernel, Mathf.CeilToInt(source.width / 32f), Mathf.CeilToInt(source.height / 32f), 1);
|
||||
|
||||
if (m_VectorscopeTexture == null || m_VectorscopeTexture.width != source.width || m_VectorscopeTexture.height != source.height)
|
||||
{
|
||||
GraphicsUtils.Destroy(m_VectorscopeTexture);
|
||||
m_VectorscopeTexture = new RenderTexture(source.width, source.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear)
|
||||
{
|
||||
hideFlags = HideFlags.DontSave,
|
||||
wrapMode = TextureWrapMode.Clamp,
|
||||
filterMode = FilterMode.Bilinear
|
||||
};
|
||||
}
|
||||
|
||||
if (m_Material == null)
|
||||
m_Material = new Material(Shader.Find("Hidden/Post FX/Monitors/Vectorscope Render")) { hideFlags = HideFlags.DontSave };
|
||||
|
||||
m_Material.SetBuffer("_Vectorscope", m_Buffer);
|
||||
m_Material.SetVector("_Size", new Vector2(m_VectorscopeTexture.width, m_VectorscopeTexture.height));
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/ThirdParty/PostProcessing/Editor/Monitors/VectorscopeMonitor.cs.meta
vendored
Normal file
12
Assets/ThirdParty/PostProcessing/Editor/Monitors/VectorscopeMonitor.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 805119df0d94800418006c621cc99cc2
|
||||
timeCreated: 1461748750
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
280
Assets/ThirdParty/PostProcessing/Editor/Monitors/WaveformMonitor.cs
vendored
Normal file
280
Assets/ThirdParty/PostProcessing/Editor/Monitors/WaveformMonitor.cs
vendored
Normal file
@@ -0,0 +1,280 @@
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.PostProcessing;
|
||||
|
||||
namespace UnityEditor.PostProcessing
|
||||
{
|
||||
public class WaveformMonitor : PostProcessingMonitor
|
||||
{
|
||||
static GUIContent s_MonitorTitle = new GUIContent("Waveform");
|
||||
|
||||
ComputeShader m_ComputeShader;
|
||||
ComputeBuffer m_Buffer;
|
||||
Material m_Material;
|
||||
RenderTexture m_WaveformTexture;
|
||||
Rect m_MonitorAreaRect;
|
||||
|
||||
public WaveformMonitor()
|
||||
{
|
||||
m_ComputeShader = EditorResources.Load<ComputeShader>("Monitors/WaveformCompute.compute");
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
GraphicsUtils.Destroy(m_Material);
|
||||
GraphicsUtils.Destroy(m_WaveformTexture);
|
||||
|
||||
if (m_Buffer != null)
|
||||
m_Buffer.Release();
|
||||
|
||||
m_Material = null;
|
||||
m_WaveformTexture = null;
|
||||
m_Buffer = null;
|
||||
}
|
||||
|
||||
public override bool IsSupported()
|
||||
{
|
||||
return m_ComputeShader != null && GraphicsUtils.supportsDX11;
|
||||
}
|
||||
|
||||
public override GUIContent GetMonitorTitle()
|
||||
{
|
||||
return s_MonitorTitle;
|
||||
}
|
||||
|
||||
public override void OnMonitorSettings()
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
bool refreshOnPlay = m_MonitorSettings.refreshOnPlay;
|
||||
float exposure = m_MonitorSettings.waveformExposure;
|
||||
bool Y = m_MonitorSettings.waveformY;
|
||||
bool R = m_MonitorSettings.waveformR;
|
||||
bool G = m_MonitorSettings.waveformG;
|
||||
bool B = m_MonitorSettings.waveformB;
|
||||
|
||||
refreshOnPlay = GUILayout.Toggle(refreshOnPlay, new GUIContent(FxStyles.playIcon, "Keep refreshing the waveform in play mode; this may impact performances."), FxStyles.preButton);
|
||||
|
||||
exposure = GUILayout.HorizontalSlider(exposure, 0.05f, 0.3f, FxStyles.preSlider, FxStyles.preSliderThumb, GUILayout.Width(40f));
|
||||
|
||||
Y = GUILayout.Toggle(Y, new GUIContent("Y", "Show the luminance waveform only."), FxStyles.preButton);
|
||||
|
||||
if (Y)
|
||||
{
|
||||
R = false;
|
||||
G = false;
|
||||
B = false;
|
||||
}
|
||||
|
||||
R = GUILayout.Toggle(R, new GUIContent("R", "Show the red waveform."), FxStyles.preButton);
|
||||
G = GUILayout.Toggle(G, new GUIContent("G", "Show the green waveform."), FxStyles.preButton);
|
||||
B = GUILayout.Toggle(B, new GUIContent("B", "Show the blue waveform."), FxStyles.preButton);
|
||||
|
||||
if (R || G || B)
|
||||
Y = false;
|
||||
|
||||
if (!Y && !R && !G && !B)
|
||||
{
|
||||
R = true;
|
||||
G = true;
|
||||
B = true;
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(m_BaseEditor.serializedObject.targetObject, "Waveforme Settings Changed");
|
||||
m_MonitorSettings.refreshOnPlay = refreshOnPlay;
|
||||
m_MonitorSettings.waveformExposure = exposure;
|
||||
m_MonitorSettings.waveformY = Y;
|
||||
m_MonitorSettings.waveformR = R;
|
||||
m_MonitorSettings.waveformG = G;
|
||||
m_MonitorSettings.waveformB = B;
|
||||
InternalEditorUtility.RepaintAllViews();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnMonitorGUI(Rect r)
|
||||
{
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
// If m_MonitorAreaRect isn't set the preview was just opened so refresh the render to get the waveform data
|
||||
if (Mathf.Approximately(m_MonitorAreaRect.width, 0) && Mathf.Approximately(m_MonitorAreaRect.height, 0))
|
||||
InternalEditorUtility.RepaintAllViews();
|
||||
|
||||
// Sizing
|
||||
float width = m_WaveformTexture != null
|
||||
? Mathf.Min(m_WaveformTexture.width, r.width - 65f)
|
||||
: r.width;
|
||||
float height = m_WaveformTexture != null
|
||||
? Mathf.Min(m_WaveformTexture.height, r.height - 45f)
|
||||
: r.height;
|
||||
|
||||
m_MonitorAreaRect = new Rect(
|
||||
Mathf.Floor(r.x + r.width / 2f - width / 2f),
|
||||
Mathf.Floor(r.y + r.height / 2f - height / 2f - 5f),
|
||||
width, height
|
||||
);
|
||||
|
||||
if (m_WaveformTexture != null)
|
||||
{
|
||||
m_Material.SetFloat("_Exposure", m_MonitorSettings.waveformExposure);
|
||||
|
||||
var oldActive = RenderTexture.active;
|
||||
Graphics.Blit(null, m_WaveformTexture, m_Material, 0);
|
||||
RenderTexture.active = oldActive;
|
||||
|
||||
Graphics.DrawTexture(m_MonitorAreaRect, m_WaveformTexture);
|
||||
|
||||
var color = Color.white;
|
||||
const float kTickSize = 5f;
|
||||
|
||||
// Rect, lines & ticks points
|
||||
// A B C D E
|
||||
// P F
|
||||
// O G
|
||||
// N H
|
||||
// M L K J I
|
||||
|
||||
var A = new Vector3(m_MonitorAreaRect.x, m_MonitorAreaRect.y);
|
||||
var E = new Vector3(A.x + m_MonitorAreaRect.width + 1f, m_MonitorAreaRect.y);
|
||||
var I = new Vector3(E.x, E.y + m_MonitorAreaRect.height + 1f);
|
||||
var M = new Vector3(A.x, I.y);
|
||||
|
||||
var C = new Vector3(A.x + (E.x - A.x) / 2f, A.y);
|
||||
var G = new Vector3(E.x, E.y + (I.y - E.y) / 2f);
|
||||
var K = new Vector3(M.x + (I.x - M.x) / 2f, M.y);
|
||||
var O = new Vector3(A.x, A.y + (M.y - A.y) / 2f);
|
||||
|
||||
var P = new Vector3(A.x, A.y + (O.y - A.y) / 2f);
|
||||
var F = new Vector3(E.x, E.y + (G.y - E.y) / 2f);
|
||||
var N = new Vector3(A.x, O.y + (M.y - O.y) / 2f);
|
||||
var H = new Vector3(E.x, G.y + (I.y - G.y) / 2f);
|
||||
|
||||
var B = new Vector3(A.x + (C.x - A.x) / 2f, A.y);
|
||||
var L = new Vector3(M.x + (K.x - M.x) / 2f, M.y);
|
||||
var D = new Vector3(C.x + (E.x - C.x) / 2f, A.y);
|
||||
var J = new Vector3(K.x + (I.x - K.x) / 2f, M.y);
|
||||
|
||||
// Borders
|
||||
Handles.color = color;
|
||||
Handles.DrawLine(A, E);
|
||||
Handles.DrawLine(E, I);
|
||||
Handles.DrawLine(I, M);
|
||||
Handles.DrawLine(M, new Vector3(A.x, A.y - 1f));
|
||||
|
||||
// Vertical ticks
|
||||
Handles.DrawLine(A, new Vector3(A.x - kTickSize, A.y));
|
||||
Handles.DrawLine(P, new Vector3(P.x - kTickSize, P.y));
|
||||
Handles.DrawLine(O, new Vector3(O.x - kTickSize, O.y));
|
||||
Handles.DrawLine(N, new Vector3(N.x - kTickSize, N.y));
|
||||
Handles.DrawLine(M, new Vector3(M.x - kTickSize, M.y));
|
||||
|
||||
Handles.DrawLine(E, new Vector3(E.x + kTickSize, E.y));
|
||||
Handles.DrawLine(F, new Vector3(F.x + kTickSize, F.y));
|
||||
Handles.DrawLine(G, new Vector3(G.x + kTickSize, G.y));
|
||||
Handles.DrawLine(H, new Vector3(H.x + kTickSize, H.y));
|
||||
Handles.DrawLine(I, new Vector3(I.x + kTickSize, I.y));
|
||||
|
||||
// Horizontal ticks
|
||||
Handles.DrawLine(A, new Vector3(A.x, A.y - kTickSize));
|
||||
Handles.DrawLine(B, new Vector3(B.x, B.y - kTickSize));
|
||||
Handles.DrawLine(C, new Vector3(C.x, C.y - kTickSize));
|
||||
Handles.DrawLine(D, new Vector3(D.x, D.y - kTickSize));
|
||||
Handles.DrawLine(E, new Vector3(E.x, E.y - kTickSize));
|
||||
|
||||
Handles.DrawLine(M, new Vector3(M.x, M.y + kTickSize));
|
||||
Handles.DrawLine(L, new Vector3(L.x, L.y + kTickSize));
|
||||
Handles.DrawLine(K, new Vector3(K.x, K.y + kTickSize));
|
||||
Handles.DrawLine(J, new Vector3(J.x, J.y + kTickSize));
|
||||
Handles.DrawLine(I, new Vector3(I.x, I.y + kTickSize));
|
||||
|
||||
// Labels
|
||||
GUI.color = color;
|
||||
GUI.Label(new Rect(A.x - kTickSize - 34f, A.y - 15f, 30f, 30f), "1.0", FxStyles.tickStyleRight);
|
||||
GUI.Label(new Rect(O.x - kTickSize - 34f, O.y - 15f, 30f, 30f), "0.5", FxStyles.tickStyleRight);
|
||||
GUI.Label(new Rect(M.x - kTickSize - 34f, M.y - 15f, 30f, 30f), "0.0", FxStyles.tickStyleRight);
|
||||
|
||||
GUI.Label(new Rect(E.x + kTickSize + 4f, E.y - 15f, 30f, 30f), "1.0", FxStyles.tickStyleLeft);
|
||||
GUI.Label(new Rect(G.x + kTickSize + 4f, G.y - 15f, 30f, 30f), "0.5", FxStyles.tickStyleLeft);
|
||||
GUI.Label(new Rect(I.x + kTickSize + 4f, I.y - 15f, 30f, 30f), "0.0", FxStyles.tickStyleLeft);
|
||||
|
||||
GUI.Label(new Rect(M.x - 15f, M.y + kTickSize - 4f, 30f, 30f), "0.0", FxStyles.tickStyleCenter);
|
||||
GUI.Label(new Rect(K.x - 15f, K.y + kTickSize - 4f, 30f, 30f), "0.5", FxStyles.tickStyleCenter);
|
||||
GUI.Label(new Rect(I.x - 15f, I.y + kTickSize - 4f, 30f, 30f), "1.0", FxStyles.tickStyleCenter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnFrameData(RenderTexture source)
|
||||
{
|
||||
if (Application.isPlaying && !m_MonitorSettings.refreshOnPlay)
|
||||
return;
|
||||
|
||||
if (Mathf.Approximately(m_MonitorAreaRect.width, 0) || Mathf.Approximately(m_MonitorAreaRect.height, 0))
|
||||
return;
|
||||
|
||||
float ratio = (float)source.width / (float)source.height;
|
||||
int h = 384;
|
||||
int w = Mathf.FloorToInt(h * ratio);
|
||||
|
||||
var rt = RenderTexture.GetTemporary(w, h, 0, source.format);
|
||||
Graphics.Blit(source, rt);
|
||||
ComputeWaveform(rt);
|
||||
m_BaseEditor.Repaint();
|
||||
RenderTexture.ReleaseTemporary(rt);
|
||||
}
|
||||
|
||||
void CreateBuffer(int width, int height)
|
||||
{
|
||||
m_Buffer = new ComputeBuffer(width * height, sizeof(uint) << 2);
|
||||
}
|
||||
|
||||
void ComputeWaveform(RenderTexture source)
|
||||
{
|
||||
if (m_Buffer == null)
|
||||
{
|
||||
CreateBuffer(source.width, source.height);
|
||||
}
|
||||
else if (m_Buffer.count != (source.width * source.height))
|
||||
{
|
||||
m_Buffer.Release();
|
||||
CreateBuffer(source.width, source.height);
|
||||
}
|
||||
|
||||
var channels = m_MonitorSettings.waveformY
|
||||
? new Vector4(0f, 0f, 0f, 1f)
|
||||
: new Vector4(m_MonitorSettings.waveformR ? 1f : 0f, m_MonitorSettings.waveformG ? 1f : 0f, m_MonitorSettings.waveformB ? 1f : 0f, 0f);
|
||||
|
||||
var cs = m_ComputeShader;
|
||||
|
||||
int kernel = cs.FindKernel("KWaveformClear");
|
||||
cs.SetBuffer(kernel, "_Waveform", m_Buffer);
|
||||
cs.Dispatch(kernel, source.width, 1, 1);
|
||||
|
||||
kernel = cs.FindKernel("KWaveform");
|
||||
cs.SetBuffer(kernel, "_Waveform", m_Buffer);
|
||||
cs.SetTexture(kernel, "_Source", source);
|
||||
cs.SetInt("_IsLinear", GraphicsUtils.isLinearColorSpace ? 1 : 0);
|
||||
cs.SetVector("_Channels", channels);
|
||||
cs.Dispatch(kernel, source.width, 1, 1);
|
||||
|
||||
if (m_WaveformTexture == null || m_WaveformTexture.width != source.width || m_WaveformTexture.height != source.height)
|
||||
{
|
||||
GraphicsUtils.Destroy(m_WaveformTexture);
|
||||
m_WaveformTexture = new RenderTexture(source.width, source.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear)
|
||||
{
|
||||
hideFlags = HideFlags.DontSave,
|
||||
wrapMode = TextureWrapMode.Clamp,
|
||||
filterMode = FilterMode.Bilinear
|
||||
};
|
||||
}
|
||||
|
||||
if (m_Material == null)
|
||||
m_Material = new Material(Shader.Find("Hidden/Post FX/Monitors/Waveform Render")) { hideFlags = HideFlags.DontSave };
|
||||
|
||||
m_Material.SetBuffer("_Waveform", m_Buffer);
|
||||
m_Material.SetVector("_Size", new Vector2(m_WaveformTexture.width, m_WaveformTexture.height));
|
||||
m_Material.SetVector("_Channels", channels);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/ThirdParty/PostProcessing/Editor/Monitors/WaveformMonitor.cs.meta
vendored
Normal file
12
Assets/ThirdParty/PostProcessing/Editor/Monitors/WaveformMonitor.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d45bc7edb5916446b4fa1ae1b6f9065
|
||||
timeCreated: 1459957472
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user