浏览代码

[Breaking] Moved volume components & profiles to disk-based assets

Because prefabs, copy-pasting, etc...
/main
Thomas 7 年前
当前提交
bee1cad8
共有 22 个文件被更改,包括 1121 次插入516 次删除
  1. 2
      SampleScenes/HDTest/AnimTest/ThreeDScans/Gutenberg/Materials.meta
  2. 65
      SampleScenes/HDTest/AnimTest2.unity
  3. 5
      ScriptableRenderPipeline/Core/CoreRP/Editor/FilterWindow.cs
  4. 1
      ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeComponentEditor.cs
  5. 6
      ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeComponentProvider.cs
  6. 430
      ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeEditor.cs
  7. 140
      ScriptableRenderPipeline/Core/CoreRP/Volume/Volume.cs
  8. 10
      ScriptableRenderPipeline/Core/CoreRP/Volume/VolumeManager.cs
  9. 16
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDRenderPipelineMenuItems.cs
  10. 68
      SampleScenes/HDTest/AnimTest/Scene Settings.asset
  11. 8
      SampleScenes/HDTest/AnimTest/Scene Settings.asset.meta
  12. 377
      ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeComponentListEditor.cs
  13. 11
      ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeComponentListEditor.cs.meta
  14. 29
      ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeProfileEditor.cs
  15. 11
      ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeProfileEditor.cs.meta
  16. 72
      ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeProfileFactory.cs
  17. 11
      ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeProfileFactory.cs.meta
  18. 108
      ScriptableRenderPipeline/Core/CoreRP/Volume/VolumeProfile.cs
  19. 11
      ScriptableRenderPipeline/Core/CoreRP/Volume/VolumeProfile.cs.meta
  20. 248
      SampleScenes/HDTest/AnimTest/ThreeDScans/Gutenberg/Materials/Gutenberg.mat
  21. 8
      SampleScenes/HDTest/AnimTest/ThreeDScans/Gutenberg/Materials/Gutenberg.mat.meta

2
SampleScenes/HDTest/AnimTest/ThreeDScans/Gutenberg/Materials.meta


fileFormatVersion: 2
guid: 3a4343f81dd267d4cbbd6726951946b3
guid: 71626f54dd039ee409ecadf9e4710bbc
folderAsset: yes
DefaultImporter:
externalObjects: {}

65
SampleScenes/HDTest/AnimTest2.unity


m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.2434549, g: 0.2638216, b: 0.3143337, a: 1}
m_IndirectSpecularColor: {r: 0.24345492, g: 0.2638216, b: 0.3143337, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:

m_Father: {fileID: 0}
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &335504040
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0d7593b3a9277ac4696b20006c21dde2, type: 3}
m_Name:
m_EditorClassIdentifier:
active: 1
skyType:
m_OverrideState: 1
m_Value: 1
fogType:
m_OverrideState: 0
m_Value: 0
--- !u!1 &450944471
GameObject:
m_ObjectHideFlags: 0

priority: 0
blendDistance: 0
weight: 1
components:
- {fileID: 335504040}
- {fileID: 1585182893}
sharedProfile: {fileID: 11400000, guid: 1b08b24317b158e47a108d8c1da634a8, type: 2}
--- !u!4 &450944473
Transform:
m_ObjectHideFlags: 0

stationaryBlending: 0.95
motionBlending: 0.85
fastApproximateAntialiasing:
mobileOptimized: 0
fastMode: 0
keepAlpha: 0
fog:
enabled: 1

m_Script: {fileID: 11500000, guid: c6c2871f720b2af4e9210febdac74517, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Version: 1
shadowResolution: 2048
shadowDimmer: 1
shadowFadeDistance: 10000

useOldInspector: 0
featuresFoldout: 1
showAdditionalSettings: 0
--- !u!114 &1585182893
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 59b6606ef2548734bb6d11b9d160bc7e, type: 3}
m_Name:
m_EditorClassIdentifier:
active: 1
rotation:
m_OverrideState: 0
m_Value: 0
min: 0
max: 360
exposure:
m_OverrideState: 0
m_Value: 0
multiplier:
m_OverrideState: 0
m_Value: 1
min: 0
resolution:
m_OverrideState: 1
m_Value: 256
updateMode:
m_OverrideState: 0
m_Value: 0
updatePeriod:
m_OverrideState: 0
m_Value: 0
min: 0
useForBaking: 1
skyHDRI:
m_OverrideState: 1
m_Value: {fileID: 8900000, guid: a484b152a713c486e98ed7a992f53a51, type: 3}
--- !u!1 &1685946095
GameObject:
m_ObjectHideFlags: 0

5
ScriptableRenderPipeline/Core/CoreRP/Editor/FilterWindow.cs


internal void OnGUI()
{
// Avoids errors in the console if a domain reload is triggered while the filter window
// is opened
if (m_Provider == null)
return;
if (s_Styles == null)
s_Styles = new Styles();

1
ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeComponentEditor.cs


}
}
// TODO: Doesn't work correctly with indented controls, fixme
protected void DrawOverrideCheckbox(SerializedDataParameter property)
{
var overrideRect = GUILayoutUtility.GetRect(17f, 17f, GUILayout.ExpandWidth(false));

6
ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeComponentProvider.cs


public Vector2 position { get; set; }
Volume m_Target;
VolumeEditor m_TargetEditor;
VolumeProfile m_Target;
VolumeComponentListEditor m_TargetEditor;
public VolumeComponentProvider(Volume target, VolumeEditor targetEditor)
public VolumeComponentProvider(VolumeProfile target, VolumeComponentListEditor targetEditor)
{
m_Target = target;
m_TargetEditor = targetEditor;

430
ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeEditor.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Assertions;
public sealed class VolumeEditor : Editor
sealed class VolumeEditor : Editor
SerializedProperty m_Components;
Dictionary<Type, Type> m_EditorTypes; // Component type => Editor type
List<VolumeComponentEditor> m_Editors;
SerializedProperty m_Profile;
static VolumeComponent s_ClipboardContent;
VolumeComponentListEditor m_ComponentList;
Volume actualTarget
{

m_BlendRadius = o.Find(x => x.blendDistance);
m_Weight = o.Find(x => x.weight);
m_Priority = o.Find(x => x.priority);
m_Components = o.Find(x => x.components);
m_EditorTypes = new Dictionary<Type, Type>();
m_Editors = new List<VolumeComponentEditor>();
// Gets the list of all available component editors
var editorTypes = CoreUtils.GetAllAssemblyTypes()
.Where(
t => t.IsSubclassOf(typeof(VolumeComponentEditor))
&& t.IsDefined(typeof(VolumeComponentEditorAttribute), false)
&& !t.IsAbstract
);
// Map them to their corresponding component type
foreach (var editorType in editorTypes)
{
var attribute = (VolumeComponentEditorAttribute)editorType.GetCustomAttributes(typeof(VolumeComponentEditorAttribute), false)[0];
m_EditorTypes.Add(attribute.componentType, editorType);
}
// Create editors for existing components
var components = actualTarget.components;
for (int i = 0; i < components.Count; i++)
CreateEditor(components[i], m_Components.GetArrayElementAtIndex(i));
m_Profile = o.Find(x => x.sharedProfile);
// Keep track of undo/redo to redraw the inspector when that happens
Undo.undoRedoPerformed += OnUndoRedoPerformed;
m_ComponentList = new VolumeComponentListEditor(this);
RefreshEffectListEditor(actualTarget.sharedProfile);
Undo.undoRedoPerformed -= OnUndoRedoPerformed;
if (m_ComponentList != null)
m_ComponentList.Clear();
}
if (m_Editors == null)
return; // Hasn't been inited yet
foreach (var editor in m_Editors)
editor.OnDisable();
void RefreshEffectListEditor(VolumeProfile asset)
{
m_ComponentList.Clear();
m_Editors.Clear();
m_EditorTypes.Clear();
if (asset != null)
m_ComponentList.Init(asset, new SerializedObject(asset));
}
public override void OnInspectorGUI()

if (actualTarget.isDirty)
EditorGUILayout.PropertyField(m_IsGlobal);
if (!m_IsGlobal.boolValue) // Blend radius is not needed for global volumes
RefreshEditors();
actualTarget.isDirty = false;
EditorGUILayout.PropertyField(m_BlendRadius);
m_BlendRadius.floatValue = Mathf.Max(m_BlendRadius.floatValue, 0f);
using (var vscope = new EditorGUILayout.VerticalScope())
{
EditorGUILayout.PropertyField(m_IsGlobal);
EditorGUILayout.PropertyField(m_Weight);
EditorGUILayout.PropertyField(m_Priority);
if (!m_IsGlobal.boolValue) // Blend radius is not needed for global volumes
{
EditorGUILayout.PropertyField(m_BlendRadius);
m_BlendRadius.floatValue = Mathf.Max(m_BlendRadius.floatValue, 0f);
}
bool assetHasChanged = false;
bool showCopy = m_Profile.objectReferenceValue != null;
bool multiEdit = m_Profile.hasMultipleDifferentValues;
EditorGUILayout.PropertyField(m_Weight);
EditorGUILayout.PropertyField(m_Priority);
// The layout system breaks alignement when mixing inspector fields with custom layouted
// fields, do the layout manually instead
int buttonWidth = showCopy ? 45 : 60;
float indentOffset = EditorGUI.indentLevel * 15f;
var lineRect = GUILayoutUtility.GetRect(1, EditorGUIUtility.singleLineHeight);
var labelRect = new Rect(lineRect.x, lineRect.y, EditorGUIUtility.labelWidth - indentOffset, lineRect.height);
var fieldRect = new Rect(labelRect.xMax, lineRect.y, lineRect.width - labelRect.width - buttonWidth * (showCopy ? 2 : 1), lineRect.height);
var buttonNewRect = new Rect(fieldRect.xMax, lineRect.y, buttonWidth, lineRect.height);
var buttonCopyRect = new Rect(buttonNewRect.xMax, lineRect.y, buttonWidth, lineRect.height);
EditorGUILayout.Space();
EditorGUI.PrefixLabel(labelRect, CoreEditorUtils.GetContent("Profile|A reference to a profile asset."));
// Component list
for (int i = 0; i < m_Editors.Count; i++)
{
var editor = m_Editors[i];
string title = editor.GetDisplayTitle();
int id = i; // Needed for closure capture below
using (var scope = new EditorGUI.ChangeCheckScope())
{
EditorGUI.BeginProperty(fieldRect, GUIContent.none, m_Profile);
CoreEditorUtils.DrawSplitter();
bool displayContent = CoreEditorUtils.DrawHeaderToggle(
title,
editor.baseProperty,
editor.activeProperty,
pos => OnContextClick(pos, editor.target, id)
);
var profile = (VolumeProfile)EditorGUI.ObjectField(fieldRect, m_Profile.objectReferenceValue, typeof(VolumeProfile), false);
if (displayContent)
{
using (new EditorGUI.DisabledScope(!editor.activeProperty.boolValue))
editor.OnInternalInspectorGUI();
}
if (scope.changed)
{
assetHasChanged = true;
m_Profile.objectReferenceValue = profile;
if (m_Editors.Count > 0)
CoreEditorUtils.DrawSplitter();
else
EditorGUILayout.HelpBox("No override set on this volume. Drop a component here or use the Add button.", MessageType.Info);
EditorGUI.EndProperty();
}
EditorGUILayout.Space();
using (var hscope = new EditorGUILayout.HorizontalScope())
using (new EditorGUI.DisabledScope(multiEdit))
{
if (GUI.Button(buttonNewRect, CoreEditorUtils.GetContent("New|Create a new profile."), showCopy ? EditorStyles.miniButtonLeft : EditorStyles.miniButton))
if (GUILayout.Button(CoreEditorUtils.GetContent("Add component overrides..."), EditorStyles.miniButton))
{
var r = hscope.rect;
var pos = new Vector2(r.x + r.width / 2f, r.yMax + 18f);
FilterWindow.Show(pos, new VolumeComponentProvider(actualTarget, this));
}
// By default, try to put assets in a folder next to the currently active
// scene file. If the user isn't a scene, put them in root instead.
var targetName = actualTarget.name;
var scene = actualTarget.gameObject.scene;
var asset = VolumeProfileFactory.CreateVolumeProfile(scene, targetName);
m_Profile.objectReferenceValue = asset;
assetHasChanged = true;
EditorGUILayout.Space();
if (showCopy && GUI.Button(buttonCopyRect, CoreEditorUtils.GetContent("Clone|Create a new profile and copy the content of the currently assigned profile."), EditorStyles.miniButtonRight))
{
// Duplicate the currently assigned profile and save it as a new profile
var origin = (VolumeProfile)m_Profile.objectReferenceValue;
var path = AssetDatabase.GetAssetPath(origin);
path = AssetDatabase.GenerateUniqueAssetPath(path);
var asset = Instantiate(origin);
asset.components.Clear();
AssetDatabase.CreateAsset(asset, path);
// Handle components drag'n'drop
var e = Event.current;
if (e.type == EventType.DragUpdated)
{
if (IsDragValid(vscope.rect, e.mousePosition))
foreach (var item in origin.components)
DragAndDrop.visualMode = DragAndDropVisualMode.Link;
e.Use();
}
else
{
DragAndDrop.visualMode = DragAndDropVisualMode.Rejected;
var itemCopy = Instantiate(item);
itemCopy.hideFlags = HideFlags.HideInInspector | HideFlags.HideInHierarchy;
itemCopy.name = item.name;
asset.components.Add(itemCopy);
AssetDatabase.AddObjectToAsset(itemCopy, asset);
}
else if (e.type == EventType.DragPerform)
{
if (IsDragValid(vscope.rect, e.mousePosition))
{
DragAndDrop.AcceptDrag();
var objs = DragAndDrop.objectReferences;
foreach (var o in objs)
{
var compType = ((MonoScript)o).GetClass();
AddComponent(compType);
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
e.Use();
}
m_Profile.objectReferenceValue = asset;
assetHasChanged = true;
serializedObject.ApplyModifiedProperties();
}
EditorGUILayout.Space();
bool IsDragValid(Rect rect, Vector2 mousePos)
{
if (!rect.Contains(mousePos))
return false;
var objs = DragAndDrop.objectReferences;
foreach (var o in objs)
if (m_Profile.objectReferenceValue == null)
if (o.GetType() != typeof(MonoScript))
return false;
var script = (MonoScript)o;
var scriptType = script.GetClass();
if (!scriptType.IsSubclassOf(typeof(VolumeComponent)) || scriptType.IsAbstract)
return false;
if (actualTarget.components.Exists(t => t.GetType() == scriptType))
return false;
if (assetHasChanged)
m_ComponentList.Clear(); // Asset wasn't null before, do some cleanup
return true;
}
void RefreshEditors()
{
// Disable all editors first
foreach (var editor in m_Editors)
editor.OnDisable();
// Remove them
m_Editors.Clear();
// Recreate editors for existing settings, if any
for (int i = 0; i < actualTarget.components.Count; i++)
CreateEditor(actualTarget.components[i], m_Components.GetArrayElementAtIndex(i));
}
// index is only used when we need to re-create a component in a specific spot (e.g. reset)
void CreateEditor(VolumeComponent settings, SerializedProperty property, int index = -1, bool forceOpen = false)
{
var settingsType = settings.GetType();
Type editorType;
if (!m_EditorTypes.TryGetValue(settingsType, out editorType))
editorType = typeof(VolumeComponentEditor);
var editor = (VolumeComponentEditor)Activator.CreateInstance(editorType);
editor.Init(settings, this);
editor.baseProperty = property.Copy();
if (forceOpen)
editor.baseProperty.isExpanded = true;
if (index < 0)
m_Editors.Add(editor);
m_Editors[index] = editor;
}
internal void AddComponent(Type type)
{
serializedObject.Update();
var component = (VolumeComponent)CreateInstance(type);
Undo.RegisterCreatedObjectUndo(component, "Add Volume Component");
// Grow the list first, then add - that's how serialized lists work in Unity
m_Components.arraySize++;
var effectProp = m_Components.GetArrayElementAtIndex(m_Components.arraySize - 1);
effectProp.objectReferenceValue = component;
// Create & store the internal editor object for this effect
CreateEditor(component, effectProp, forceOpen: true);
serializedObject.ApplyModifiedProperties();
}
internal void RemoveComponent(int id)
{
// Huh. Hack to keep foldout state on the next element...
bool nextFoldoutState = false;
if (id < m_Editors.Count - 1)
nextFoldoutState = m_Editors[id + 1].baseProperty.isExpanded;
// Remove from the cached editors list
m_Editors[id].OnDisable();
m_Editors.RemoveAt(id);
serializedObject.Update();
var property = m_Components.GetArrayElementAtIndex(id);
var effect = property.objectReferenceValue;
// Unassign it (should be null already but serialization does funky things
property.objectReferenceValue = null;
// ...and remove the array index itself from the list
m_Components.DeleteArrayElementAtIndex(id);
// Finally refresh editor reference to the serialized settings list
for (int i = 0; i < m_Editors.Count; i++)
m_Editors[i].baseProperty = m_Components.GetArrayElementAtIndex(i).Copy();
// Set the proper foldout state if needed
if (id < m_Editors.Count)
m_Editors[id].baseProperty.isExpanded = nextFoldoutState;
serializedObject.ApplyModifiedProperties();
{
if (assetHasChanged)
RefreshEffectListEditor((VolumeProfile)m_Profile.objectReferenceValue);
// Destroy the setting object after ApplyModifiedProperties(). If we do it before, redo
// actions will be in the wrong order and the reference to the setting object in the
// list will be lost.
Undo.DestroyObjectImmediate(effect);
}
// Reset is done by deleting and removing the object from the list and adding a new one in
// the same spot as it was before
internal void ResetComponent(Type type, int id)
{
// Remove from the cached editors list
m_Editors[id].OnDisable();
m_Editors[id] = null;
serializedObject.Update();
var property = m_Components.GetArrayElementAtIndex(id);
var prevSettings = property.objectReferenceValue;
// Unassign it but down remove it from the array to keep the index available
property.objectReferenceValue = null;
// Create a new object
var newEffect = (VolumeComponent)CreateInstance(type);
Undo.RegisterCreatedObjectUndo(newEffect, "Reset Volume Component");
// Put it in the reserved space
property.objectReferenceValue = newEffect;
// Create & store the internal editor object for this effect
CreateEditor(newEffect, property, id);
serializedObject.ApplyModifiedProperties();
// Same as RemoveComponent, destroy at the end so it's recreated first on Undo to make
// sure the GUID exists before undoing the list state
Undo.DestroyObjectImmediate(prevSettings);
}
internal void MoveComponent(int id, int offset)
{
// Move components
serializedObject.Update();
m_Components.MoveArrayElement(id, id + offset);
serializedObject.ApplyModifiedProperties();
// Move editors
var prev = m_Editors[id + offset];
m_Editors[id + offset] = m_Editors[id];
m_Editors[id] = prev;
}
void OnContextClick(Vector2 position, VolumeComponent targetComponent, int id)
{
var menu = new GenericMenu();
if (id == 0)
menu.AddDisabledItem(CoreEditorUtils.GetContent("Move Up"));
else
menu.AddItem(CoreEditorUtils.GetContent("Move Up"), false, () => MoveComponent(id, -1));
if (id == m_Editors.Count - 1)
menu.AddDisabledItem(CoreEditorUtils.GetContent("Move Down"));
else
menu.AddItem(CoreEditorUtils.GetContent("Move Down"), false, () => MoveComponent(id, 1));
menu.AddSeparator(string.Empty);
menu.AddItem(CoreEditorUtils.GetContent("Reset"), false, () => ResetComponent(targetComponent.GetType(), id));
menu.AddItem(CoreEditorUtils.GetContent("Remove"), false, () => RemoveComponent(id));
menu.AddSeparator(string.Empty);
menu.AddItem(CoreEditorUtils.GetContent("Copy Settings"), false, () => CopySettings(targetComponent));
if (CanPaste(targetComponent))
menu.AddItem(CoreEditorUtils.GetContent("Paste Settings"), false, () => PasteSettings(targetComponent));
else
menu.AddDisabledItem(CoreEditorUtils.GetContent("Paste Settings"));
menu.AddSeparator(string.Empty);
menu.AddItem(CoreEditorUtils.GetContent("Toggle All"), false, () => m_Editors[id].SetAllOverridesTo(true));
menu.AddItem(CoreEditorUtils.GetContent("Toggle None"), false, () => m_Editors[id].SetAllOverridesTo(false));
menu.DropDown(new Rect(position, Vector2.zero));
}
// Copy/pasting is simply done by creating an in memory copy of the selected component and
// copying over the serialized data to another; it doesn't use nor affect the OS clipboard
bool CanPaste(VolumeComponent targetComponent)
{
return s_ClipboardContent != null
&& s_ClipboardContent.GetType() == targetComponent.GetType();
}
void CopySettings(VolumeComponent targetComponent)
{
if (s_ClipboardContent != null)
{
CoreUtils.Destroy(s_ClipboardContent);
s_ClipboardContent = null;
if (!multiEdit)
{
m_ComponentList.OnGUI();
EditorGUILayout.Space();
}
s_ClipboardContent = (VolumeComponent)CreateInstance(targetComponent.GetType());
EditorUtility.CopySerializedIfDifferent(targetComponent, s_ClipboardContent);
}
void PasteSettings(VolumeComponent targetComponent)
{
Assert.IsNotNull(s_ClipboardContent);
Assert.AreEqual(s_ClipboardContent.GetType(), targetComponent.GetType());
Undo.RecordObject(targetComponent, "Paste Settings");
EditorUtility.CopySerializedIfDifferent(s_ClipboardContent, targetComponent);
}
void OnUndoRedoPerformed()
{
actualTarget.isDirty = true;
// Dumb hack to make sure the serialized object is up to date on undo
serializedObject.Update();
// Seems like there's an issue with the inspector not repainting after some undo events
// This will take care of that
Repaint();
}
}
}

140
ScriptableRenderPipeline/Core/CoreRP/Volume/Volume.cs


using System;
using System.Collections.Generic;
namespace UnityEngine.Experimental.Rendering

[Range(0f, 1f), Tooltip("Total weight of this volume in the scene. 0 means it won't do anything, 1 means full effect.")]
public float weight = 1f;
public List<VolumeComponent> components = new List<VolumeComponent>();
// Modifying sharedProfile will change the behavior of all volumes using this profile, and
// change profile settings that are stored in the project too
public VolumeProfile sharedProfile;
// This property automatically instantiates the profile and makes it unique to this volume
// so you can safely edit it via scripting at runtime without changing the original asset
// in the project.
// Note that if you pass in your own profile, it is your responsability to destroy it once
// it's not in use anymore.
public VolumeProfile profile
{
get
{
if (m_InternalProfile == null)
{
m_InternalProfile = ScriptableObject.CreateInstance<VolumeProfile>();
// Editor-only
[NonSerialized]
public bool isDirty;
if (sharedProfile != null)
{
foreach (var item in sharedProfile.components)
{
var itemCopy = Instantiate(item);
m_InternalProfile.components.Add(itemCopy);
}
}
}
return m_InternalProfile;
}
set
{
m_InternalProfile = value;
}
}
internal VolumeProfile profileRef
{
get
{
return m_InternalProfile == null
? sharedProfile
: m_InternalProfile;
}
}
VolumeProfile m_InternalProfile;
// Make sure every setting is valid. If a profile holds a script that doesn't exist
// anymore, nuke it to keep the volume clean. Note that if you delete a script that is
// currently in use in a volume you'll still get a one-time error in the console, it's
// harmless and happens because Unity does a redraw of the editor (and thus the current
// frame) before the recompilation step.
components.RemoveAll(x => x == null);
m_PreviousLayer = gameObject.layer;
VolumeManager.instance.Register(this, m_PreviousLayer);
}

VolumeManager.instance.Unregister(this, gameObject.layer);
}
void Reset()
{
isDirty = true;
}
void Update()

VolumeManager.instance.SetLayerDirty(layer);
m_PreviousPriority = priority;
}
}
public T Add<T>(bool overrides = false)
where T : VolumeComponent
{
return (T)Add(typeof(T), overrides);
}
public VolumeComponent Add(Type type, bool overrides = false)
{
if (Has(type))
throw new InvalidOperationException("Component already exists in the volume");
var component = (VolumeComponent)ScriptableObject.CreateInstance(type);
component.SetAllOverridesTo(overrides);
components.Add(component);
isDirty = true;
return component;
}
public void Remove<T>()
where T : VolumeComponent
{
Remove(typeof(T));
}
public void Remove(Type type)
{
int toRemove = -1;
for (int i = 0; i < components.Count; i++)
{
if (components[i].GetType() == type)
{
toRemove = i;
break;
}
}
if (toRemove >= 0)
{
components.RemoveAt(toRemove);
isDirty = true;
}
}
public bool Has<T>()
where T : VolumeComponent
{
return Has(typeof(T));
}
public bool Has(Type type)
{
foreach (var component in components)
{
if (component.GetType() == type)
return true;
}
return false;
}
public bool TryGet<T>(out T component)
where T : VolumeComponent
{
var type = typeof(T);
component = null;
foreach (var comp in components)
{
if (comp.GetType() == type)
{
component = (T)comp;
return true;
}
}
return false;
}
#if UNITY_EDITOR

10
ScriptableRenderPipeline/Core/CoreRP/Volume/VolumeManager.cs


foreach (var volume in kvp.Value)
{
if (!volume.enabled)
if (!volume.enabled || volume.profileRef == null)
if (volume.TryGet(out component) && component.active)
if (volume.profileRef.TryGet(out component) && component.active)
return true;
}
}

foreach (var volume in volumes)
{
// Skip disabled volumes and volumes without any data or weight
if (!volume.enabled || volume.weight <= 0f)
if (!volume.enabled || volume.profileRef == null || volume.weight <= 0f)
OverrideData(stack, volume.components, Mathf.Clamp01(volume.weight));
OverrideData(stack, volume.profileRef.components, Mathf.Clamp01(volume.weight));
continue;
}

interpFactor = 1f - (closestDistanceSqr / blendDistSqr);
// No need to clamp01 the interpolation factor as it'll always be in [0;1[ range
OverrideData(stack, volume.components, interpFactor * Mathf.Clamp01(volume.weight));
OverrideData(stack, volume.profileRef.components, interpFactor * Mathf.Clamp01(volume.weight));
}
}

16
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDRenderPipelineMenuItems.cs


GameObjectUtility.SetParentAndAlign(sceneSettings, menuCommand.context as GameObject);
Undo.RegisterCreatedObjectUndo(sceneSettings, "Create " + sceneSettings.name);
Selection.activeObject = sceneSettings;
var volume = sceneSettings.AddComponent<Volume>();
volume.isGlobal = true;
volume.Add<HDShadowSettings>(true);
var visualEnv = volume.Add<VisualEnvironment>(true);
var profile = VolumeProfileFactory.CreateVolumeProfile(sceneSettings.scene, "Scene Settings");
profile.Add<HDShadowSettings>(true);
var visualEnv = profile.Add<VisualEnvironment>(true);
volume.Add<ProceduralSky>(true);
volume.Add<ExponentialFog>(true);
profile.Add<ProceduralSky>(true);
profile.Add<ExponentialFog>(true);
var volume = sceneSettings.AddComponent<Volume>();
volume.isGlobal = true;
volume.sharedProfile = profile;
}
class DoCreateNewAsset<TAssetType> : ProjectWindowCallback.EndNameEditAction where TAssetType : ScriptableObject

68
SampleScenes/HDTest/AnimTest/Scene Settings.asset


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d7fd9488000d3734a9e00ee676215985, type: 3}
m_Name: New Volume Profile
m_EditorClassIdentifier:
components:
- {fileID: 114030632975742018}
--- !u!114 &114030632975742018
MonoBehaviour:
m_ObjectHideFlags: 3
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0d7593b3a9277ac4696b20006c21dde2, type: 3}
m_Name: VisualEnvironment
m_EditorClassIdentifier:
active: 1
skyType:
m_OverrideState: 1
m_Value: 1
fogType:
m_OverrideState: 0
m_Value: 0
--- !u!114 &114738636232829174
MonoBehaviour:
m_ObjectHideFlags: 3
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 59b6606ef2548734bb6d11b9d160bc7e, type: 3}
m_Name: HDRISky
m_EditorClassIdentifier:
active: 1
rotation:
m_OverrideState: 0
m_Value: 0
min: 0
max: 360
exposure:
m_OverrideState: 0
m_Value: 0
multiplier:
m_OverrideState: 0
m_Value: 1
min: 0
updateMode:
m_OverrideState: 0
m_Value: 0
updatePeriod:
m_OverrideState: 0
m_Value: 0
min: 0
useForBaking: 0
skyHDRI:
m_OverrideState: 0
m_Value: {fileID: 0}

8
SampleScenes/HDTest/AnimTest/Scene Settings.asset.meta


fileFormatVersion: 2
guid: a96b0d1a526de994ba6e83b6d9f369c8
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

377
ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeComponentListEditor.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.Experimental.Rendering;
namespace UnityEditor.Experimental.Rendering
{
public sealed class VolumeComponentListEditor
{
Editor m_BaseEditor;
VolumeProfile m_Asset;
SerializedObject m_SerializedObject;
SerializedProperty m_ComponentsProperty;
Dictionary<Type, Type> m_EditorTypes; // Component type => Editor type
List<VolumeComponentEditor> m_Editors;
static VolumeComponent s_ClipboardContent;
public VolumeComponentListEditor(Editor editor)
{
Assert.IsNotNull(editor);
m_BaseEditor = editor;
}
public void Init(VolumeProfile asset, SerializedObject serializedObject)
{
Assert.IsNotNull(asset);
Assert.IsNotNull(serializedObject);
m_Asset = asset;
m_SerializedObject = serializedObject;
m_ComponentsProperty = new PropertyFetcher<VolumeProfile>(serializedObject).Find(x => x.components);
Assert.IsNotNull(m_ComponentsProperty);
m_EditorTypes = new Dictionary<Type, Type>();
m_Editors = new List<VolumeComponentEditor>();
// Gets the list of all available component editors
var editorTypes = CoreUtils.GetAllAssemblyTypes()
.Where(
t => t.IsSubclassOf(typeof(VolumeComponentEditor))
&& t.IsDefined(typeof(VolumeComponentEditorAttribute), false)
&& !t.IsAbstract
);
// Map them to their corresponding component type
foreach (var editorType in editorTypes)
{
var attribute = (VolumeComponentEditorAttribute)editorType.GetCustomAttributes(typeof(VolumeComponentEditorAttribute), false)[0];
m_EditorTypes.Add(attribute.componentType, editorType);
}
// Create editors for existing components
var components = asset.components;
for (int i = 0; i < components.Count; i++)
CreateEditor(components[i], m_ComponentsProperty.GetArrayElementAtIndex(i));
// Keep track of undo/redo to redraw the inspector when that happens
Undo.undoRedoPerformed += OnUndoRedoPerformed;
}
void OnUndoRedoPerformed()
{
m_Asset.isDirty = true;
// Dumb hack to make sure the serialized object is up to date on undo (else there'll be
// a state mismatch when this class is used in a GameObject inspector).
m_SerializedObject.Update();
m_SerializedObject.ApplyModifiedProperties();
// Seems like there's an issue with the inspector not repainting after some undo events
// This will take care of that
m_BaseEditor.Repaint();
}
// index is only used when we need to re-create a component in a specific spot (e.g. reset)
void CreateEditor(VolumeComponent component, SerializedProperty property, int index = -1, bool forceOpen = false)
{
var componentType = component.GetType();
Type editorType;
if (!m_EditorTypes.TryGetValue(componentType, out editorType))
editorType = typeof(VolumeComponentEditor);
var editor = (VolumeComponentEditor)Activator.CreateInstance(editorType);
editor.Init(component, m_BaseEditor);
editor.baseProperty = property.Copy();
if (forceOpen)
editor.baseProperty.isExpanded = true;
if (index < 0)
m_Editors.Add(editor);
else
m_Editors[index] = editor;
}
void RefreshEditors()
{
// Disable all editors first
foreach (var editor in m_Editors)
editor.OnDisable();
// Remove them
m_Editors.Clear();
// Recreate editors for existing settings, if any
for (int i = 0; i < m_Asset.components.Count; i++)
CreateEditor(m_Asset.components[i], m_ComponentsProperty.GetArrayElementAtIndex(i));
}
public void Clear()
{
if (m_Editors == null)
return; // Hasn't been inited yet
foreach (var editor in m_Editors)
editor.OnDisable();
m_Editors.Clear();
m_EditorTypes.Clear();
// ReSharper disable once DelegateSubtraction
Undo.undoRedoPerformed -= OnUndoRedoPerformed;
}
public void OnGUI()
{
if (m_Asset == null)
return;
if (m_Asset.isDirty)
{
RefreshEditors();
m_Asset.isDirty = false;
}
bool isEditable = !VersionControl.Provider.isActive
|| AssetDatabase.IsOpenForEdit(m_Asset, StatusQueryOptions.UseCachedIfPossible);
using (new EditorGUI.DisabledScope(!isEditable))
{
// Component list
for (int i = 0; i < m_Editors.Count; i++)
{
var editor = m_Editors[i];
string title = editor.GetDisplayTitle();
int id = i; // Needed for closure capture below
CoreEditorUtils.DrawSplitter();
bool displayContent = CoreEditorUtils.DrawHeaderToggle(
title,
editor.baseProperty,
editor.activeProperty,
pos => OnContextClick(pos, editor.target, id)
);
if (displayContent)
{
using (new EditorGUI.DisabledScope(!editor.activeProperty.boolValue))
editor.OnInternalInspectorGUI();
}
}
if (m_Editors.Count > 0)
CoreEditorUtils.DrawSplitter();
else
EditorGUILayout.HelpBox("No override set on this volume. Drop a component here or use the Add button.", MessageType.Info);
EditorGUILayout.Space();
using (var hscope = new EditorGUILayout.HorizontalScope())
{
if (GUILayout.Button(CoreEditorUtils.GetContent("Add component overrides..."), EditorStyles.miniButton))
{
var r = hscope.rect;
var pos = new Vector2(r.x + r.width / 2f, r.yMax + 18f);
FilterWindow.Show(pos, new VolumeComponentProvider(m_Asset, this));
}
}
}
}
void OnContextClick(Vector2 position, VolumeComponent targetComponent, int id)
{
var menu = new GenericMenu();
if (id == 0)
menu.AddDisabledItem(CoreEditorUtils.GetContent("Move Up"));
else
menu.AddItem(CoreEditorUtils.GetContent("Move Up"), false, () => MoveComponent(id, -1));
if (id == m_Editors.Count - 1)
menu.AddDisabledItem(CoreEditorUtils.GetContent("Move Down"));
else
menu.AddItem(CoreEditorUtils.GetContent("Move Down"), false, () => MoveComponent(id, 1));
menu.AddSeparator(string.Empty);
menu.AddItem(CoreEditorUtils.GetContent("Reset"), false, () => ResetComponent(targetComponent.GetType(), id));
menu.AddItem(CoreEditorUtils.GetContent("Remove"), false, () => RemoveComponent(id));
menu.AddSeparator(string.Empty);
menu.AddItem(CoreEditorUtils.GetContent("Copy Settings"), false, () => CopySettings(targetComponent));
if (CanPaste(targetComponent))
menu.AddItem(CoreEditorUtils.GetContent("Paste Settings"), false, () => PasteSettings(targetComponent));
else
menu.AddDisabledItem(CoreEditorUtils.GetContent("Paste Settings"));
menu.AddSeparator(string.Empty);
menu.AddItem(CoreEditorUtils.GetContent("Toggle All"), false, () => m_Editors[id].SetAllOverridesTo(true));
menu.AddItem(CoreEditorUtils.GetContent("Toggle None"), false, () => m_Editors[id].SetAllOverridesTo(false));
menu.DropDown(new Rect(position, Vector2.zero));
}
VolumeComponent CreateNewComponent(Type type)
{
var effect = (VolumeComponent)ScriptableObject.CreateInstance(type);
effect.hideFlags = HideFlags.HideInInspector | HideFlags.HideInHierarchy;
effect.name = type.Name;
return effect;
}
internal void AddComponent(Type type)
{
m_SerializedObject.Update();
var component = CreateNewComponent(type);
Undo.RegisterCreatedObjectUndo(component, "Add Volume Component");
// Store this new effect as a subasset so we can reference it safely afterwards
AssetDatabase.AddObjectToAsset(component, m_Asset);
// Grow the list first, then add - that's how serialized lists work in Unity
m_ComponentsProperty.arraySize++;
var componentProp = m_ComponentsProperty.GetArrayElementAtIndex(m_ComponentsProperty.arraySize - 1);
componentProp.objectReferenceValue = component;
// Force save / refresh
EditorUtility.SetDirty(m_Asset);
AssetDatabase.SaveAssets();
// Create & store the internal editor object for this effect
CreateEditor(component, componentProp, forceOpen: true);
m_SerializedObject.ApplyModifiedProperties();
}
internal void RemoveComponent(int id)
{
// Huh. Hack to keep foldout state on the next element...
bool nextFoldoutState = false;
if (id < m_Editors.Count - 1)
nextFoldoutState = m_Editors[id + 1].baseProperty.isExpanded;
// Remove from the cached editors list
m_Editors[id].OnDisable();
m_Editors.RemoveAt(id);
m_SerializedObject.Update();
var property = m_ComponentsProperty.GetArrayElementAtIndex(id);
var component = property.objectReferenceValue;
// Unassign it (should be null already but serialization does funky things
property.objectReferenceValue = null;
// ...and remove the array index itself from the list
m_ComponentsProperty.DeleteArrayElementAtIndex(id);
// Finally refresh editor reference to the serialized settings list
for (int i = 0; i < m_Editors.Count; i++)
m_Editors[i].baseProperty = m_ComponentsProperty.GetArrayElementAtIndex(i).Copy();
// Set the proper foldout state if needed
if (id < m_Editors.Count)
m_Editors[id].baseProperty.isExpanded = nextFoldoutState;
m_SerializedObject.ApplyModifiedProperties();
// Destroy the setting object after ApplyModifiedProperties(). If we do it before, redo
// actions will be in the wrong order and the reference to the setting object in the
// list will be lost.
Undo.DestroyObjectImmediate(component);
// Force save / refresh
EditorUtility.SetDirty(m_Asset);
AssetDatabase.SaveAssets();
}
// Reset is done by deleting and removing the object from the list and adding a new one in
// the same spot as it was before
internal void ResetComponent(Type type, int id)
{
// Remove from the cached editors list
m_Editors[id].OnDisable();
m_Editors[id] = null;
m_SerializedObject.Update();
var property = m_ComponentsProperty.GetArrayElementAtIndex(id);
var prevComponent = property.objectReferenceValue;
// Unassign it but down remove it from the array to keep the index available
property.objectReferenceValue = null;
// Create a new object
var newComponent = CreateNewComponent(type);
Undo.RegisterCreatedObjectUndo(newComponent, "Reset Volume Component");
// Store this new effect as a subasset so we can reference it safely afterwards
AssetDatabase.AddObjectToAsset(newComponent, m_Asset);
// Put it in the reserved space
property.objectReferenceValue = newComponent;
// Create & store the internal editor object for this effect
CreateEditor(newComponent, property, id);
m_SerializedObject.ApplyModifiedProperties();
// Same as RemoveComponent, destroy at the end so it's recreated first on Undo to make
// sure the GUID exists before undoing the list state
Undo.DestroyObjectImmediate(prevComponent);
// Force save / refresh
EditorUtility.SetDirty(m_Asset);
AssetDatabase.SaveAssets();
}
internal void MoveComponent(int id, int offset)
{
// Move components
m_SerializedObject.Update();
m_ComponentsProperty.MoveArrayElement(id, id + offset);
m_SerializedObject.ApplyModifiedProperties();
// Move editors
var prev = m_Editors[id + offset];
m_Editors[id + offset] = m_Editors[id];
m_Editors[id] = prev;
}
// Copy/pasting is simply done by creating an in memory copy of the selected component and
// copying over the serialized data to another; it doesn't use nor affect the OS clipboard
static bool CanPaste(VolumeComponent targetComponent)
{
return s_ClipboardContent != null
&& s_ClipboardContent.GetType() == targetComponent.GetType();
}
static void CopySettings(VolumeComponent targetComponent)
{
if (s_ClipboardContent != null)
{
CoreUtils.Destroy(s_ClipboardContent);
s_ClipboardContent = null;
}
s_ClipboardContent = (VolumeComponent)ScriptableObject.CreateInstance(targetComponent.GetType());
EditorUtility.CopySerializedIfDifferent(targetComponent, s_ClipboardContent);
}
static void PasteSettings(VolumeComponent targetComponent)
{
Assert.IsNotNull(s_ClipboardContent);
Assert.AreEqual(s_ClipboardContent.GetType(), targetComponent.GetType());
Undo.RecordObject(targetComponent, "Paste Settings");
EditorUtility.CopySerializedIfDifferent(s_ClipboardContent, targetComponent);
}
}
}

11
ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeComponentListEditor.cs.meta


fileFormatVersion: 2
guid: f3ec0801d05bcb24c8a404d62f357d9c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

29
ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeProfileEditor.cs


using UnityEngine.Experimental.Rendering;
namespace UnityEditor.Experimental.Rendering
{
[CustomEditor(typeof(VolumeProfile))]
sealed class VolumeProfileEditor : Editor
{
VolumeComponentListEditor m_ComponentList;
void OnEnable()
{
m_ComponentList = new VolumeComponentListEditor(this);
m_ComponentList.Init(target as VolumeProfile, serializedObject);
}
void OnDisable()
{
if (m_ComponentList != null)
m_ComponentList.Clear();
}
public override void OnInspectorGUI()
{
serializedObject.Update();
m_ComponentList.OnGUI();
serializedObject.ApplyModifiedProperties();
}
}
}

11
ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeProfileEditor.cs.meta


fileFormatVersion: 2
guid: 77e4433a29bc5b547a429fcd8552c691
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

72
ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeProfileFactory.cs


using UnityEngine;
using UnityEditor.ProjectWindowCallback;
using System.IO;
using UnityEngine.Experimental.Rendering;
using UnityEngine.SceneManagement;
namespace UnityEditor.Experimental.Rendering
{
public static class VolumeProfileFactory
{
[MenuItem("Assets/Create/Volume Profile", priority = 201)]
static void CreateVolumeProfile()
{
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(
0,
ScriptableObject.CreateInstance<DoCreatePostProcessProfile>(),
"New Volume Profile.asset",
null,
null
);
}
public static VolumeProfile CreateVolumeProfileAtPath(string path)
{
var profile = ScriptableObject.CreateInstance<VolumeProfile>();
profile.name = Path.GetFileName(path);
AssetDatabase.CreateAsset(profile, path);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
return profile;
}
public static VolumeProfile CreateVolumeProfile(Scene scene, string targetName)
{
string path;
if (string.IsNullOrEmpty(scene.path))
{
path = "Assets/";
}
else
{
var scenePath = Path.GetDirectoryName(scene.path);
var extPath = scene.name + "_Profiles";
var profilePath = scenePath + "/" + extPath;
if (!AssetDatabase.IsValidFolder(profilePath))
AssetDatabase.CreateFolder(scenePath, extPath);
path = profilePath + "/";
}
path += targetName + " Profile.asset";
path = AssetDatabase.GenerateUniqueAssetPath(path);
var profile = ScriptableObject.CreateInstance<VolumeProfile>();
AssetDatabase.CreateAsset(profile, path);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
return profile;
}
}
class DoCreatePostProcessProfile : EndNameEditAction
{
public override void Action(int instanceId, string pathName, string resourceFile)
{
var profile = VolumeProfileFactory.CreateVolumeProfileAtPath(pathName);
ProjectWindowUtil.ShowCreatedAsset(profile);
}
}
}

11
ScriptableRenderPipeline/Core/CoreRP/Editor/Volume/VolumeProfileFactory.cs.meta


fileFormatVersion: 2
guid: da75d0a7610da4245824752899c20db4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

108
ScriptableRenderPipeline/Core/CoreRP/Volume/VolumeProfile.cs


using System;
using System.Collections.Generic;
namespace UnityEngine.Experimental.Rendering
{
public sealed class VolumeProfile : ScriptableObject
{
public List<VolumeComponent> components = new List<VolumeComponent>();
// Editor only, doesn't have any use outside of it
[NonSerialized]
public bool isDirty = true;
void OnEnable()
{
// Make sure every setting is valid. If a profile holds a script that doesn't exist
// anymore, nuke it to keep the volume clean. Note that if you delete a script that is
// currently in use in a volume you'll still get a one-time error in the console, it's
// harmless and happens because Unity does a redraw of the editor (and thus the current
// frame) before the recompilation step.
components.RemoveAll(x => x == null);
}
public void Reset()
{
isDirty = true;
}
public T Add<T>(bool overrides = false)
where T : VolumeComponent
{
return (T)Add(typeof(T), overrides);
}
public VolumeComponent Add(Type type, bool overrides = false)
{
if (Has(type))
throw new InvalidOperationException("Component already exists in the volume");
var component = (VolumeComponent)CreateInstance(type);
component.SetAllOverridesTo(overrides);
components.Add(component);
isDirty = true;
return component;
}
public void Remove<T>()
where T : VolumeComponent
{
Remove(typeof(T));
}
public void Remove(Type type)
{
int toRemove = -1;
for (int i = 0; i < components.Count; i++)
{
if (components[i].GetType() == type)
{
toRemove = i;
break;
}
}
if (toRemove >= 0)
{
components.RemoveAt(toRemove);
isDirty = true;
}
}
public bool Has<T>()
where T : VolumeComponent
{
return Has(typeof(T));
}
public bool Has(Type type)
{
foreach (var component in components)
{
if (component.GetType() == type)
return true;
}
return false;
}
public bool TryGet<T>(out T component)
where T : VolumeComponent
{
var type = typeof(T);
component = null;
foreach (var comp in components)
{
if (comp.GetType() == type)
{
component = (T)comp;
return true;
}
}
return false;
}
}
}

11
ScriptableRenderPipeline/Core/CoreRP/Volume/VolumeProfile.cs.meta


fileFormatVersion: 2
guid: d7fd9488000d3734a9e00ee676215985
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

248
SampleScenes/HDTest/AnimTest/ThreeDScans/Gutenberg/Materials/Gutenberg.mat


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Gutenberg
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _ALBEDOAFFECTEMISSIVE_OFF _ALPHACUTOFFENABLE_OFF _DEPTHOFFSETENABLE_OFF
_DISTORTIONENABLE_OFF _DOUBLESIDEDENABLE_OFF _ENABLEMOTIONVECTORFORVERTEXANIMATION_OFF
_ENABLESPECULAROCCLUSION_OFF _ENABLEWIND_OFF _MASKMAP _NORMALMAP _NORMALMAP_TANGENT_SPACE
_PREREFRACTIONPASS_OFF _TRANSPARENTBACKFACEENABLE_OFF _TRANSPARENTDEPTHPOSTPASSENABLE_OFF
_TRANSPARENTDEPTHPREPASSENABLE_OFF
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses:
- DistortionVectors
- TransparentDepthPrepass
- TransparentDepthPostPass
- TransparentBackface
- TransparentBackfaceDebugDisplay
- MOTIONVECTORS
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _AnisotropyMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BaseColorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMapOS:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DistortionVectorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissiveColorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _HeightMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MaskMap:
m_Texture: {fileID: 2800000, guid: 34c46fc849d819b48a7f28c2b4f40844, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap:
m_Texture: {fileID: 2800000, guid: 49b62f1e54497814082cff3f8c72ca67, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMapOS:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecularColorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SubsurfaceRadiusMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _TangentMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _TangentMapOS:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _TransmittanceColorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _AORemapMax: 1
- _AORemapMin: 0
- _ATDistance: 1
- _AlbedoAffectEmissive: 0
- _AlphaCutoff: 0.5
- _AlphaCutoffEnable: 0
- _AlphaCutoffPostpass: 0.5
- _AlphaCutoffPrepass: 0.5
- _Anisotropy: 0
- _BlendMode: 0
- _BumpScale: 1
- _CoatCoverage: 1
- _CoatIOR: 0.5
- _CullMode: 2
- _CullModeForward: 2
- _Cutoff: 0.5
- _DepthOffsetEnable: 0
- _DetailAlbedoScale: 1
- _DetailNormalMapScale: 1
- _DetailNormalScale: 1
- _DetailSmoothnessScale: 1
- _DisplacementLockObjectScale: 1
- _DisplacementLockTilingScale: 1
- _DisplacementMode: 0
- _DistortionBlendMode: 0
- _DistortionBlurBlendMode: 0
- _DistortionBlurDstBlend: 1
- _DistortionBlurRemapMax: 1
- _DistortionBlurRemapMin: 0
- _DistortionBlurScale: 1
- _DistortionBlurSrcBlend: 1
- _DistortionDepthTest: 1
- _DistortionDstBlend: 1
- _DistortionEnable: 0
- _DistortionScale: 1
- _DistortionSrcBlend: 1
- _DistortionVectorBias: -1
- _DistortionVectorScale: 2
- _DoubleSidedEnable: 0
- _DoubleSidedNormalMode: 1
- _Drag: 1
- _DstBlend: 0
- _EmissiveColorMode: 1
- _EmissiveIntensity: 0
- _EnableBlendModePreserveSpecularLighting: 1
- _EnableFogOnTransparent: 1
- _EnableMotionVectorForVertexAnimation: 0
- _EnableSpecularOcclusion: 0
- _EnableWind: 0
- _GlossMapScale: 1
- _Glossiness: 0
- _GlossyReflections: 1
- _HeightAmplitude: 0.02
- _HeightCenter: 0.5
- _HeightMax: 1
- _HeightMin: -1
- _IOR: 1
- _InitialBend: 1
- _InvTilingScale: 1
- _LinkDetailsWithBase: 1
- _MaterialID: 1
- _Metallic: 0
- _Mode: 0
- _NormalMapSpace: 0
- _NormalScale: 1
- _OcclusionStrength: 1
- _PPDLodThreshold: 5
- _PPDMaxSamples: 15
- _PPDMinSamples: 5
- _PPDPrimitiveLength: 1
- _PPDPrimitiveWidth: 1
- _Parallax: 0.02
- _PreRefractionPass: 0
- _RefractionMode: 0
- _ShiverDirectionality: 0.5
- _ShiverDrag: 0.2
- _Smoothness: 1
- _SmoothnessRemapMax: 1
- _SmoothnessRemapMin: 0
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _StencilRef: 2
- _StencilRefMV: 128
- _StencilWriteMask: 7
- _StencilWriteMaskMV: 128
- _Stiffness: 1
- _SubsurfaceProfile: 0
- _SubsurfaceRadius: 1
- _SurfaceType: 0
- _TexWorldScale: 1
- _Thickness: 1
- _ThicknessMultiplier: 1
- _TransparentBackfaceEnable: 0
- _TransparentDepthPostpassEnable: 0
- _TransparentDepthPrepassEnable: 0
- _UVBase: 0
- _UVDetail: 0
- _UVSec: 0
- _ZTestMode: 4
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 0.5754717, g: 0.5754717, b: 0.5754717, a: 1}
- _Color: {r: 0.57547164, g: 0.57547164, b: 0.57547164, a: 1}
- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 0}
- _EmissiveColor: {r: 1, g: 1, b: 1, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}
- _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask: {r: 1, g: 0, b: 0, a: 0}

8
SampleScenes/HDTest/AnimTest/ThreeDScans/Gutenberg/Materials/Gutenberg.mat.meta


fileFormatVersion: 2
guid: c8cfc2839a54f5e4fbfb14b94f0e327a
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存