You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
327 lines
15 KiB
327 lines
15 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using UnityEditor;
|
|
using UnityEditor.Rendering;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
|
|
namespace HorizonBasedAmbientOcclusion.Universal
|
|
{
|
|
#if UNITY_2022_2_OR_NEWER
|
|
[CustomEditor(typeof(HBAO), true)]
|
|
#else
|
|
[VolumeComponentEditor(typeof(HBAO))]
|
|
#endif
|
|
public class HBAOEditor : VolumeComponentEditor
|
|
{
|
|
private HBAO m_HBAO;
|
|
private Texture2D m_HBAOTex;
|
|
private GUIStyle m_SettingsGroupStyle;
|
|
private GUIStyle m_TitleLabelStyle;
|
|
private int m_SelectedPreset;
|
|
private PropertyFetcher<HBAO> m_PropertyFetcher;
|
|
|
|
// settings group <setting, property reference>
|
|
private Dictionary<HBAO.SettingsGroup, List<MemberInfo>> m_GroupFields;
|
|
private readonly Dictionary<int, HBAO.Preset> m_Presets = new Dictionary<int, HBAO.Preset>()
|
|
{
|
|
{ 0, HBAO.Preset.Normal },
|
|
{ 1, HBAO.Preset.FastPerformance },
|
|
{ 2, HBAO.Preset.FastestPerformance },
|
|
{ 3, HBAO.Preset.Custom },
|
|
{ 4, HBAO.Preset.HighQuality },
|
|
{ 5, HBAO.Preset.HighestQuality }
|
|
};
|
|
|
|
#if UNITY_2021_2_OR_NEWER
|
|
public override bool hasAdditionalProperties => false;
|
|
#else
|
|
public override bool hasAdvancedMode => false;
|
|
#endif
|
|
|
|
public override void OnEnable()
|
|
{
|
|
base.OnEnable();
|
|
|
|
m_HBAO = (HBAO)target;
|
|
m_HBAOTex = Resources.Load<Texture2D>("hbao_urp");
|
|
|
|
//var o = new PropertyFetcher<HBAO>(serializedObject);
|
|
m_PropertyFetcher = new PropertyFetcher<HBAO>(serializedObject);
|
|
m_GroupFields = new Dictionary<HBAO.SettingsGroup, List<MemberInfo>>();
|
|
|
|
var settings = m_HBAO.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
|
|
.Where(t => t.FieldType.IsSubclassOf(typeof(VolumeParameter)))
|
|
.Where(t => (t.IsPublic && t.GetCustomAttributes(typeof(NonSerializedAttribute), false).Length == 0) ||
|
|
(t.GetCustomAttributes(typeof(SerializeField), false).Length > 0))
|
|
.Where(t => t.GetCustomAttributes(typeof(HideInInspector), false).Length == 0)
|
|
.Where(t => t.GetCustomAttributes(typeof(HBAO.SettingsGroup), false).Any());
|
|
foreach (var setting in settings)
|
|
{
|
|
//Debug.Log("setting name: " + setting.Name);
|
|
|
|
foreach (var attr in setting.GetCustomAttributes(typeof(HBAO.SettingsGroup)) as IEnumerable<HBAO.SettingsGroup>)
|
|
{
|
|
if (!m_GroupFields.ContainsKey(attr))
|
|
m_GroupFields[attr] = new List<MemberInfo>();
|
|
|
|
m_GroupFields[attr].Add(setting);
|
|
}
|
|
}
|
|
|
|
m_SelectedPreset = m_Presets.Values.ToList().IndexOf(m_HBAO.GetCurrentPreset());
|
|
}
|
|
|
|
public override void OnInspectorGUI()
|
|
{
|
|
SetStyles();
|
|
|
|
EditorGUILayout.BeginVertical();
|
|
{
|
|
// header
|
|
GUILayout.Space(10.0f);
|
|
GUILayout.Label(m_HBAOTex, m_TitleLabelStyle, GUILayout.ExpandWidth(true));
|
|
|
|
//if (m_HBAO.GetComponents<MonoBehaviour>()[0] != m_HBAO)
|
|
//{
|
|
//GUILayout.Space(6.0f);
|
|
//EditorGUILayout.HelpBox("This Post FX should be one of the first in your effect stack", MessageType.Info);
|
|
//}
|
|
|
|
Event e = Event.current;
|
|
|
|
// settings groups
|
|
foreach (var group in m_GroupFields)
|
|
{
|
|
GUILayout.Space(6.0f);
|
|
Rect rect = GUILayoutUtility.GetRect(16f, 22f, m_SettingsGroupStyle);
|
|
GUI.Box(rect, ObjectNames.NicifyVariableName(group.Key.GetType().Name), m_SettingsGroupStyle);
|
|
if (e.type == EventType.MouseDown && rect.Contains(e.mousePosition))
|
|
{
|
|
group.Key.isExpanded = !group.Key.isExpanded;
|
|
e.Use();
|
|
}
|
|
|
|
if (!group.Key.isExpanded)
|
|
continue;
|
|
|
|
// presets is a special case
|
|
if (group.Key.GetType() == typeof(HBAO.Presets))
|
|
{
|
|
GUILayout.Space(6.0f);
|
|
m_SelectedPreset = GUILayout.SelectionGrid(m_SelectedPreset, m_Presets.Values.Select(x => ObjectNames.NicifyVariableName(x.ToString())).ToArray(), 3);
|
|
GUILayout.Space(6.0f);
|
|
if (GUILayout.Button("Apply Preset"))
|
|
{
|
|
Undo.RecordObject(target, "Apply Preset");
|
|
m_HBAO.ApplyPreset(m_Presets[m_SelectedPreset]);
|
|
EditorUtility.SetDirty(target);
|
|
/*if (!EditorApplication.isPlaying)
|
|
{
|
|
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEngine.SceneManagement.SceneManager.GetActiveScene());
|
|
}*/
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
foreach (var field in group.Value)
|
|
{
|
|
// warn about URP10+ required when mode is LitAO
|
|
if (group.Key.GetType() == typeof(HBAO.GeneralSettings) && field.Name == "renderingPath")
|
|
{
|
|
#if UNITY_2021_2_OR_NEWER
|
|
if (m_HBAO.mode.overrideState && m_HBAO.mode.value != HBAO.Mode.LitAO)
|
|
{
|
|
continue; // hides rendering path settings when not LitAO
|
|
}
|
|
#else
|
|
continue; // hides rendering path before URP12
|
|
#endif
|
|
}
|
|
|
|
// hide resolution when deinterleaved HBAO is on
|
|
if (group.Key.GetType() == typeof(HBAO.GeneralSettings) && field.Name == "resolution")
|
|
{
|
|
if (m_HBAO.deinterleaving.overrideState && m_HBAO.GetDeinterleaving() != HBAO.Deinterleaving.Disabled)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
// hide noise type when deinterleaved HBAO is on
|
|
else if (group.Key.GetType() == typeof(HBAO.GeneralSettings) && field.Name == "noiseType")
|
|
{
|
|
if (m_HBAO.deinterleaving.overrideState && m_HBAO.GetDeinterleaving() != HBAO.Deinterleaving.Disabled)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
// hide useMultiBounce setting when mode is LitAO
|
|
else if (group.Key.GetType() == typeof(HBAO.AOSettings) && field.Name == "useMultiBounce")
|
|
{
|
|
if (!m_HBAO.mode.overrideState || m_HBAO.mode.value == HBAO.Mode.LitAO)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
// hide multiBounceInfluence setting when not used or when mode is LitAO
|
|
else if (group.Key.GetType() == typeof(HBAO.AOSettings) && field.Name == "multiBounceInfluence")
|
|
{
|
|
if (!m_HBAO.useMultiBounce.overrideState || !m_HBAO.UseMultiBounce() ||
|
|
(!m_HBAO.mode.overrideState || m_HBAO.mode.value == HBAO.Mode.LitAO))
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
// hide directLightingStrength setting when mode is normal
|
|
else if (group.Key.GetType() == typeof(HBAO.AOSettings) && field.Name == "directLightingStrength")
|
|
{
|
|
if (m_HBAO.mode.overrideState && m_HBAO.mode.value == HBAO.Mode.Normal)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
// warn about distance falloff greater than max distance
|
|
else if (group.Key.GetType() == typeof(HBAO.AOSettings) && field.Name == "perPixelNormals")
|
|
{
|
|
if ((m_HBAO.distanceFalloff.overrideState || m_HBAO.maxDistance.overrideState) && m_HBAO.GetAoDistanceFalloff() > m_HBAO.GetAoMaxDistance())
|
|
{
|
|
GUILayout.Space(6.0f);
|
|
EditorGUILayout.HelpBox("Distance Falloff shoudn't be greater than Max Distance.", MessageType.Warning);
|
|
}
|
|
}
|
|
// warn about motion vectors not supported
|
|
else if (group.Key.GetType() == typeof(HBAO.TemporalFilterSettings) && field.Name == "temporalFilterEnabled")
|
|
{
|
|
// For platforms not supporting motion vectors texture
|
|
// https://docs.unity3d.com/ScriptReference/DepthTextureMode.MotionVectors.html
|
|
if (!SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RGHalf))
|
|
{
|
|
GUILayout.Space(6.0f);
|
|
EditorGUILayout.HelpBox("Motion vectors not supported on this platform...", MessageType.Warning);
|
|
|
|
if (m_HBAO.IsTemporalFilterEnabled())
|
|
m_HBAO.EnableTemporalFilter(false);
|
|
}
|
|
else
|
|
{
|
|
#if !UNITY_2021_2_OR_NEWER
|
|
GUILayout.Space(6.0f);
|
|
EditorGUILayout.HelpBox("Requires proper motion vectors support available in 2021.2+", MessageType.Warning);
|
|
|
|
if (m_HBAO.IsTemporalFilterEnabled())
|
|
m_HBAO.EnableTemporalFilter(false);
|
|
#else
|
|
if (IsVrRunning())
|
|
{
|
|
GUILayout.Space(6.0f);
|
|
EditorGUILayout.HelpBox("Not supported yet in VR...", MessageType.Warning);
|
|
|
|
if (m_HBAO.IsTemporalFilterEnabled())
|
|
m_HBAO.EnableTemporalFilter(false);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
// warn about color bleeding not supported when doing LitAO
|
|
else if (group.Key.GetType() == typeof(HBAO.ColorBleedingSettings) && field.Name == "colorBleedingEnabled")
|
|
{
|
|
if (!m_HBAO.mode.overrideState || m_HBAO.mode.value == HBAO.Mode.LitAO)
|
|
{
|
|
GUILayout.Space(6.0f);
|
|
EditorGUILayout.HelpBox("Color bleeding can't be used in LitAO mode as AO is being injected into the lighting.", MessageType.Warning);
|
|
|
|
if (m_HBAO.IsColorBleedingEnabled())
|
|
m_HBAO.EnableColorBleeding(false);
|
|
}
|
|
}
|
|
|
|
var parameter = Unpack(m_PropertyFetcher.Find(field.Name));
|
|
var displayName = parameter.displayName;
|
|
var hasDisplayName = field.GetCustomAttributes(typeof(HBAO.ParameterDisplayName)).Any();
|
|
if (hasDisplayName)
|
|
{
|
|
var displayNameAttribute = field.GetCustomAttributes(typeof(HBAO.ParameterDisplayName)).First() as HBAO.ParameterDisplayName;
|
|
displayName = displayNameAttribute.name;
|
|
}
|
|
|
|
PropertyField(parameter, new GUIContent(displayName));
|
|
}
|
|
|
|
GUILayout.Space(6.0f);
|
|
}
|
|
}
|
|
EditorGUILayout.EndVertical();
|
|
}
|
|
|
|
private void SetStyles()
|
|
{
|
|
// set banner label style
|
|
m_TitleLabelStyle = new GUIStyle(GUI.skin.label);
|
|
m_TitleLabelStyle.alignment = TextAnchor.MiddleCenter;
|
|
m_TitleLabelStyle.contentOffset = new Vector2(0f, 0f);
|
|
|
|
// get shuriken module title style
|
|
GUIStyle skurikenModuleTitleStyle = "ShurikenModuleTitle";
|
|
|
|
// clone it as to not interfere with the original, and adjust it
|
|
m_SettingsGroupStyle = new GUIStyle(skurikenModuleTitleStyle);
|
|
m_SettingsGroupStyle.font = (new GUIStyle("Label")).font;
|
|
m_SettingsGroupStyle.fontStyle = FontStyle.Bold;
|
|
m_SettingsGroupStyle.border = new RectOffset(15, 7, 4, 4);
|
|
m_SettingsGroupStyle.fixedHeight = 22;
|
|
m_SettingsGroupStyle.contentOffset = new Vector2(10f, -2f);
|
|
}
|
|
|
|
List<UnityEngine.XR.XRDisplaySubsystem> displays = new List<UnityEngine.XR.XRDisplaySubsystem>();
|
|
|
|
private bool IsVrRunning()
|
|
{
|
|
bool vrIsRunning = false;
|
|
displays.Clear();
|
|
SubsystemManager.GetSubsystems(displays);
|
|
foreach (var displaySubsystem in displays)
|
|
{
|
|
if (displaySubsystem.running)
|
|
{
|
|
vrIsRunning = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return vrIsRunning;
|
|
}
|
|
|
|
[VolumeParameterDrawer(typeof(HBAO.MinMaxFloatParameter))]
|
|
public class MaxFloatParameterDrawer : VolumeParameterDrawer
|
|
{
|
|
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
|
|
{
|
|
if (parameter.value.propertyType == SerializedPropertyType.Vector2)
|
|
{
|
|
var o = parameter.GetObjectRef<HBAO.MinMaxFloatParameter>();
|
|
var range = o.value;
|
|
float x = range.x;
|
|
float y = range.y;
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
EditorGUILayout.MinMaxSlider(title, ref x, ref y, o.min, o.max);
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
range.x = x;
|
|
range.y = y;
|
|
o.SetValue(new HBAO.MinMaxFloatParameter(range, o.min, o.max));
|
|
}
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
EditorGUILayout.LabelField(title, "Use only with Vector2");
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|