浏览代码

Abstracted the volume stack to allow for custom stack management; simplified the domain reload code

/namespace
Thomas 7 年前
当前提交
fe53c258
共有 3 个文件被更改,包括 92 次插入60 次删除
  1. 87
      ScriptableRenderPipeline/Core/Volume/VolumeManager.cs
  2. 54
      ScriptableRenderPipeline/Core/Volume/VolumeStack.cs
  3. 11
      ScriptableRenderPipeline/Core/Volume/VolumeStack.cs.meta

87
ScriptableRenderPipeline/Core/Volume/VolumeManager.cs


}
//<<<
// Internal stack
public VolumeStack stack { get; private set; }
// Current list of tracked component types
IEnumerable<Type> m_BaseTypes;
// Max amount of layers available in Unity
const int k_MaxLayerCount = 32;

// Keep track of sorting states for layer masks
readonly Dictionary<LayerMask, bool> m_SortNeeded;
// Internal state of all component types
readonly Dictionary<Type, VolumeComponent> m_Components;
// Internal list of default state for each component type - this is used to reset component
// states on update instead of having to implement a Reset method on all components (which
// would be error-prone)

readonly List<Collider> m_TempColliders;
// In the editor, when entering play-mode, it will call the constructor and OnEditorReload()
// which in turn will call ReloadBaseTypes() twice, so we need to keep track of the reloads
// to avoid wasting any more CPU than required
static bool s_StopReloads = false;
VolumeManager()
{
m_SortedVolumes = new Dictionary<LayerMask, List<Volume>>();

m_Components = new Dictionary<Type, VolumeComponent>();
}
#if UNITY_EDITOR
// Called every time Unity recompiles scripts in the editor. We need this to keep track of
// any new custom component the user might add to the project.
[UnityEditor.Callbacks.DidReloadScripts]
static void OnEditorReload()
{
if (!s_StopReloads)
instance.ReloadBaseTypes();
s_StopReloads = false;
stack = CreateStack();
#endif
// Clean component map & default states
foreach (var component in m_Components)
CoreUtils.Destroy(component.Value);
foreach (var component in m_ComponentsDefaultState)
CoreUtils.Destroy(component);
m_Components.Clear();
m_ComponentsDefaultState.Clear();
// Rebuild it from scratch
var types = CoreUtils.GetAllAssemblyTypes()
// Grab all the component types we can find
m_BaseTypes = CoreUtils.GetAllAssemblyTypes()
foreach (var type in types)
// Keep an instance of each type to be used in a virtual lowest priority global volume
// so that we have a default state to fallback to when exiting volumes
foreach (var type in m_BaseTypes)
// We need two instances, one for global state tracking and another one to keep a
// default state that will act as the lowest priority global volume (so that we have
// a state to fallback to when exiting volumes)
m_Components.Add(type, inst);
inst = (VolumeComponent)ScriptableObject.CreateInstance(type);
s_StopReloads = true;
public T GetComponent<T>()
where T : VolumeComponent
public VolumeStack CreateStack()
var comp = GetComponent(typeof(T));
return (T)comp;
}
public VolumeComponent GetComponent(Type type)
{
VolumeComponent comp;
m_Components.TryGetValue(type, out comp);
return comp;
return new VolumeStack(m_BaseTypes);
}
public void Register(Volume volume, int layer)

}
// Go through all listed components and lerp overriden values in the global state
void OverrideData(List<VolumeComponent> components, float interpFactor)
void OverrideData(VolumeStack stack, List<VolumeComponent> components, float interpFactor)
{
foreach (var component in components)
{

var target = GetComponent(component.GetType());
var target = stack.GetComponent(component.GetType());
int count = component.parameters.Count;
for (int i = 0; i < count; i++)

}
// Faster version of OverrideData to force replace values in the global state
void ReplaceData(List<VolumeComponent> components)
void ReplaceData(VolumeStack stack, List<VolumeComponent> components)
var target = GetComponent(component.GetType());
var target = stack.GetComponent(component.GetType());
int count = component.parameters.Count;
for (int i = 0; i < count; i++)

// in the update loop before rendering
public void Update(Transform trigger, LayerMask layerMask)
{
Update(stack, trigger, layerMask);
}
// Update a specific stack - can be used to manage your own stack and store it for later use
public void Update(VolumeStack stack, Transform trigger, LayerMask layerMask)
{
ReplaceData(m_ComponentsDefaultState);
ReplaceData(stack, m_ComponentsDefaultState);
bool onlyGlobal = trigger == null;
var triggerPos = onlyGlobal ? Vector3.zero : trigger.position;

// Global volumes always have influence
if (volume.isGlobal)
{
OverrideData(volume.components, Mathf.Clamp01(volume.weight));
OverrideData(stack, volume.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(volume.components, interpFactor * Mathf.Clamp01(volume.weight));
OverrideData(stack, volume.components, interpFactor * Mathf.Clamp01(volume.weight));
}
}

54
ScriptableRenderPipeline/Core/Volume/VolumeStack.cs


using System;
using System.Collections.Generic;
namespace UnityEngine.Experimental.Rendering
{
public sealed class VolumeStack : IDisposable
{
// Holds the state of _all_ component types you can possibly add on volumes
public readonly Dictionary<Type, VolumeComponent> components;
internal VolumeStack(IEnumerable<Type> baseTypes)
{
components = new Dictionary<Type, VolumeComponent>();
foreach (var type in baseTypes)
{
var inst = (VolumeComponent)ScriptableObject.CreateInstance(type);
components.Add(type, inst);
}
}
public bool HasComponent<T>()
{
return HasComponent(typeof(T));
}
public bool HasComponent(Type type)
{
return components.ContainsKey(type);
}
public T GetComponent<T>()
where T : VolumeComponent
{
var comp = GetComponent(typeof(T));
return (T)comp;
}
public VolumeComponent GetComponent(Type type)
{
VolumeComponent comp;
components.TryGetValue(type, out comp);
return comp;
}
public void Dispose()
{
foreach (var component in components)
CoreUtils.Destroy(component.Value);
components.Clear();
}
}
}

11
ScriptableRenderPipeline/Core/Volume/VolumeStack.cs.meta


fileFormatVersion: 2
guid: 7af226ce5122db0409963decbabf9d9b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存