This commit is contained in:
2021-06-13 10:28:03 +02:00
parent eb70603c85
commit df2d24cbd3
7487 changed files with 943244 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
using System.Linq;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace UnityEditor.Rendering.Universal
{
[VolumeComponentEditor(typeof(Bloom))]
sealed class BloomEditor : VolumeComponentEditor
{
SerializedDataParameter m_Threshold;
SerializedDataParameter m_Intensity;
SerializedDataParameter m_Scatter;
SerializedDataParameter m_Clamp;
SerializedDataParameter m_Tint;
SerializedDataParameter m_HighQualityFiltering;
SerializedDataParameter m_SkipIterations;
SerializedDataParameter m_DirtTexture;
SerializedDataParameter m_DirtIntensity;
public override void OnEnable()
{
var o = new PropertyFetcher<Bloom>(serializedObject);
m_Threshold = Unpack(o.Find(x => x.threshold));
m_Intensity = Unpack(o.Find(x => x.intensity));
m_Scatter = Unpack(o.Find(x => x.scatter));
m_Clamp = Unpack(o.Find(x => x.clamp));
m_Tint = Unpack(o.Find(x => x.tint));
m_HighQualityFiltering = Unpack(o.Find(x => x.highQualityFiltering));
m_SkipIterations = Unpack(o.Find(x => x.skipIterations));
m_DirtTexture = Unpack(o.Find(x => x.dirtTexture));
m_DirtIntensity = Unpack(o.Find(x => x.dirtIntensity));
}
public override void OnInspectorGUI()
{
EditorGUILayout.LabelField("Bloom", EditorStyles.miniLabel);
PropertyField(m_Threshold);
PropertyField(m_Intensity);
PropertyField(m_Scatter);
PropertyField(m_Tint);
PropertyField(m_Clamp);
PropertyField(m_HighQualityFiltering);
if (m_HighQualityFiltering.overrideState.boolValue && m_HighQualityFiltering.value.boolValue && CoreEditorUtils.buildTargets.Contains(GraphicsDeviceType.OpenGLES2))
EditorGUILayout.HelpBox("High Quality Bloom isn't supported on GLES2 platforms.", MessageType.Warning);
PropertyField(m_SkipIterations);
EditorGUILayout.LabelField("Lens Dirt", EditorStyles.miniLabel);
PropertyField(m_DirtTexture);
PropertyField(m_DirtIntensity);
}
}
}

View File

@@ -0,0 +1,76 @@
using UnityEngine;
using UnityEngine.Rendering.Universal;
namespace UnityEditor.Rendering.Universal
{
[VolumeComponentEditor(typeof(ChannelMixer))]
sealed class ChannelMixerEditor : VolumeComponentEditor
{
SerializedDataParameter m_RedOutRedIn;
SerializedDataParameter m_RedOutGreenIn;
SerializedDataParameter m_RedOutBlueIn;
SerializedDataParameter m_GreenOutRedIn;
SerializedDataParameter m_GreenOutGreenIn;
SerializedDataParameter m_GreenOutBlueIn;
SerializedDataParameter m_BlueOutRedIn;
SerializedDataParameter m_BlueOutGreenIn;
SerializedDataParameter m_BlueOutBlueIn;
SavedInt m_SelectedChannel;
public override void OnEnable()
{
var o = new PropertyFetcher<ChannelMixer>(serializedObject);
m_RedOutRedIn = Unpack(o.Find(x => x.redOutRedIn));
m_RedOutGreenIn = Unpack(o.Find(x => x.redOutGreenIn));
m_RedOutBlueIn = Unpack(o.Find(x => x.redOutBlueIn));
m_GreenOutRedIn = Unpack(o.Find(x => x.greenOutRedIn));
m_GreenOutGreenIn = Unpack(o.Find(x => x.greenOutGreenIn));
m_GreenOutBlueIn = Unpack(o.Find(x => x.greenOutBlueIn));
m_BlueOutRedIn = Unpack(o.Find(x => x.blueOutRedIn));
m_BlueOutGreenIn = Unpack(o.Find(x => x.blueOutGreenIn));
m_BlueOutBlueIn = Unpack(o.Find(x => x.blueOutBlueIn));
m_SelectedChannel = new SavedInt($"{target.GetType()}.SelectedChannel", 0);
}
public override void OnInspectorGUI()
{
int currentChannel = m_SelectedChannel.value;
EditorGUI.BeginChangeCheck();
{
using (new EditorGUILayout.HorizontalScope())
{
if (GUILayout.Toggle(currentChannel == 0, EditorGUIUtility.TrTextContent("Red", "Red output channel."), EditorStyles.miniButtonLeft)) currentChannel = 0;
if (GUILayout.Toggle(currentChannel == 1, EditorGUIUtility.TrTextContent("Green", "Green output channel."), EditorStyles.miniButtonMid)) currentChannel = 1;
if (GUILayout.Toggle(currentChannel == 2, EditorGUIUtility.TrTextContent("Blue", "Blue output channel."), EditorStyles.miniButtonRight)) currentChannel = 2;
}
}
if (EditorGUI.EndChangeCheck())
GUI.FocusControl(null);
m_SelectedChannel.value = currentChannel;
if (currentChannel == 0)
{
PropertyField(m_RedOutRedIn, EditorGUIUtility.TrTextContent("Red"));
PropertyField(m_RedOutGreenIn, EditorGUIUtility.TrTextContent("Green"));
PropertyField(m_RedOutBlueIn, EditorGUIUtility.TrTextContent("Blue"));
}
else if (currentChannel == 1)
{
PropertyField(m_GreenOutRedIn, EditorGUIUtility.TrTextContent("Red"));
PropertyField(m_GreenOutGreenIn, EditorGUIUtility.TrTextContent("Green"));
PropertyField(m_GreenOutBlueIn, EditorGUIUtility.TrTextContent("Blue"));
}
else
{
PropertyField(m_BlueOutRedIn, EditorGUIUtility.TrTextContent("Red"));
PropertyField(m_BlueOutGreenIn, EditorGUIUtility.TrTextContent("Green"));
PropertyField(m_BlueOutBlueIn, EditorGUIUtility.TrTextContent("Blue"));
}
}
}
}

View File

@@ -0,0 +1,374 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering.Universal;
namespace UnityEditor.Rendering.Universal
{
using CurveState = InspectorCurveEditor.CurveState;
[VolumeComponentEditor(typeof(ColorCurves))]
sealed class ColorCurvesEditor : VolumeComponentEditor
{
SerializedDataParameter m_Master;
SerializedDataParameter m_Red;
SerializedDataParameter m_Green;
SerializedDataParameter m_Blue;
SerializedDataParameter m_HueVsHue;
SerializedDataParameter m_HueVsSat;
SerializedDataParameter m_SatVsSat;
SerializedDataParameter m_LumVsSat;
// Internal references to the actual animation curves
// Needed for the curve editor
SerializedProperty m_RawMaster;
SerializedProperty m_RawRed;
SerializedProperty m_RawGreen;
SerializedProperty m_RawBlue;
SerializedProperty m_RawHueVsHue;
SerializedProperty m_RawHueVsSat;
SerializedProperty m_RawSatVsSat;
SerializedProperty m_RawLumVsSat;
InspectorCurveEditor m_CurveEditor;
Dictionary<SerializedProperty, Color> m_CurveDict;
static Material s_MaterialGrid;
static GUIStyle s_PreLabel;
static GUIContent[] s_Curves =
{
new GUIContent("Master"),
new GUIContent("Red"),
new GUIContent("Green"),
new GUIContent("Blue"),
new GUIContent("Hue Vs Hue"),
new GUIContent("Hue Vs Sat"),
new GUIContent("Sat Vs Sat"),
new GUIContent("Lum Vs Sat")
};
SavedInt m_SelectedCurve;
public override void OnEnable()
{
var o = new PropertyFetcher<ColorCurves>(serializedObject);
m_Master = Unpack(o.Find(x => x.master));
m_Red = Unpack(o.Find(x => x.red));
m_Green = Unpack(o.Find(x => x.green));
m_Blue = Unpack(o.Find(x => x.blue));
m_HueVsHue = Unpack(o.Find(x => x.hueVsHue));
m_HueVsSat = Unpack(o.Find(x => x.hueVsSat));
m_SatVsSat = Unpack(o.Find(x => x.satVsSat));
m_LumVsSat = Unpack(o.Find(x => x.lumVsSat));
m_RawMaster = o.Find("master.m_Value.m_Curve");
m_RawRed = o.Find("red.m_Value.m_Curve");
m_RawGreen = o.Find("green.m_Value.m_Curve");
m_RawBlue = o.Find("blue.m_Value.m_Curve");
m_RawHueVsHue = o.Find("hueVsHue.m_Value.m_Curve");
m_RawHueVsSat = o.Find("hueVsSat.m_Value.m_Curve");
m_RawSatVsSat = o.Find("satVsSat.m_Value.m_Curve");
m_RawLumVsSat = o.Find("lumVsSat.m_Value.m_Curve");
m_SelectedCurve = new SavedInt($"{target.GetType()}.SelectedCurve", 0);
// Prepare the curve editor
m_CurveEditor = new InspectorCurveEditor();
m_CurveDict = new Dictionary<SerializedProperty, Color>();
SetupCurve(m_RawMaster, new Color(1f, 1f, 1f), 2, false);
SetupCurve(m_RawRed, new Color(1f, 0f, 0f), 2, false);
SetupCurve(m_RawGreen, new Color(0f, 1f, 0f), 2, false);
SetupCurve(m_RawBlue, new Color(0f, 0.5f, 1f), 2, false);
SetupCurve(m_RawHueVsHue, new Color(1f, 1f, 1f), 0, true);
SetupCurve(m_RawHueVsSat, new Color(1f, 1f, 1f), 0, true);
SetupCurve(m_RawSatVsSat, new Color(1f, 1f, 1f), 0, false);
SetupCurve(m_RawLumVsSat, new Color(1f, 1f, 1f), 0, false);
}
void SetupCurve(SerializedProperty prop, Color color, uint minPointCount, bool loop)
{
var state = CurveState.defaultState;
state.color = color;
state.visible = false;
state.minPointCount = minPointCount;
state.onlyShowHandlesOnSelection = true;
state.zeroKeyConstantValue = 0.5f;
state.loopInBounds = loop;
m_CurveEditor.Add(prop, state);
m_CurveDict.Add(prop, color);
}
void ResetVisibleCurves()
{
foreach (var curve in m_CurveDict)
{
var state = m_CurveEditor.GetCurveState(curve.Key);
state.visible = false;
m_CurveEditor.SetCurveState(curve.Key, state);
}
}
void SetCurveVisible(SerializedProperty rawProp, SerializedProperty overrideProp)
{
var state = m_CurveEditor.GetCurveState(rawProp);
state.visible = true;
state.editable = overrideProp.boolValue;
m_CurveEditor.SetCurveState(rawProp, state);
}
void CurveOverrideToggle(SerializedProperty overrideProp)
{
overrideProp.boolValue = GUILayout.Toggle(overrideProp.boolValue, EditorGUIUtility.TrTextContent("Override"), EditorStyles.toolbarButton);
}
int DoCurveSelectionPopup(int id)
{
GUILayout.Label(s_Curves[id], EditorStyles.toolbarPopup, GUILayout.MaxWidth(150f));
var lastRect = GUILayoutUtility.GetLastRect();
var e = Event.current;
if (e.type == EventType.MouseDown && e.button == 0 && lastRect.Contains(e.mousePosition))
{
var menu = new GenericMenu();
for (int i = 0; i < s_Curves.Length; i++)
{
if (i == 4)
menu.AddSeparator("");
int current = i; // Capture local for closure
menu.AddItem(s_Curves[i], current == id, () =>
{
m_SelectedCurve.value = current;
serializedObject.ApplyModifiedProperties();
});
}
menu.DropDown(new Rect(lastRect.xMin, lastRect.yMax, 1f, 1f));
}
return id;
}
void DrawBackgroundTexture(Rect rect, int pass)
{
if (s_MaterialGrid == null)
s_MaterialGrid = new Material(Shader.Find("Hidden/Universal Render Pipeline/Editor/CurveBackground")) { hideFlags = HideFlags.HideAndDontSave };
float scale = EditorGUIUtility.pixelsPerPoint;
var oldRt = RenderTexture.active;
var rt = RenderTexture.GetTemporary(Mathf.CeilToInt(rect.width * scale), Mathf.CeilToInt(rect.height * scale), 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);
s_MaterialGrid.SetFloat("_DisabledState", GUI.enabled ? 1f : 0.5f);
Graphics.Blit(null, rt, s_MaterialGrid, pass);
RenderTexture.active = oldRt;
GUI.DrawTexture(rect, rt);
RenderTexture.ReleaseTemporary(rt);
}
void MarkTextureCurveAsDirty(int curveId)
{
var t = target as ColorCurves;
if (t == null)
return;
switch (curveId)
{
case 0: t.master.value.SetDirty(); break;
case 1: t.red.value.SetDirty(); break;
case 2: t.green.value.SetDirty(); break;
case 3: t.blue.value.SetDirty(); break;
case 4: t.hueVsHue.value.SetDirty(); break;
case 5: t.hueVsSat.value.SetDirty(); break;
case 6: t.satVsSat.value.SetDirty(); break;
case 7: t.lumVsSat.value.SetDirty(); break;
}
}
public override void OnInspectorGUI()
{
EditorGUILayout.Space();
ResetVisibleCurves();
using (new EditorGUI.DisabledGroupScope(serializedObject.isEditingMultipleObjects))
{
int curveEditingId;
SerializedProperty currentCurveRawProp = null;
// Top toolbar
using (new GUILayout.HorizontalScope(EditorStyles.toolbar))
{
curveEditingId = DoCurveSelectionPopup(m_SelectedCurve.value);
curveEditingId = Mathf.Clamp(curveEditingId, 0, 7);
EditorGUILayout.Space();
switch (curveEditingId)
{
case 0:
CurveOverrideToggle(m_Master.overrideState);
SetCurveVisible(m_RawMaster, m_Master.overrideState);
currentCurveRawProp = m_RawMaster;
break;
case 1:
CurveOverrideToggle(m_Red.overrideState);
SetCurveVisible(m_RawRed, m_Red.overrideState);
currentCurveRawProp = m_RawRed;
break;
case 2:
CurveOverrideToggle(m_Green.overrideState);
SetCurveVisible(m_RawGreen, m_Green.overrideState);
currentCurveRawProp = m_RawGreen;
break;
case 3:
CurveOverrideToggle(m_Blue.overrideState);
SetCurveVisible(m_RawBlue, m_Blue.overrideState);
currentCurveRawProp = m_RawBlue;
break;
case 4:
CurveOverrideToggle(m_HueVsHue.overrideState);
SetCurveVisible(m_RawHueVsHue, m_HueVsHue.overrideState);
currentCurveRawProp = m_RawHueVsHue;
break;
case 5:
CurveOverrideToggle(m_HueVsSat.overrideState);
SetCurveVisible(m_RawHueVsSat, m_HueVsSat.overrideState);
currentCurveRawProp = m_RawHueVsSat;
break;
case 6:
CurveOverrideToggle(m_SatVsSat.overrideState);
SetCurveVisible(m_RawSatVsSat, m_SatVsSat.overrideState);
currentCurveRawProp = m_RawSatVsSat;
break;
case 7:
CurveOverrideToggle(m_LumVsSat.overrideState);
SetCurveVisible(m_RawLumVsSat, m_LumVsSat.overrideState);
currentCurveRawProp = m_RawLumVsSat;
break;
}
GUILayout.FlexibleSpace();
if (GUILayout.Button("Reset", EditorStyles.toolbarButton))
{
MarkTextureCurveAsDirty(curveEditingId);
switch (curveEditingId)
{
case 0: m_RawMaster.animationCurveValue = AnimationCurve.Linear(0f, 0f, 1f, 1f); break;
case 1: m_RawRed.animationCurveValue = AnimationCurve.Linear(0f, 0f, 1f, 1f); break;
case 2: m_RawGreen.animationCurveValue = AnimationCurve.Linear(0f, 0f, 1f, 1f); break;
case 3: m_RawBlue.animationCurveValue = AnimationCurve.Linear(0f, 0f, 1f, 1f); break;
case 4: m_RawHueVsHue.animationCurveValue = new AnimationCurve(); break;
case 5: m_RawHueVsSat.animationCurveValue = new AnimationCurve(); break;
case 6: m_RawSatVsSat.animationCurveValue = new AnimationCurve(); break;
case 7: m_RawLumVsSat.animationCurveValue = new AnimationCurve(); break;
}
}
m_SelectedCurve.value = curveEditingId;
}
// Curve area
var rect = GUILayoutUtility.GetAspectRect(2f);
var innerRect = new RectOffset(10, 10, 10, 10).Remove(rect);
if (Event.current.type == EventType.Repaint)
{
// Background
EditorGUI.DrawRect(rect, new Color(0.15f, 0.15f, 0.15f, 1f));
if (curveEditingId == 4 || curveEditingId == 5)
DrawBackgroundTexture(innerRect, 0);
else if (curveEditingId == 6 || curveEditingId == 7)
DrawBackgroundTexture(innerRect, 1);
// Bounds
Handles.color = Color.white * (GUI.enabled ? 1f : 0.5f);
Handles.DrawSolidRectangleWithOutline(innerRect, Color.clear, new Color(0.8f, 0.8f, 0.8f, 0.5f));
// Grid setup
Handles.color = new Color(1f, 1f, 1f, 0.05f);
int hLines = (int)Mathf.Sqrt(innerRect.width);
int vLines = (int)(hLines / (innerRect.width / innerRect.height));
// Vertical grid
int gridOffset = Mathf.FloorToInt(innerRect.width / hLines);
int gridPadding = ((int)(innerRect.width) % hLines) / 2;
for (int i = 1; i < hLines; i++)
{
var offset = i * Vector2.right * gridOffset;
offset.x += gridPadding;
Handles.DrawLine(innerRect.position + offset, new Vector2(innerRect.x, innerRect.yMax - 1) + offset);
}
// Horizontal grid
gridOffset = Mathf.FloorToInt(innerRect.height / vLines);
gridPadding = ((int)(innerRect.height) % vLines) / 2;
for (int i = 1; i < vLines; i++)
{
var offset = i * Vector2.up * gridOffset;
offset.y += gridPadding;
Handles.DrawLine(innerRect.position + offset, new Vector2(innerRect.xMax - 1, innerRect.y) + offset);
}
}
// Curve editor
using (new GUI.ClipScope(innerRect))
{
if (m_CurveEditor.OnGUI(new Rect(0, 0, innerRect.width - 1, innerRect.height - 1)))
{
Repaint();
GUI.changed = true;
MarkTextureCurveAsDirty(m_SelectedCurve.value);
}
}
if (Event.current.type == EventType.Repaint)
{
// Borders
Handles.color = Color.black;
Handles.DrawLine(new Vector2(rect.x, rect.y - 20f), new Vector2(rect.xMax, rect.y - 20f));
Handles.DrawLine(new Vector2(rect.x, rect.y - 21f), new Vector2(rect.x, rect.yMax));
Handles.DrawLine(new Vector2(rect.x, rect.yMax), new Vector2(rect.xMax, rect.yMax));
Handles.DrawLine(new Vector2(rect.xMax, rect.yMax), new Vector2(rect.xMax, rect.y - 20f));
bool editable = m_CurveEditor.GetCurveState(currentCurveRawProp).editable;
string editableString = editable ? string.Empty : "(Not Overriding)\n";
// Selection info
var selection = m_CurveEditor.GetSelection();
var infoRect = innerRect;
infoRect.x += 5f;
infoRect.width = 100f;
infoRect.height = 30f;
if (s_PreLabel == null)
s_PreLabel = new GUIStyle("ShurikenLabel");
if (selection.curve != null && selection.keyframeIndex > -1)
{
var key = selection.keyframe.Value;
GUI.Label(infoRect, $"{key.time:F3}\n{key.value:F3}", s_PreLabel);
}
else
{
GUI.Label(infoRect, editableString, s_PreLabel);
}
}
}
}
}
}

View File

@@ -0,0 +1,39 @@
using UnityEngine.Rendering.Universal;
namespace UnityEditor.Rendering.Universal
{
[VolumeComponentEditor(typeof(ColorLookup))]
sealed class ColorLookupEditor : VolumeComponentEditor
{
SerializedDataParameter m_Texture;
SerializedDataParameter m_Contribution;
public override void OnEnable()
{
var o = new PropertyFetcher<ColorLookup>(serializedObject);
m_Texture = Unpack(o.Find(x => x.texture));
m_Contribution = Unpack(o.Find(x => x.contribution));
}
public override void OnInspectorGUI()
{
PropertyField(m_Texture, EditorGUIUtility.TrTextContent("Lookup Texture"));
var lut = m_Texture.value.objectReferenceValue;
if (lut != null && !((ColorLookup)target).ValidateLUT())
EditorGUILayout.HelpBox("Invalid lookup texture. It must be a non-sRGB 2D texture or render texture with the same size as set in the Universal Render Pipeline settings.", MessageType.Warning);
PropertyField(m_Contribution, EditorGUIUtility.TrTextContent("Contribution"));
var asset = UniversalRenderPipeline.asset;
if (asset != null)
{
if (asset.supportsHDR && asset.colorGradingMode == ColorGradingMode.HighDynamicRange)
EditorGUILayout.HelpBox("Color Grading Mode in the Universal Render Pipeline Settings is set to HDR. As a result, this LUT will be applied after the internal color grading and tonemapping have been applied.", MessageType.Info);
else
EditorGUILayout.HelpBox("Color Grading Mode in the Universal Render Pipeline Settings is set to LDR. As a result, this LUT will be applied after tonemapping and before the internal color grading has been applied.", MessageType.Info);
}
}
}
}

View File

@@ -0,0 +1,62 @@
using UnityEngine.Rendering.Universal;
namespace UnityEditor.Rendering.Universal
{
[VolumeComponentEditor(typeof(DepthOfField))]
sealed class DepthOfFieldEditor : VolumeComponentEditor
{
SerializedDataParameter m_Mode;
SerializedDataParameter m_GaussianStart;
SerializedDataParameter m_GaussianEnd;
SerializedDataParameter m_GaussianMaxRadius;
SerializedDataParameter m_HighQualitySampling;
SerializedDataParameter m_FocusDistance;
SerializedDataParameter m_FocalLength;
SerializedDataParameter m_Aperture;
SerializedDataParameter m_BladeCount;
SerializedDataParameter m_BladeCurvature;
SerializedDataParameter m_BladeRotation;
public override void OnEnable()
{
var o = new PropertyFetcher<DepthOfField>(serializedObject);
m_Mode = Unpack(o.Find(x => x.mode));
m_GaussianStart = Unpack(o.Find(x => x.gaussianStart));
m_GaussianEnd = Unpack(o.Find(x => x.gaussianEnd));
m_GaussianMaxRadius = Unpack(o.Find(x => x.gaussianMaxRadius));
m_HighQualitySampling = Unpack(o.Find(x => x.highQualitySampling));
m_FocusDistance = Unpack(o.Find(x => x.focusDistance));
m_FocalLength = Unpack(o.Find(x => x.focalLength));
m_Aperture = Unpack(o.Find(x => x.aperture));
m_BladeCount = Unpack(o.Find(x => x.bladeCount));
m_BladeCurvature = Unpack(o.Find(x => x.bladeCurvature));
m_BladeRotation = Unpack(o.Find(x => x.bladeRotation));
}
public override void OnInspectorGUI()
{
PropertyField(m_Mode);
if (m_Mode.value.intValue == (int)DepthOfFieldMode.Gaussian)
{
PropertyField(m_GaussianStart, EditorGUIUtility.TrTextContent("Start"));
PropertyField(m_GaussianEnd, EditorGUIUtility.TrTextContent("End"));
PropertyField(m_GaussianMaxRadius, EditorGUIUtility.TrTextContent("Max Radius"));
PropertyField(m_HighQualitySampling);
}
else if (m_Mode.value.intValue == (int)DepthOfFieldMode.Bokeh)
{
PropertyField(m_FocusDistance);
PropertyField(m_FocalLength);
PropertyField(m_Aperture);
PropertyField(m_BladeCount);
PropertyField(m_BladeCurvature);
PropertyField(m_BladeRotation);
}
}
}
}

View File

@@ -0,0 +1,69 @@
using UnityEngine;
using UnityEngine.Rendering.Universal;
namespace UnityEditor.Rendering.Universal
{
[VolumeComponentEditor(typeof(FilmGrain))]
sealed class FilmGrainEditor : VolumeComponentEditor
{
SerializedDataParameter m_Type;
SerializedDataParameter m_Intensity;
SerializedDataParameter m_Response;
SerializedDataParameter m_Texture;
public override void OnEnable()
{
var o = new PropertyFetcher<FilmGrain>(serializedObject);
m_Type = Unpack(o.Find(x => x.type));
m_Intensity = Unpack(o.Find(x => x.intensity));
m_Response = Unpack(o.Find(x => x.response));
m_Texture = Unpack(o.Find(x => x.texture));
}
public override void OnInspectorGUI()
{
PropertyField(m_Type);
if (m_Type.value.intValue == (int)FilmGrainLookup.Custom)
{
PropertyField(m_Texture);
var texture = (target as FilmGrain).texture.value;
if (texture != null)
{
var importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(texture)) as TextureImporter;
// Fails when using an internal texture as you can't change import settings on
// builtin resources, thus the check for null
if (importer != null)
{
bool valid = importer.mipmapEnabled == false
&& importer.alphaSource == TextureImporterAlphaSource.FromGrayScale
&& importer.filterMode == FilterMode.Point
&& importer.textureCompression == TextureImporterCompression.Uncompressed
&& importer.textureType == TextureImporterType.SingleChannel;
if (!valid)
CoreEditorUtils.DrawFixMeBox("Invalid texture import settings.", () => SetTextureImportSettings(importer));
}
}
}
PropertyField(m_Intensity);
PropertyField(m_Response);
}
static void SetTextureImportSettings(TextureImporter importer)
{
importer.textureType = TextureImporterType.SingleChannel;
importer.alphaSource = TextureImporterAlphaSource.FromGrayScale;
importer.mipmapEnabled = false;
importer.filterMode = FilterMode.Point;
importer.textureCompression = TextureImporterCompression.Uncompressed;
importer.SaveAndReimport();
AssetDatabase.Refresh();
}
}
}

View File

@@ -0,0 +1,38 @@
using UnityEngine;
using UnityEngine.Rendering.Universal;
namespace UnityEditor.Rendering.Universal
{
[VolumeComponentEditor(typeof(LiftGammaGain))]
sealed class LiftGammaGainEditor : VolumeComponentEditor
{
SerializedDataParameter m_Lift;
SerializedDataParameter m_Gamma;
SerializedDataParameter m_Gain;
readonly TrackballUIDrawer m_TrackballUIDrawer = new TrackballUIDrawer();
public override void OnEnable()
{
var o = new PropertyFetcher<LiftGammaGain>(serializedObject);
m_Lift = Unpack(o.Find(x => x.lift));
m_Gamma = Unpack(o.Find(x => x.gamma));
m_Gain = Unpack(o.Find(x => x.gain));
}
public override void OnInspectorGUI()
{
using (new EditorGUILayout.HorizontalScope())
{
m_TrackballUIDrawer.OnGUI(m_Lift.value, m_Lift.overrideState, EditorGUIUtility.TrTextContent("Lift"), GetLiftValue);
GUILayout.Space(4f);
m_TrackballUIDrawer.OnGUI(m_Gamma.value, m_Gamma.overrideState, EditorGUIUtility.TrTextContent("Gamma"), GetLiftValue);
GUILayout.Space(4f);
m_TrackballUIDrawer.OnGUI(m_Gain.value, m_Gain.overrideState, EditorGUIUtility.TrTextContent("Gain"), GetLiftValue);
}
}
static Vector3 GetLiftValue(Vector4 x) => new Vector3(x.x + x.w, x.y + x.w, x.z + x.w);
}
}

View File

@@ -0,0 +1,39 @@
using UnityEngine.Rendering.Universal;
namespace UnityEditor.Rendering.Universal
{
[VolumeComponentEditor(typeof(MotionBlur))]
sealed class MotionBlurEditor : VolumeComponentEditor
{
//SerializedDataParameter m_Mode;
SerializedDataParameter m_Quality;
SerializedDataParameter m_Intensity;
SerializedDataParameter m_Clamp;
public override void OnEnable()
{
var o = new PropertyFetcher<MotionBlur>(serializedObject);
//m_Mode = Unpack(o.Find(x => x.mode));
m_Quality = Unpack(o.Find(x => x.quality));
m_Intensity = Unpack(o.Find(x => x.intensity));
m_Clamp = Unpack(o.Find(x => x.clamp));
}
public override void OnInspectorGUI()
{
//PropertyField(m_Mode);
//if (m_Mode.value.intValue == (int)MotionBlurMode.CameraOnly)
//{
PropertyField(m_Quality);
PropertyField(m_Intensity);
PropertyField(m_Clamp);
//}
//else
//{
// EditorGUILayout.HelpBox("Object motion blur is not supported on the Universal Render Pipeline yet.", MessageType.Info);
//}
}
}
}

View File

@@ -0,0 +1,63 @@
Shader "Hidden/Universal Render Pipeline/Editor/CurveBackground"
{
CGINCLUDE
#pragma target 3.0
#include "UnityCG.cginc"
float _DisabledState;
float3 HsvToRgb(float3 c)
{
float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);
}
float4 FragHue(v2f_img i) : SV_Target
{
float3 hsv = HsvToRgb(float3(i.uv.x, 1.0, 0.2));
float4 color = float4((0.0).xxx, 1.0);
color.rgb = lerp(color.rgb, hsv, smoothstep(0.5, 1.1, 1.0 - i.uv.y)) + lerp(color.rgb, hsv, smoothstep(0.5, 1.1, i.uv.y));
color.rgb += GammaToLinearSpace(0.15).xxx;
return float4(color.rgb, color.a * _DisabledState);
}
float4 FragSat(v2f_img i) : SV_Target
{
float4 color = float4((0.0).xxx, 1.0);
float sat = i.uv.x / 2;
color.rgb += lerp(color.rgb, (sat).xxx, smoothstep(0.5, 1.2, 1.0 - i.uv.y)) + lerp(color.rgb, (sat).xxx, smoothstep(0.5, 1.2, i.uv.y));
color.rgb += GammaToLinearSpace(0.15).xxx;
return float4(color.rgb, color.a * _DisabledState);
}
ENDCG
SubShader
{
Cull Off ZWrite Off ZTest Always
// (0) Hue
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment FragHue
ENDCG
}
// (1) Sat/lum
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment FragSat
ENDCG
}
}
}

View File

@@ -0,0 +1,90 @@
Shader "Hidden/Universal Render Pipeline/Editor/Shadows Midtones Highlights Curve"
{
CGINCLUDE
#include "UnityCG.cginc"
#pragma editor_sync_compilation
#pragma target 3.5
float4 _ShaHiLimits; // xy: shadows min/max, zw: highlight min/max
float4 _Variants; // x: disabled state, y: x-scale, wz: unused
float3 BlendScreen(float3 base, float3 blend)
{
return 1.0 - (1.0 - blend) * (1.0 - base);
}
float4 DrawCurve(v2f_img i, float3 background, float3 shadowsCurveColor, float3 midtonesCurveColor, float3 highlightsCurveColor)
{
float x = i.uv.x * _Variants.y;
float y = i.uv.y;
float aa = fwidth(i.uv.y) * 2.0;
float shadowsY = 1.0 - smoothstep(_ShaHiLimits.x, _ShaHiLimits.y, x);
float shadowsCurve = smoothstep(shadowsY + aa, shadowsY, y);
float shadowsLine = smoothstep(shadowsY - aa, shadowsY, y) - smoothstep(shadowsY, shadowsY + aa, y);
float highlightsY = smoothstep(_ShaHiLimits.z, _ShaHiLimits.w, x);
float highlightsCurve = smoothstep(highlightsY + aa, highlightsY, y);
float highlightsLine = smoothstep(highlightsY - aa, highlightsY, y) - smoothstep(highlightsY, highlightsY + aa, y);
float midtonesY = 1.0 - shadowsY - highlightsY;
float midtonesCurve = smoothstep(midtonesY + aa, midtonesY, y);
float midtonesLine = smoothstep(midtonesY - aa, midtonesY, y) - smoothstep(midtonesY, midtonesY + aa, y);
float grad = lerp(0.7, 1.0, y);
float3 shadowsColor = shadowsCurveColor * shadowsCurve * grad;
float3 midtonesColor = midtonesCurveColor * midtonesCurve * grad;
float3 highlightsColor = highlightsCurveColor * highlightsCurve * grad;
float3 color = BlendScreen(shadowsColor, midtonesColor);
color = BlendScreen(color, highlightsColor);
color = BlendScreen(background, color * _Variants.xxx);
const float kAlpha = 0.3 * _Variants.xxx;
color += shadowsLine * shadowsColor * kAlpha;
color += midtonesLine * midtonesColor * kAlpha;
color += highlightsLine * highlightsColor * kAlpha;
return float4(color, 1.0);
}
float4 FragCurveDark(v2f_img i) : SV_Target
{
return DrawCurve(i, (pow(0.196, 2.2)).xxx, pow(float3(0.161, 0.851, 0.761), 2.2), pow(float3(0.741, 0.949, 0.443), 2.2), pow(float3(0.9, 0.9, 0.651), 2.2));
}
float4 FragCurveLight(v2f_img i) : SV_Target
{
return DrawCurve(i, (pow(0.635, 2.2)).xxx, pow(float3(0.161, 0.851, 0.761), 2.2), pow(float3(0.741, 0.949, 0.443), 2.2), pow(float3(1.0, 1.0, 0.651), 2.2));
}
ENDCG
SubShader
{
Cull Off ZWrite Off ZTest Always
// (0) Dark skin
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment FragCurveDark
ENDCG
}
// (1) Light skin
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment FragCurveLight
ENDCG
}
}
}

View File

@@ -0,0 +1,126 @@
Shader "Hidden/Universal Render Pipeline/Editor/Trackball"
{
CGINCLUDE
#pragma editor_sync_compilation
#include "UnityCG.cginc"
#define PI 3.14159265359
#define PI2 6.28318530718
float _Offset;
float _DisabledState;
float2 _Resolution; // x: size, y: size / 2
float3 HsvToRgb(float3 c)
{
float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);
}
float4 CreateWheel(v2f_img i, float crossColor, float offsetColor)
{
const float kHueOuterRadius = 0.45;
const float kHueInnerRadius = 0.38;
const float kLumOuterRadius = 0.495;
const float kLumInnerRadius = 0.48;
float4 color = (0.0).xxxx;
float2 uvc = i.uv - (0.5).xx;
float dist = sqrt(dot(uvc, uvc));
float delta = fwidth(dist);
float angle = atan2(uvc.x, uvc.y);
// Cross
{
float radius = (0.5 - kHueInnerRadius) * _Resolution.x + 1.0;
float2 pixel = (_Resolution.xx - 1.0) * i.uv + 1.0;
float vline = step(floor(fmod(pixel.x, _Resolution.y)), 0.0);
vline *= step(radius, pixel.y) * step(pixel.y, _Resolution.x - radius);
float hline = step(floor(fmod(pixel.y, _Resolution.y)), 0.0);
hline *= step(radius, pixel.x) * step(pixel.x, _Resolution.x - radius);
color += hline.xxxx * (1.0).xxxx;
color += vline.xxxx * (1.0).xxxx;
color = saturate(color);
color *= half4((crossColor).xxx, 0.05);
}
// Hue
{
float alphaOut = smoothstep(kHueOuterRadius - delta, kHueOuterRadius + delta, dist);
float alphaIn = smoothstep(kHueInnerRadius - delta, kHueInnerRadius + delta, dist);
float hue = angle;
hue = 1.0 - ((hue > 0.0) ? hue : PI2 + hue) / PI2;
float4 c = float4(HsvToRgb(float3(hue, 1.0, 1.0)), 1.0);
color += lerp((0.0).xxxx, c, alphaIn - alphaOut);
}
// Offset
{
float alphaOut = smoothstep(kLumOuterRadius - delta, kLumOuterRadius + delta, dist);
float alphaIn = smoothstep(kLumInnerRadius - delta, kLumInnerRadius + delta / 2, dist);
float4 c = float4((offsetColor).xxx, 1.0);
float a = PI * _Offset;
if (_Offset >= 0 && angle < a && angle > 0.0)
c = float4((1.0).xxx, 0.5);
else if (angle > a && angle < 0.0)
c = float4((1.0).xxx, 0.5);
color += lerp((0.0).xxxx, c, alphaIn - alphaOut);
}
color = color * _DisabledState;
#if !UNITY_COLORSPACE_GAMMA
color = half4(GammaToLinearSpace(color.xyz), color.w);
#endif
return color;
}
float4 FragTrackballDark(v2f_img i) : SV_Target
{
return CreateWheel(i, 1.0, 0.15);
}
float4 FragTrackballLight(v2f_img i) : SV_Target
{
return CreateWheel(i, 0.0, 0.3);
}
ENDCG
SubShader
{
Cull Off ZWrite Off ZTest Always
// (0) Dark skin
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment FragTrackballDark
ENDCG
}
// (1) Light skin
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment FragTrackballLight
ENDCG
}
}
}

View File

@@ -0,0 +1,138 @@
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace UnityEditor.Rendering.Universal
{
// TODO: handle retina / EditorGUIUtility.pixelsPerPoint
[VolumeComponentEditor(typeof(ShadowsMidtonesHighlights))]
sealed class ShadowsMidtonesHighlightsEditor : VolumeComponentEditor
{
SerializedDataParameter m_Shadows;
SerializedDataParameter m_Midtones;
SerializedDataParameter m_Highlights;
SerializedDataParameter m_ShadowsStart;
SerializedDataParameter m_ShadowsEnd;
SerializedDataParameter m_HighlightsStart;
SerializedDataParameter m_HighlightsEnd;
const string k_ShaderName = "Hidden/Universal Render Pipeline/Editor/Shadows Midtones Highlights Curve";
static Material s_Material;
readonly TrackballUIDrawer m_TrackballUIDrawer = new TrackballUIDrawer();
// Curve drawing utilities
Rect m_CurveRect;
RenderTexture m_CurveTex;
public override void OnEnable()
{
var o = new PropertyFetcher<ShadowsMidtonesHighlights>(serializedObject);
m_Shadows = Unpack(o.Find(x => x.shadows));
m_Midtones = Unpack(o.Find(x => x.midtones));
m_Highlights = Unpack(o.Find(x => x.highlights));
m_ShadowsStart = Unpack(o.Find(x => x.shadowsStart));
m_ShadowsEnd = Unpack(o.Find(x => x.shadowsEnd));
m_HighlightsStart = Unpack(o.Find(x => x.highlightsStart));
m_HighlightsEnd = Unpack(o.Find(x => x.highlightsEnd));
}
public override void OnInspectorGUI()
{
if (!CheckMaterialAndShader())
{
return;
}
using (new EditorGUILayout.HorizontalScope())
{
m_TrackballUIDrawer.OnGUI(m_Shadows.value, m_Shadows.overrideState, EditorGUIUtility.TrTextContent("Shadows"), GetWheelValue);
GUILayout.Space(4f);
m_TrackballUIDrawer.OnGUI(m_Midtones.value, m_Midtones.overrideState, EditorGUIUtility.TrTextContent("Midtones"), GetWheelValue);
GUILayout.Space(4f);
m_TrackballUIDrawer.OnGUI(m_Highlights.value, m_Highlights.overrideState, EditorGUIUtility.TrTextContent("Highlights"), GetWheelValue);
}
EditorGUILayout.Space();
// Reserve GUI space
using (new GUILayout.HorizontalScope())
{
GUILayout.Space(EditorGUI.indentLevel * 15f);
m_CurveRect = GUILayoutUtility.GetRect(128, 80);
}
if (Event.current.type == EventType.Repaint)
{
float alpha = GUI.enabled ? 1f : 0.4f;
var limits = new Vector4(m_ShadowsStart.value.floatValue, m_ShadowsEnd.value.floatValue, m_HighlightsStart.value.floatValue, m_HighlightsEnd.value.floatValue);
s_Material.SetVector("_ShaHiLimits", limits);
s_Material.SetVector("_Variants", new Vector4(alpha, Mathf.Max(m_HighlightsEnd.value.floatValue, 1f), 0f, 0f));
CheckCurveRT((int)m_CurveRect.width, (int)m_CurveRect.height);
var oldRt = RenderTexture.active;
Graphics.Blit(null, m_CurveTex, s_Material, EditorGUIUtility.isProSkin ? 0 : 1);
RenderTexture.active = oldRt;
GUI.DrawTexture(m_CurveRect, m_CurveTex);
Handles.DrawSolidRectangleWithOutline(m_CurveRect, Color.clear, Color.white * 0.4f);
}
EditorGUILayout.Space();
EditorGUILayout.LabelField("Shadow Limits", EditorStyles.miniLabel);
PropertyField(m_ShadowsStart, EditorGUIUtility.TrTextContent("Start"));
m_ShadowsStart.value.floatValue = Mathf.Min(m_ShadowsStart.value.floatValue, m_ShadowsEnd.value.floatValue);
PropertyField(m_ShadowsEnd, EditorGUIUtility.TrTextContent("End"));
m_ShadowsEnd.value.floatValue = Mathf.Max(m_ShadowsStart.value.floatValue, m_ShadowsEnd.value.floatValue);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Highlight Limits", EditorStyles.miniLabel);
PropertyField(m_HighlightsStart, EditorGUIUtility.TrTextContent("Start"));
m_HighlightsStart.value.floatValue = Mathf.Min(m_HighlightsStart.value.floatValue, m_HighlightsEnd.value.floatValue);
PropertyField(m_HighlightsEnd, EditorGUIUtility.TrTextContent("End"));
m_HighlightsEnd.value.floatValue = Mathf.Max(m_HighlightsStart.value.floatValue, m_HighlightsEnd.value.floatValue);
}
void CheckCurveRT(int width, int height)
{
if (m_CurveTex == null || !m_CurveTex.IsCreated() || m_CurveTex.width != width || m_CurveTex.height != height)
{
CoreUtils.Destroy(m_CurveTex);
m_CurveTex = new RenderTexture(width, height, 0, RenderTextureFormat.ARGB32);
m_CurveTex.hideFlags = HideFlags.HideAndDontSave;
}
}
static Vector3 GetWheelValue(Vector4 v)
{
float w = v.w * (Mathf.Sign(v.w) < 0f ? 1f : 4f);
return new Vector3(
Mathf.Max(v.x + w, 0f),
Mathf.Max(v.y + w, 0f),
Mathf.Max(v.z + w, 0f)
);
}
bool CheckMaterialAndShader()
{
if (s_Material != null)
{
return true;
}
Shader shader = Shader.Find(k_ShaderName);
if (shader == null)
{
Debug.LogError("ShadowsMidtonesHighlightsEditor: Unable to find shader \"" + k_ShaderName + "\"");
return false;
}
s_Material = new Material(shader);
return true;
}
}
}

View File

@@ -0,0 +1,30 @@
using UnityEngine.Rendering.Universal;
namespace UnityEditor.Rendering.Universal
{
[VolumeComponentEditor(typeof(Tonemapping))]
sealed class TonemappingEditor : VolumeComponentEditor
{
SerializedDataParameter m_Mode;
public override void OnEnable()
{
var o = new PropertyFetcher<Tonemapping>(serializedObject);
m_Mode = Unpack(o.Find(x => x.mode));
}
public override void OnInspectorGUI()
{
PropertyField(m_Mode);
// Display a warning if the user is trying to use a tonemap while rendering in LDR
var asset = UniversalRenderPipeline.asset;
if (asset != null && !asset.supportsHDR)
{
EditorGUILayout.HelpBox("Tonemapping should only be used when working in HDR.", MessageType.Warning);
return;
}
}
}
}