393 lines
19 KiB
C#
393 lines
19 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering.HighDefinition;
|
|
using UnityEngine.Rendering;
|
|
using UnityEngine.UIElements;
|
|
using UnityEditorInternal;
|
|
using System.Linq;
|
|
|
|
namespace UnityEditor.Rendering.HighDefinition
|
|
{
|
|
class DefaultSettingsPanelProvider
|
|
{
|
|
static DefaultSettingsPanelIMGUI s_IMGUIImpl = new DefaultSettingsPanelIMGUI();
|
|
|
|
[SettingsProvider]
|
|
public static SettingsProvider CreateSettingsProvider()
|
|
{
|
|
return new SettingsProvider("Project/HDRP Default Settings", SettingsScope.Project)
|
|
{
|
|
activateHandler = s_IMGUIImpl.OnActivate,
|
|
keywords = SettingsProvider.GetSearchKeywordsFromGUIContentProperties<HDRenderPipelineUI.Styles.GeneralSection>()
|
|
.Concat(SettingsProvider.GetSearchKeywordsFromGUIContentProperties<DefaultSettingsPanelIMGUI.Styles>())
|
|
.Concat(OverridableFrameSettingsArea.frameSettingsKeywords).ToArray(),
|
|
guiHandler = s_IMGUIImpl.DoGUI,
|
|
};
|
|
}
|
|
|
|
class DefaultSettingsPanelIMGUI
|
|
{
|
|
// A wrapper for CoreEditorDrawers
|
|
class CoreEditorDrawerEditorWrapper : Editor, IDefaultFrameSettingsType
|
|
{
|
|
public FrameSettingsRenderType GetFrameSettingsType()
|
|
{
|
|
switch (HDRenderPipelineUI.selectedFrameSettings)
|
|
{
|
|
case HDRenderPipelineUI.SelectedFrameSettings.Camera: return FrameSettingsRenderType.Camera;
|
|
case HDRenderPipelineUI.SelectedFrameSettings.RealtimeReflection: return FrameSettingsRenderType.RealtimeReflection;
|
|
case HDRenderPipelineUI.SelectedFrameSettings.BakedOrCustomReflection: return FrameSettingsRenderType.CustomOrBakedReflection;
|
|
}
|
|
throw new Exception("unreachable");
|
|
}
|
|
}
|
|
|
|
public class Styles
|
|
{
|
|
public const int labelWidth = 220;
|
|
public static GUIContent defaultHDRPAsset = new GUIContent("Asset with the default settings");
|
|
public static GUIContent defaultVolumeProfileLabel = new GUIContent("Default Volume Profile Asset");
|
|
public static GUIContent lookDevVolumeProfileLabel = new GUIContent("LookDev Volume Profile Asset");
|
|
public static GUIContent frameSettingsLabel = new GUIContent("Frame Settings");
|
|
public static GUIContent volumeComponentsLabel = new GUIContent("Volume Components");
|
|
public static GUIContent customPostProcessOrderLabel = new GUIContent("Custom Post Process Orders");
|
|
public static GUIContent diffusionProfileSettingsLabel = new GUIContent("Default Diffusion Profile Assets");
|
|
}
|
|
|
|
Vector2 m_ScrollViewPosition = Vector2.zero;
|
|
Editor m_CachedDefaultVolumeProfileEditor;
|
|
Editor m_CachedLookDevVolumeProfileEditor;
|
|
ReorderableList m_BeforeTransparentCustomPostProcesses;
|
|
ReorderableList m_BeforeTAACustomPostProcesses;
|
|
ReorderableList m_BeforePostProcessCustomPostProcesses;
|
|
ReorderableList m_AfterPostProcessCustomPostProcesses;
|
|
int m_CurrentVolumeProfileInstanceID;
|
|
private Editor m_Cache;
|
|
DiffusionProfileSettingsListUI m_DiffusionProfileUI;
|
|
SerializedHDRenderPipelineAsset m_SerializeHDRPAsset;
|
|
|
|
public void DoGUI(string searchContext)
|
|
{
|
|
if (HDRenderPipeline.defaultAsset == null)
|
|
{
|
|
EditorGUILayout.HelpBox("Base SRP Asset is not a HDRenderPipelineAsset.", MessageType.Warning);
|
|
return;
|
|
}
|
|
|
|
m_SerializeHDRPAsset.Update();
|
|
|
|
m_ScrollViewPosition = GUILayout.BeginScrollView(m_ScrollViewPosition, EditorStyles.largeLabel);
|
|
Draw_GeneralSettings();
|
|
EditorGUILayout.Space();
|
|
|
|
EditorGUILayout.LabelField(Styles.frameSettingsLabel, EditorStyles.largeLabel);
|
|
Draw_DefaultFrameSettings();
|
|
EditorGUILayout.Space();
|
|
|
|
EditorGUILayout.LabelField(Styles.volumeComponentsLabel, EditorStyles.largeLabel);
|
|
Draw_VolumeInspector();
|
|
EditorGUILayout.Space();
|
|
|
|
EditorGUILayout.LabelField(Styles.customPostProcessOrderLabel, EditorStyles.largeLabel);
|
|
Draw_CustomPostProcess();
|
|
|
|
EditorGUILayout.LabelField(Styles.diffusionProfileSettingsLabel, EditorStyles.largeLabel);
|
|
Draw_DiffusionProfileSettings();
|
|
GUILayout.EndScrollView();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Executed when activate is called from the settings provider.
|
|
/// </summary>
|
|
/// <param name="searchContext"></param>
|
|
/// <param name="rootElement"></param>
|
|
public void OnActivate(string searchContext, VisualElement rootElement)
|
|
{
|
|
if (HDRenderPipeline.defaultAsset == null)
|
|
return;
|
|
|
|
m_ScrollViewPosition = Vector2.zero;
|
|
InitializeCustomPostProcessesLists();
|
|
|
|
m_DiffusionProfileUI = new DiffusionProfileSettingsListUI()
|
|
{
|
|
drawElement = DrawDiffusionProfileElement
|
|
};
|
|
|
|
var serializedObject = new SerializedObject(HDRenderPipeline.defaultAsset);
|
|
m_SerializeHDRPAsset = new SerializedHDRenderPipelineAsset(serializedObject);
|
|
|
|
var editorResources = HDRenderPipeline.defaultAsset.renderPipelineEditorResources;
|
|
if (!EditorUtility.IsPersistent(editorResources))
|
|
{
|
|
var editorResourcesPath = HDUtils.GetHDRenderPipelinePath() + "Editor/RenderPipelineResources/HDRenderPipelineEditorResources.asset";
|
|
HDRenderPipeline.defaultAsset.renderPipelineEditorResources = AssetDatabase.LoadAssetAtPath<HDRenderPipelineEditorResources>(editorResourcesPath);
|
|
}
|
|
}
|
|
|
|
void InitializeCustomPostProcessesLists()
|
|
{
|
|
var hdrpAsset = HDRenderPipeline.defaultAsset;
|
|
if (hdrpAsset == null)
|
|
return;
|
|
|
|
var ppVolumeTypes = TypeCache.GetTypesDerivedFrom<CustomPostProcessVolumeComponent>();
|
|
var ppVolumeTypeInjectionPoints = new Dictionary<Type, CustomPostProcessInjectionPoint>();
|
|
foreach (var ppVolumeType in ppVolumeTypes)
|
|
{
|
|
if (ppVolumeType.IsAbstract)
|
|
continue;
|
|
|
|
var comp = ScriptableObject.CreateInstance(ppVolumeType) as CustomPostProcessVolumeComponent;
|
|
ppVolumeTypeInjectionPoints[ppVolumeType] = comp.injectionPoint;
|
|
CoreUtils.Destroy(comp);
|
|
}
|
|
|
|
InitList(ref m_BeforeTransparentCustomPostProcesses, hdrpAsset.beforeTransparentCustomPostProcesses, "After Opaque And Sky", CustomPostProcessInjectionPoint.AfterOpaqueAndSky);
|
|
InitList(ref m_BeforeTAACustomPostProcesses, hdrpAsset.beforeTAACustomPostProcesses, "Before TAA", CustomPostProcessInjectionPoint.BeforeTAA);
|
|
InitList(ref m_BeforePostProcessCustomPostProcesses, hdrpAsset.beforePostProcessCustomPostProcesses, "Before Post Process", CustomPostProcessInjectionPoint.BeforePostProcess);
|
|
InitList(ref m_AfterPostProcessCustomPostProcesses, hdrpAsset.afterPostProcessCustomPostProcesses, "After Post Process", CustomPostProcessInjectionPoint.AfterPostProcess);
|
|
|
|
void InitList(ref ReorderableList reorderableList, List<string> customPostProcessTypes, string headerName, CustomPostProcessInjectionPoint injectionPoint)
|
|
{
|
|
// Sanitize the list:
|
|
customPostProcessTypes.RemoveAll(s => Type.GetType(s) == null);
|
|
|
|
reorderableList = new ReorderableList(customPostProcessTypes, typeof(string));
|
|
reorderableList.drawHeaderCallback = (rect) =>
|
|
EditorGUI.LabelField(rect, headerName, EditorStyles.boldLabel);
|
|
reorderableList.drawElementCallback = (rect, index, isActive, isFocused) =>
|
|
{
|
|
rect.height = EditorGUIUtility.singleLineHeight;
|
|
var elemType = Type.GetType(customPostProcessTypes[index]);
|
|
EditorGUI.LabelField(rect, elemType.ToString(), EditorStyles.boldLabel);
|
|
};
|
|
reorderableList.onAddCallback = (list) =>
|
|
{
|
|
var menu = new GenericMenu();
|
|
|
|
foreach (var kp in ppVolumeTypeInjectionPoints)
|
|
{
|
|
if (kp.Value == injectionPoint && !customPostProcessTypes.Contains(kp.Key.AssemblyQualifiedName))
|
|
menu.AddItem(new GUIContent(kp.Key.ToString()), false, () =>
|
|
{
|
|
Undo.RegisterCompleteObjectUndo(hdrpAsset, $"Added {kp.Key.ToString()} Custom Post Process");
|
|
customPostProcessTypes.Add(kp.Key.AssemblyQualifiedName);
|
|
});
|
|
}
|
|
|
|
if (menu.GetItemCount() == 0)
|
|
menu.AddDisabledItem(new GUIContent("No Custom Post Process Availble"));
|
|
|
|
menu.ShowAsContext();
|
|
EditorUtility.SetDirty(hdrpAsset);
|
|
};
|
|
reorderableList.onRemoveCallback = (list) =>
|
|
{
|
|
Undo.RegisterCompleteObjectUndo(hdrpAsset, $"Removed {list.list[list.index].ToString()} Custom Post Process");
|
|
customPostProcessTypes.RemoveAt(list.index);
|
|
EditorUtility.SetDirty(hdrpAsset);
|
|
};
|
|
reorderableList.elementHeightCallback = _ => EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
|
reorderableList.onReorderCallback = (list) => EditorUtility.SetDirty(hdrpAsset);
|
|
}
|
|
}
|
|
|
|
void Draw_CustomPostProcess()
|
|
{
|
|
var hdrpAsset = HDRenderPipeline.defaultAsset;
|
|
if (hdrpAsset == null)
|
|
return;
|
|
|
|
m_BeforeTransparentCustomPostProcesses.DoLayoutList();
|
|
m_BeforeTAACustomPostProcesses.DoLayoutList();
|
|
m_BeforePostProcessCustomPostProcesses.DoLayoutList();
|
|
m_AfterPostProcessCustomPostProcesses.DoLayoutList();
|
|
}
|
|
|
|
void Draw_GeneralSettings()
|
|
{
|
|
var hdrpAsset = HDRenderPipeline.defaultAsset;
|
|
if (hdrpAsset == null)
|
|
{
|
|
EditorGUILayout.HelpBox("Base SRP Asset is not a HDRenderPipelineAsset.", MessageType.Warning);
|
|
return;
|
|
}
|
|
|
|
var oldWidth = EditorGUIUtility.labelWidth;
|
|
EditorGUIUtility.labelWidth = Styles.labelWidth;
|
|
|
|
GUI.enabled = false;
|
|
EditorGUILayout.ObjectField(Styles.defaultHDRPAsset, hdrpAsset, typeof(HDRenderPipelineAsset), false);
|
|
GUI.enabled = true;
|
|
|
|
HDRenderPipelineUI.GeneralSection.Draw(m_SerializeHDRPAsset, null);
|
|
|
|
m_SerializeHDRPAsset.serializedObject.ApplyModifiedProperties();
|
|
EditorGUIUtility.labelWidth = oldWidth;
|
|
}
|
|
|
|
void Draw_VolumeInspector()
|
|
{
|
|
var hdrpAsset = HDRenderPipeline.defaultAsset;
|
|
if (hdrpAsset == null)
|
|
return;
|
|
|
|
var oldWidth = EditorGUIUtility.labelWidth;
|
|
EditorGUIUtility.labelWidth = Styles.labelWidth;
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
var asset = EditorDefaultSettings.GetOrAssignDefaultVolumeProfile();
|
|
var newAsset = (VolumeProfile)EditorGUILayout.ObjectField(Styles.defaultVolumeProfileLabel, asset, typeof(VolumeProfile), false);
|
|
if (newAsset == null)
|
|
{
|
|
Debug.Log("Default Volume Profile Asset cannot be null. Rolling back to previous value.");
|
|
}
|
|
else if (newAsset != asset)
|
|
{
|
|
Undo.RegisterCompleteObjectUndo(hdrpAsset, "Default Volume Profile Asset Change.");
|
|
asset = newAsset;
|
|
hdrpAsset.defaultVolumeProfile = asset;
|
|
EditorUtility.SetDirty(hdrpAsset);
|
|
}
|
|
|
|
if (GUILayout.Button(EditorGUIUtility.TrTextContent("New", "Create a new Volume Profile for default in your default resource folder (defined in Wizard)"), GUILayout.Width(38), GUILayout.Height(18)))
|
|
{
|
|
DefaultVolumeProfileCreator.CreateAndAssign(DefaultVolumeProfileCreator.Kind.Default);
|
|
}
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
// The state of the profile can change without the asset reference changing so in this case we need to reset the editor.
|
|
if (m_CurrentVolumeProfileInstanceID != asset.GetInstanceID() && m_CachedDefaultVolumeProfileEditor != null)
|
|
{
|
|
m_CurrentVolumeProfileInstanceID = asset.GetInstanceID();
|
|
m_CachedDefaultVolumeProfileEditor = null;
|
|
}
|
|
|
|
Editor.CreateCachedEditor(asset, Type.GetType("UnityEditor.Rendering.VolumeProfileEditor"), ref m_CachedDefaultVolumeProfileEditor);
|
|
EditorGUIUtility.labelWidth -= 18;
|
|
bool oldEnabled = GUI.enabled;
|
|
GUI.enabled = AssetDatabase.IsOpenForEdit(asset);
|
|
m_CachedDefaultVolumeProfileEditor.OnInspectorGUI();
|
|
GUI.enabled = oldEnabled;
|
|
EditorGUIUtility.labelWidth = oldWidth;
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
var lookDevAsset = EditorDefaultSettings.GetOrAssignLookDevVolumeProfile();
|
|
EditorGUIUtility.labelWidth = 221;
|
|
var newLookDevAsset = (VolumeProfile)EditorGUILayout.ObjectField(Styles.lookDevVolumeProfileLabel, lookDevAsset, typeof(VolumeProfile), false);
|
|
if (lookDevAsset == null)
|
|
{
|
|
Debug.Log("LookDev Volume Profile Asset cannot be null. Rolling back to previous value.");
|
|
}
|
|
else if (newLookDevAsset != lookDevAsset)
|
|
{
|
|
hdrpAsset.defaultLookDevProfile = newLookDevAsset;
|
|
EditorUtility.SetDirty(hdrpAsset);
|
|
}
|
|
|
|
if (GUILayout.Button(EditorGUIUtility.TrTextContent("New", "Create a new Volume Profile for default in your default resource folder (defined in Wizard)"), GUILayout.Width(38), GUILayout.Height(18)))
|
|
{
|
|
DefaultVolumeProfileCreator.CreateAndAssign(DefaultVolumeProfileCreator.Kind.LookDev);
|
|
}
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
Editor.CreateCachedEditor(lookDevAsset, Type.GetType("UnityEditor.Rendering.VolumeProfileEditor"), ref m_CachedLookDevVolumeProfileEditor);
|
|
EditorGUIUtility.labelWidth -= 18;
|
|
oldEnabled = GUI.enabled;
|
|
GUI.enabled = AssetDatabase.IsOpenForEdit(asset);
|
|
m_CachedLookDevVolumeProfileEditor.OnInspectorGUI();
|
|
GUI.enabled = oldEnabled;
|
|
EditorGUIUtility.labelWidth = oldWidth;
|
|
|
|
if (lookDevAsset.Has<VisualEnvironment>())
|
|
EditorGUILayout.HelpBox("VisualEnvironment is not modifiable and will be overridden by the LookDev", MessageType.Warning);
|
|
if (lookDevAsset.Has<HDRISky>())
|
|
EditorGUILayout.HelpBox("HDRISky is not modifiable and will be overridden by the LookDev", MessageType.Warning);
|
|
}
|
|
|
|
void Draw_DefaultFrameSettings()
|
|
{
|
|
var hdrpAsset = HDRenderPipeline.defaultAsset;
|
|
if (hdrpAsset == null)
|
|
return;
|
|
|
|
Editor.CreateCachedEditor(hdrpAsset, typeof(CoreEditorDrawerEditorWrapper), ref m_Cache);
|
|
|
|
HDRenderPipelineUI.FrameSettingsSection.Draw(m_SerializeHDRPAsset, m_Cache);
|
|
m_SerializeHDRPAsset.serializedObject.ApplyModifiedProperties();
|
|
}
|
|
|
|
void DrawDiffusionProfileElement(SerializedProperty element, Rect rect, int index)
|
|
{
|
|
EditorGUI.BeginChangeCheck();
|
|
EditorGUI.ObjectField(rect, element, EditorGUIUtility.TrTextContent("Profile " + index));
|
|
if (EditorGUI.EndChangeCheck())
|
|
m_SerializeHDRPAsset.serializedObject.ApplyModifiedProperties();
|
|
}
|
|
|
|
void Draw_DiffusionProfileSettings()
|
|
{
|
|
m_DiffusionProfileUI.OnGUI(m_SerializeHDRPAsset.diffusionProfileSettingsList);
|
|
}
|
|
}
|
|
}
|
|
|
|
class DefaultVolumeProfileCreator : ProjectWindowCallback.EndNameEditAction
|
|
{
|
|
public enum Kind { Default, LookDev }
|
|
Kind m_Kind;
|
|
|
|
void SetKind(Kind kind) => m_Kind = kind;
|
|
|
|
public override void Action(int instanceId, string pathName, string resourceFile)
|
|
{
|
|
var profile = VolumeProfileFactory.CreateVolumeProfileAtPath(pathName);
|
|
ProjectWindowUtil.ShowCreatedAsset(profile);
|
|
Assign(profile);
|
|
}
|
|
|
|
void Assign(VolumeProfile profile)
|
|
{
|
|
var hdrpAsset = HDRenderPipeline.defaultAsset;
|
|
switch (m_Kind)
|
|
{
|
|
case Kind.Default:
|
|
hdrpAsset.defaultVolumeProfile = profile;
|
|
break;
|
|
case Kind.LookDev:
|
|
hdrpAsset.defaultLookDevProfile = profile;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static string GetDefaultName(Kind kind)
|
|
{
|
|
string defaultName;
|
|
switch (kind)
|
|
{
|
|
case Kind.Default:
|
|
defaultName = "DefaultVolumeSettingsProfile";
|
|
break;
|
|
case Kind.LookDev:
|
|
defaultName = "LookDevVolumeSettingsProfile";
|
|
break;
|
|
default:
|
|
defaultName = "N/A";
|
|
break;
|
|
}
|
|
return defaultName;
|
|
}
|
|
|
|
public static void CreateAndAssign(Kind kind)
|
|
{
|
|
var assetCreator = ScriptableObject.CreateInstance<DefaultVolumeProfileCreator>();
|
|
assetCreator.SetKind(kind);
|
|
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(assetCreator.GetInstanceID(), assetCreator, $"Assets/{HDProjectSettings.projectSettingsFolderPath}/{GetDefaultName(kind)}.asset", null, null);
|
|
}
|
|
}
|
|
}
|