浏览代码

Merge pull request #642 from Unity-Technologies/volume-improvements

Volume improvements
/asmdef
GitHub 7 年前
当前提交
88d1f57c
共有 12 个文件被更改,包括 746 次插入412 次删除
  1. 2
      ScriptableRenderPipeline/Core/Volume/Editor/VolumeEditor.cs
  2. 2
      ScriptableRenderPipeline/Core/Volume/Volume.cs
  3. 223
      ScriptableRenderPipeline/Core/Volume/VolumeManager.cs
  4. 473
      ScriptableRenderPipeline/Core/Volume/VolumeParameter.cs
  5. 144
      ScriptableRenderPipeline/Core/Volume/Editor/Drawers/FloatParameterDrawer.cs
  6. 107
      ScriptableRenderPipeline/Core/Volume/Editor/Drawers/IntParameterDrawer.cs
  7. 77
      ScriptableRenderPipeline/Core/Volume/Editor/Drawers/ClampedFloatParameterDrawer.cs
  8. 77
      ScriptableRenderPipeline/Core/Volume/Editor/Drawers/ClampedIntParameterDrawer.cs
  9. 42
      ScriptableRenderPipeline/Core/Volume/Editor/Drawers/RangeParameterDrawer.cs
  10. 11
      ScriptableRenderPipeline/Core/Volume/Editor/Drawers/RangeParameterDrawer.cs.meta
  11. 0
      /ScriptableRenderPipeline/Core/Volume/Editor/Drawers/IntParameterDrawer.cs.meta
  12. 0
      /ScriptableRenderPipeline/Core/Volume/Editor/Drawers/FloatParameterDrawer.cs.meta

2
ScriptableRenderPipeline/Core/Volume/Editor/VolumeEditor.cs


var script = (MonoScript)o;
var scriptType = script.GetClass();
if (!scriptType.IsSubclassOf(typeof(VolumeComponent)))
if (!scriptType.IsSubclassOf(typeof(VolumeComponent)) || scriptType.IsAbstract)
return false;
if (actualTarget.components.Exists(t => t.GetType() == scriptType))

2
ScriptableRenderPipeline/Core/Volume/Volume.cs


[Tooltip("Volume priority in the stack. Higher number means higher priority. Negative values are supported.")]
public float priority = 0f;
[Tooltip("Outer distance to start blending from. A value of 0 means no blending and the volume overrides will be applied immediatly upon entry.")]
[Tooltip("Outer distance to start blending from. A value of 0 means no blending and the volume overrides will be applied immediately upon entry.")]
public float blendDistance = 0f;
[Range(0f, 1f), Tooltip("Total weight of this volume in the scene. 0 means it won't do anything, 1 means full effect.")]

223
ScriptableRenderPipeline/Core/Volume/VolumeManager.cs


using System;
using System.Collections.Generic;
using System.Diagnostics;
using UnityObject = UnityEngine.Object;
static object s_LockObj = new Object();
static object s_LockObj = new UnityObject();
public static VolumeManager instance
{

// Max amount of layers available in Unity
const int k_MaxLayerCount = 32;
// List of all volumes (sorted by priority) per layer
readonly List<Volume>[] m_Volumes;
// Cached lists of all volumes (sorted by priority) by layer mask
readonly Dictionary<LayerMask, List<Volume>> m_SortedVolumes;
// Keep track of sorting states for all layers
readonly bool[] m_SortNeeded;
// Holds all the registered volumes
readonly List<Volume> m_Volumes;
// 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;

VolumeManager()
{
m_Volumes = new List<Volume>[k_MaxLayerCount];
m_SortNeeded = new bool[k_MaxLayerCount];
m_SortedVolumes = new Dictionary<LayerMask, List<Volume>>();
m_Volumes = new List<Volume>();
m_SortNeeded = new Dictionary<LayerMask, bool>();
m_TempColliders = new List<Collider>(8);
m_Components = new Dictionary<Type, VolumeComponent>();
m_ComponentsDefaultState = new List<VolumeComponent>();

.SelectMany(
a => a.GetTypes()
.Where(
t => t.IsSubclassOf(typeof(VolumeComponent))
t => t.IsSubclassOf(typeof(VolumeComponent)) && !t.IsAbstract
)
);

m_Components.Add(type, inst);
inst = (VolumeComponent)ScriptableObject.CreateInstance(type);
inst.SetAllOverridesTo(true);
m_ComponentsDefaultState.Add(inst);
}

{
VolumeComponent comp;
m_Components.TryGetValue(type, out comp);
Assert.IsNotNull(comp, "Component map is corrupted, \"" + type + "\" not found");
var volumes = m_Volumes[layer];
m_Volumes.Add(volume);
if (volumes == null)
// Look for existing cached layer masks and add it there if needed
foreach (var kvp in m_SortedVolumes)
volumes = new List<Volume>();
m_Volumes[layer] = volumes;
var mask = kvp.Key;
if ((mask & (1 << layer)) != 0)
kvp.Value.Add(volume);
Assert.IsFalse(volumes.Contains(volume), "Volume has already been registered");
volumes.Add(volume);
var volumes = m_Volumes[layer];
m_Volumes.Remove(volume);
if (volumes == null)
return;
foreach (var kvp in m_SortedVolumes)
{
var mask = kvp.Key;
volumes.Remove(volume);
// Skip layer masks this volume doesn't belong to
if ((mask & (1 << layer)) == 0)
continue;
kvp.Value.Remove(volume);
}
m_SortNeeded[layer] = true;
foreach (var kvp in m_SortedVolumes)
{
var mask = kvp.Key;
if ((mask & (1 << layer)) != 0)
m_SortNeeded[mask] = true;
}
}
internal void UpdateVolumeLayer(Volume volume, int prevLayer, int newLayer)

for (int i = 0; i < count; i++)
{
var fromParam = target.parameters[i];
// Keep track of the override state for debugging purpose
fromParam.overrideState = toParam.overrideState;
{
var fromParam = target.parameters[i];
}
}
}
}

}
}
// Update the global state - should be called once per frame in the update loop before
// anything else
public void Update(Transform trigger, LayerMask layerMask)
[Conditional("UNITY_EDITOR")]
public void CheckBaseTypes()
#if UNITY_EDITOR
// play mode -> re-create the world when bad things happen
if (m_ComponentsDefaultState == null
|| (m_ComponentsDefaultState.Count > 0 && m_ComponentsDefaultState[0] == null))
{
if (m_ComponentsDefaultState == null || (m_ComponentsDefaultState.Count > 0 && m_ComponentsDefaultState[0] == null))
}
else
#endif
{
// Start by resetting the global state to default values
ReplaceData(m_ComponentsDefaultState);
}
}
// Do magic
// Update the global state - should be called once per frame per transform/layer mask combo
// in the update loop before rendering
public void Update(Transform trigger, LayerMask layerMask)
{
CheckBaseTypes();
// Start by resetting the global state to default values
ReplaceData(m_ComponentsDefaultState);
int mask = layerMask.value;
for (int i = 0; i < k_MaxLayerCount; i++)
// Sort the cached volume list(s) for the given layer mask if needed and return it
var volumes = GrabVolumes(layerMask);
// Traverse all volumes
foreach (var volume in volumes)
// Skip layers not in the mask
if ((mask & (1 << i)) == 0)
// Skip disabled volumes and volumes without any data or weight
if (!volume.enabled || volume.weight <= 0f)
continue;
// Global volumes always have influence
if (volume.isGlobal)
{
OverrideData(volume.components, Mathf.Clamp01(volume.weight));
}
// Skip empty layers
var volumes = m_Volumes[i];
if (onlyGlobal)
continue;
if (volumes == null)
// If volume isn't global and has no collider, skip it as it's useless
var colliders = m_TempColliders;
volume.GetComponents(colliders);
if (colliders.Count == 0)
// Sort the volume list if needed
if (m_SortNeeded[i])
{
SortByPriority(volumes);
m_SortNeeded[i] = false;
}
// Find closest distance to volume, 0 means it's inside it
float closestDistanceSqr = float.PositiveInfinity;
// Traverse all volumes
foreach (var volume in volumes)
foreach (var collider in colliders)
// Skip disabled volumes and volumes without any data or weight
if (!volume.enabled || volume.weight <= 0f)
if (!collider.enabled)
var components = volume.components;
var closestPoint = collider.ClosestPoint(triggerPos);
var d = (closestPoint - triggerPos).sqrMagnitude;
// Global volumes always have influence
if (volume.isGlobal)
{
OverrideData(components, Mathf.Clamp01(volume.weight));
continue;
}
if (d < closestDistanceSqr)
closestDistanceSqr = d;
}
if (onlyGlobal)
continue;
colliders.Clear();
float blendDistSqr = volume.blendDistance * volume.blendDistance;
// If volume isn't global and has no collider, skip it as it's useless
var colliders = m_TempColliders;
volume.GetComponents(colliders);
if (colliders.Count == 0)
continue;
// Volume has no influence, ignore it
// Note: Volume doesn't do anything when `closestDistanceSqr = blendDistSqr` but
// we can't use a >= comparison as blendDistSqr could be set to 0 in which
// case volume would have total influence
if (closestDistanceSqr > blendDistSqr)
continue;
// Find closest distance to volume, 0 means it's inside it
float closestDistanceSqr = float.PositiveInfinity;
// Volume has influence
float interpFactor = 1f;
foreach (var collider in colliders)
{
if (!collider.enabled)
continue;
if (blendDistSqr > 0f)
interpFactor = 1f - (closestDistanceSqr / blendDistSqr);
var closestPoint = collider.ClosestPoint(triggerPos);
var d = (closestPoint - triggerPos).sqrMagnitude;
// No need to clamp01 the interpolation factor as it'll always be in [0;1[ range
OverrideData(volume.components, interpFactor * Mathf.Clamp01(volume.weight));
}
}
if (d < closestDistanceSqr)
closestDistanceSqr = d;
}
List<Volume> GrabVolumes(LayerMask mask)
{
List<Volume> list;
colliders.Clear();
float blendDistSqr = volume.blendDistance * volume.blendDistance;
if (!m_SortedVolumes.TryGetValue(mask, out list))
{
// New layer mask detected, create a new list and cache all the volumes that belong
// to this mask in it
list = new List<Volume>();
// Volume has no influence, ignore it
// Note: Volume doesn't do anything when `closestDistanceSqr = blendDistSqr` but
// we can't use a >= comparison as blendDistSqr could be set to 0 in which
// case volume would have total influence
if (closestDistanceSqr > blendDistSqr)
foreach (var volume in m_Volumes)
{
if ((mask & (1 << volume.gameObject.layer)) == 0)
// Volume has influence
float interpFactor = 1f;
list.Add(volume);
m_SortNeeded[mask] = true;
}
if (blendDistSqr > 0f)
interpFactor = 1f - (closestDistanceSqr / blendDistSqr);
m_SortedVolumes.Add(mask, list);
}
// No need to clamp01 the interpolation factor as it'll always be in [0;1[ range
OverrideData(components, interpFactor * Mathf.Clamp01(volume.weight));
}
// Check sorting state
bool sortNeeded;
if (m_SortNeeded.TryGetValue(mask, out sortNeeded) && sortNeeded)
{
m_SortNeeded[mask] = false;
SortByPriority(list);
return list;
}
// Stable insertion sort. Faster than List<T>.Sort() for our needs.

473
ScriptableRenderPipeline/Core/Volume/VolumeParameter.cs


using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;

// of the following is a bit hacky...
public abstract class VolumeParameter
{
public const string k_DebuggerDisplay = "{m_Value} ({m_OverrideState})";
[SerializeField]
protected bool m_OverrideState;

}
}
[Serializable]
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class VolumeParameter<T> : VolumeParameter
{
[SerializeField]

get { return m_Value; }
set { m_Value = value; }
}
protected const float k_DefaultInterpSwap = 0f;
public VolumeParameter()
: this(default(T), false)

public virtual void Interp(T from, T to, float t)
{
// Returns `b` if `dt > 0` by default so we don't have to write overrides for bools and
// enumerations.
m_Value = t > 0f ? to : from;
// Default interpolation is naive
m_Value = t > k_DefaultInterpSwap ? to : from;
}
public void Override(T x)

}
}
public override string ToString()
{
return string.Format("{0} ({1})", value, overrideState);
}
//
// Implicit conversion; assuming the following:
//

}
}
public enum ParameterClampMode
{
Min,
Max,
MinMax
}
//
// The serialization system in Unity can't serialize generic types, the workaround is to extend
// and flatten pre-defined generic types.

// public enum MyEnum { One, Two }
//
[Serializable]
public sealed class BoolParameter : VolumeParameter<bool> { }
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class BoolParameter : VolumeParameter<bool>
{
public BoolParameter(bool value, bool overrideState = false)
: base(value, overrideState) { }
}
[Serializable]
public sealed class IntParameter : VolumeParameter<int>
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class IntParameter : VolumeParameter<int>
public override void Interp(int from, int to, float t)
public IntParameter(int value, bool overrideState = false)
: base(value, overrideState) { }
public sealed override void Interp(int from, int to, float t)
{
// Int snapping interpolation. Don't use this for enums as they don't necessarily have
// contiguous values. Use the default interpolator instead (same as bool).

[Serializable]
public sealed class InstantIntParameter : VolumeParameter<int> { }
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class NoInterpIntParameter : VolumeParameter<int>
{
public NoInterpIntParameter(int value, bool overrideState = false)
: base(value, overrideState) { }
}
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class MinIntParameter : IntParameter
{
public int min;
public override int value
{
get { return m_Value; }
set { m_Value = Mathf.Max(value, min); }
}
public MinIntParameter(int value, int min, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
}
}
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class NoInterpMinIntParameter : VolumeParameter<int>
{
public int min;
public override int value
{
get { return m_Value; }
set { m_Value = Mathf.Max(value, min); }
}
public NoInterpMinIntParameter(int value, int min, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
}
}
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class MaxIntParameter : IntParameter
{
public int max;
public override int value
{
get { return m_Value; }
set { m_Value = Mathf.Min(value, max); }
}
public MaxIntParameter(int value, int max, bool overrideState = false)
: base(value, overrideState)
{
this.max = max;
}
}
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class NoInterpMaxIntParameter : VolumeParameter<int>
{
public int max;
public override int value
{
get { return m_Value; }
set { m_Value = Mathf.Min(value, max); }
}
public NoInterpMaxIntParameter(int value, int max, bool overrideState = false)
: base(value, overrideState)
{
this.max = max;
}
}
[Serializable]
public sealed class ClampedIntParameter : VolumeParameter<int>
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class ClampedIntParameter : IntParameter
public ParameterClampMode clampMode = ParameterClampMode.MinMax;
public int min = 0;
public int max = 10;
public int min;
public int max;
set
{
switch (clampMode)
{
case ParameterClampMode.Min: m_Value = Mathf.Max(min, value); break;
case ParameterClampMode.Max: m_Value = Mathf.Min(max, value); break;
case ParameterClampMode.MinMax: m_Value = Mathf.Clamp(value, min, max); break;
}
}
set { m_Value = Mathf.Clamp(value, min, max); }
public override void Interp(int from, int to, float t)
public ClampedIntParameter(int value, int min, int max, bool overrideState = false)
: base(value, overrideState)
m_Value = (int)(from + (to - from) * t);
this.min = min;
this.max = max;
[Serializable]
public sealed class InstantClampedIntParameter : VolumeParameter<int>
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class NoInterpClampedIntParameter : VolumeParameter<int>
public ParameterClampMode clampMode = ParameterClampMode.MinMax;
public int min = 0;
public int max = 10;
public int min;
public int max;
set
{
switch (clampMode)
{
case ParameterClampMode.Min: m_Value = Mathf.Max(min, value); break;
case ParameterClampMode.Max: m_Value = Mathf.Min(max, value); break;
case ParameterClampMode.MinMax: m_Value = Mathf.Clamp(value, min, max); break;
}
}
set { m_Value = Mathf.Clamp(value, min, max); }
}
public NoInterpClampedIntParameter(int value, int min, int max, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
this.max = max;
[Serializable]
public sealed class FloatParameter : VolumeParameter<float>
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class FloatParameter : VolumeParameter<float>
public override void Interp(float from, float to, float t)
public FloatParameter(float value, bool overrideState = false)
: base(value, overrideState) { }
public sealed override void Interp(float from, float to, float t)
[Serializable]
public sealed class InstantFloatParameter : VolumeParameter<float> { }
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class NoInterpFloatParameter : VolumeParameter<float>
{
public NoInterpFloatParameter(float value, bool overrideState = false)
: base(value, overrideState) { }
}
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class MinFloatParameter : FloatParameter
{
public float min;
public override float value
{
get { return m_Value; }
set { m_Value = Mathf.Max(value, min); }
}
public MinFloatParameter(float value, float min, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
}
}
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class NoInterpMinFloatParameter : VolumeParameter<float>
{
public float min;
public override float value
{
get { return m_Value; }
set { m_Value = Mathf.Max(value, min); }
}
public NoInterpMinFloatParameter(float value, float min, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
}
}
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class MaxFloatParameter : FloatParameter
{
public float max;
public override float value
{
get { return m_Value; }
set { m_Value = Mathf.Min(value, max); }
}
public MaxFloatParameter(float value, float max, bool overrideState = false)
: base(value, overrideState)
{
this.max = max;
}
}
[Serializable]
public sealed class ClampedFloatParameter : VolumeParameter<float>
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class NoInterpMaxFloatParameter : VolumeParameter<float>
public ParameterClampMode clampMode = ParameterClampMode.MinMax;
public float min = 0f;
public float max = 1f;
public float max;
set
{
switch (clampMode)
{
case ParameterClampMode.Min: m_Value = Mathf.Max(min, value); break;
case ParameterClampMode.Max: m_Value = Mathf.Min(max, value); break;
case ParameterClampMode.MinMax: m_Value = Mathf.Clamp(value, min, max); break;
}
}
set { m_Value = Mathf.Min(value, max); }
// We could override FloatParameter here but that would require making it not-sealed which
// will stop the compiler from doing specific optimizations on virtual methods - considering
// how often float is used, duplicating the code in this case is a definite win
public override void Interp(float from, float to, float t)
public NoInterpMaxFloatParameter(float value, float max, bool overrideState = false)
: base(value, overrideState)
m_Value = from + (to - from) * t;
this.max = max;
[Serializable]
public sealed class InstantClampedFloatParameter : VolumeParameter<float>
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class ClampedFloatParameter : FloatParameter
public ParameterClampMode clampMode = ParameterClampMode.MinMax;
public float min = 0f;
public float max = 1f;
public float min;
public float max;
set
{
switch (clampMode)
{
case ParameterClampMode.Min: m_Value = Mathf.Max(min, value); break;
case ParameterClampMode.Max: m_Value = Mathf.Min(max, value); break;
case ParameterClampMode.MinMax: m_Value = Mathf.Clamp(value, min, max); break;
}
}
set { m_Value = Mathf.Clamp(value, min, max); }
}
public ClampedFloatParameter(float value, float min, float max, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
this.max = max;
}
}
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class NoInterpClampedFloatParameter : VolumeParameter<float>
{
public float min;
public float max;
public override float value
{
get { return m_Value; }
set { m_Value = Mathf.Clamp(value, min, max); }
}
public NoInterpClampedFloatParameter(float value, float min, float max, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
this.max = max;
[Serializable]
public sealed class RangeParameter : VolumeParameter<Vector2>
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class FloatRangeParameter : VolumeParameter<Vector2>
public float min = 0;
public float max = 1;
public float min;
public float max;
public override Vector2 value
{

}
}
public FloatRangeParameter(Vector2 value, float min, float max, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
this.max = max;
}
public override void Interp(Vector2 from, Vector2 to, float t)
{
m_Value.x = from.x + (to.x - from.x) * t;

[Serializable]
public sealed class InstantRangeParameter : VolumeParameter<Vector2>
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class NoInterpFloatRangeParameter : VolumeParameter<Vector2>
public float min = 0;
public float max = 1;
public float min;
public float max;
public override Vector2 value
{

m_Value.y = Mathf.Min(value.y, max);
}
}
public NoInterpFloatRangeParameter(Vector2 value, float min, float max, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
this.max = max;
}
[Serializable]
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class ColorParameter : VolumeParameter<Color>
{
public bool hdr = false;

public ColorParameter(Color value, bool overrideState = false)
: base(value, overrideState) { }
public ColorParameter(Color value, bool hdr, bool showAlpha, bool showEyeDropper, bool overrideState = false)
: base(value, overrideState)
{
this.hdr = hdr;
this.showAlpha = showAlpha;
this.overrideState = overrideState;
}
public override void Interp(Color from, Color to, float t)
{
// Lerping color values is a sensitive subject... We looked into lerping colors using

}
}
[Serializable]
public sealed class InstantColorParameter : VolumeParameter<Color> { }
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class NoInterpColorParameter : VolumeParameter<Color>
{
public bool hdr = false;
public bool showAlpha = true;
public bool showEyeDropper = true;
[Serializable]
public NoInterpColorParameter(Color value, bool overrideState = false)
: base(value, overrideState) { }
public NoInterpColorParameter(Color value, bool hdr, bool showAlpha, bool showEyeDropper, bool overrideState = false)
: base(value, overrideState)
{
this.hdr = hdr;
this.showAlpha = showAlpha;
this.overrideState = overrideState;
}
}
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public Vector2Parameter(Vector2 value, bool overrideState = false)
: base(value, overrideState) { }
public override void Interp(Vector2 from, Vector2 to, float t)
{
m_Value.x = from.x + (to.x - from.x) * t;

[Serializable]
public sealed class InstantVector2Parameter : VolumeParameter<Vector2> { }
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class NoInterpVector2Parameter : VolumeParameter<Vector2>
{
public NoInterpVector2Parameter(Vector2 value, bool overrideState = false)
: base(value, overrideState) { }
}
[Serializable]
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public Vector3Parameter(Vector3 value, bool overrideState = false)
: base(value, overrideState) { }
public override void Interp(Vector3 from, Vector3 to, float t)
{
m_Value.x = from.x + (to.x - from.x) * t;

}
[Serializable]
public sealed class InstantVector3Parameter : VolumeParameter<Vector3> { }
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class NoInterpVector3Parameter : VolumeParameter<Vector3>
{
public NoInterpVector3Parameter(Vector3 value, bool overrideState = false)
: base(value, overrideState) { }
}
[Serializable]
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public Vector4Parameter(Vector4 value, bool overrideState = false)
: base(value, overrideState) { }
public override void Interp(Vector4 from, Vector4 to, float t)
{
m_Value.x = from.x + (to.x - from.x) * t;

}
}
[Serializable]
public sealed class InstantVector4Parameter : VolumeParameter<Vector4> { }
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class NoInterpVector4Parameter : VolumeParameter<Vector4>
{
public NoInterpVector4Parameter(Vector4 value, bool overrideState = false)
: base(value, overrideState) { }
}
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class TextureParameter : VolumeParameter<Texture>
{
public TextureParameter(Texture value, bool overrideState = false)
: base(value, overrideState) { }
// TODO: Texture interpolation
}
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class NoInterpTextureParameter : VolumeParameter<Texture>
{
public NoInterpTextureParameter(Texture value, bool overrideState = false)
: base(value, overrideState) { }
}
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class RenderTextureParameter : VolumeParameter<RenderTexture>
{
public RenderTextureParameter(RenderTexture value, bool overrideState = false)
: base(value, overrideState) { }
// TODO: RenderTexture interpolation
}
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class NoInterpRenderTextureParameter : VolumeParameter<RenderTexture>
{
public NoInterpRenderTextureParameter(RenderTexture value, bool overrideState = false)
: base(value, overrideState) { }
}
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class CubemapParameter : VolumeParameter<Cubemap>
{
public CubemapParameter(Cubemap value, bool overrideState = false)
: base(value, overrideState) { }
// TODO: Cubemap interpolation
}
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class NoInterpCubemapParameter : VolumeParameter<Cubemap>
{
public NoInterpCubemapParameter(Cubemap value, bool overrideState = false)
: base(value, overrideState) { }
}
[Serializable]
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class ObjectParameter<T> : VolumeParameter<T>
{
internal ReadOnlyCollection<VolumeParameter> parameters { get; private set; }

.ToList()
.AsReadOnly();
}
}
public ObjectParameter(T value)
{
m_OverrideState = true;
this.value = value;
}
internal override void Interp(VolumeParameter from, VolumeParameter to, float t)

144
ScriptableRenderPipeline/Core/Volume/Editor/Drawers/FloatParameterDrawer.cs


using UnityEngine;
using UnityEngine.Experimental.Rendering;
namespace UnityEditor.Experimental.Rendering
{
[VolumeParameterDrawer(typeof(MinFloatParameter))]
sealed class MinFloatParameterDrawer : VolumeParameterDrawer
{
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
{
var value = parameter.value;
if (value.propertyType != SerializedPropertyType.Float)
return false;
var o = parameter.GetObjectRef<MinFloatParameter>();
float v = EditorGUILayout.FloatField(title, value.floatValue);
value.floatValue = Mathf.Max(v, o.min);
return true;
}
}
[VolumeParameterDrawer(typeof(NoInterpMinFloatParameter))]
sealed class NoInterpMinFloatParameterDrawer : VolumeParameterDrawer
{
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
{
var value = parameter.value;
if (value.propertyType != SerializedPropertyType.Float)
return false;
var o = parameter.GetObjectRef<NoInterpMinFloatParameter>();
float v = EditorGUILayout.FloatField(title, value.floatValue);
value.floatValue = Mathf.Max(v, o.min);
return true;
}
}
[VolumeParameterDrawer(typeof(MaxFloatParameter))]
sealed class MaxFloatParameterDrawer : VolumeParameterDrawer
{
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
{
var value = parameter.value;
if (value.propertyType != SerializedPropertyType.Float)
return false;
var o = parameter.GetObjectRef<MaxFloatParameter>();
float v = EditorGUILayout.FloatField(title, value.floatValue);
value.floatValue = Mathf.Min(v, o.max);
return true;
}
}
[VolumeParameterDrawer(typeof(NoInterpMaxFloatParameter))]
sealed class NoInterpMaxFloatParameterDrawer : VolumeParameterDrawer
{
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
{
var value = parameter.value;
if (value.propertyType != SerializedPropertyType.Float)
return false;
var o = parameter.GetObjectRef<NoInterpMaxFloatParameter>();
float v = EditorGUILayout.FloatField(title, value.floatValue);
value.floatValue = Mathf.Min(v, o.max);
return true;
}
}
[VolumeParameterDrawer(typeof(ClampedFloatParameter))]
sealed class ClampedFloatParameterDrawer : VolumeParameterDrawer
{
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
{
var value = parameter.value;
if (value.propertyType != SerializedPropertyType.Float)
return false;
var o = parameter.GetObjectRef<ClampedFloatParameter>();
EditorGUILayout.Slider(value, o.min, o.max, title);
value.floatValue = Mathf.Clamp(value.floatValue, o.min, o.max);
return true;
}
}
[VolumeParameterDrawer(typeof(NoInterpClampedFloatParameter))]
sealed class NoInterpClampedFloatParameterDrawer : VolumeParameterDrawer
{
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
{
var value = parameter.value;
if (value.propertyType != SerializedPropertyType.Float)
return false;
var o = parameter.GetObjectRef<NoInterpClampedFloatParameter>();
EditorGUILayout.Slider(value, o.min, o.max, title);
value.floatValue = Mathf.Clamp(value.floatValue, o.min, o.max);
return true;
}
}
[VolumeParameterDrawer(typeof(FloatRangeParameter))]
sealed class FloatRangeParameterDrawer : VolumeParameterDrawer
{
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
{
var value = parameter.value;
if (value.propertyType != SerializedPropertyType.Vector2)
return false;
var o = parameter.GetObjectRef<FloatRangeParameter>();
var v = value.vector2Value;
// The layout system breaks alignement when mixing inspector fields with custom layouted
// fields as soon as a scrollbar is needed in the inspector, so we'll do the layout
// manually instead
const int kFloatFieldWidth = 50;
const int kSeparatorWidth = 5;
float indentOffset = EditorGUI.indentLevel * 15f;
var lineRect = GUILayoutUtility.GetRect(1, EditorGUIUtility.singleLineHeight);
lineRect.xMin += 4f;
lineRect.y += 2f;
var labelRect = new Rect(lineRect.x, lineRect.y, EditorGUIUtility.labelWidth - indentOffset, lineRect.height);
var floatFieldLeft = new Rect(labelRect.xMax, lineRect.y, kFloatFieldWidth + indentOffset, lineRect.height);
var sliderRect = new Rect(floatFieldLeft.xMax + kSeparatorWidth - indentOffset, lineRect.y, lineRect.width - labelRect.width - kFloatFieldWidth * 2 - kSeparatorWidth * 2, lineRect.height);
var floatFieldRight = new Rect(sliderRect.xMax + kSeparatorWidth - indentOffset, lineRect.y, kFloatFieldWidth + indentOffset, lineRect.height);
EditorGUI.PrefixLabel(labelRect, title);
v.x = EditorGUI.FloatField(floatFieldLeft, v.x);
EditorGUI.MinMaxSlider(sliderRect, ref v.x, ref v.y, o.min, o.max);
v.y = EditorGUI.FloatField(floatFieldRight, v.y);
value.vector2Value = v;
return true;
}
}
}

107
ScriptableRenderPipeline/Core/Volume/Editor/Drawers/IntParameterDrawer.cs


using UnityEngine;
using UnityEngine.Experimental.Rendering;
namespace UnityEditor.Experimental.Rendering
{
[VolumeParameterDrawer(typeof(MinIntParameter))]
sealed class MinIntParameterDrawer : VolumeParameterDrawer
{
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
{
var value = parameter.value;
if (value.propertyType != SerializedPropertyType.Integer)
return false;
var o = parameter.GetObjectRef<MinIntParameter>();
int v = EditorGUILayout.IntField(title, value.intValue);
value.intValue = Mathf.Max(v, o.min);
return true;
}
}
[VolumeParameterDrawer(typeof(NoInterpMinIntParameter))]
sealed class NoInterpMinIntParameterDrawer : VolumeParameterDrawer
{
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
{
var value = parameter.value;
if (value.propertyType != SerializedPropertyType.Integer)
return false;
var o = parameter.GetObjectRef<NoInterpMinIntParameter>();
int v = EditorGUILayout.IntField(title, value.intValue);
value.intValue = Mathf.Max(v, o.min);
return true;
}
}
[VolumeParameterDrawer(typeof(MaxIntParameter))]
sealed class MaxIntParameterDrawer : VolumeParameterDrawer
{
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
{
var value = parameter.value;
if (value.propertyType != SerializedPropertyType.Integer)
return false;
var o = parameter.GetObjectRef<MaxIntParameter>();
int v = EditorGUILayout.IntField(title, value.intValue);
value.intValue = Mathf.Min(v, o.max);
return true;
}
}
[VolumeParameterDrawer(typeof(NoInterpMaxIntParameter))]
sealed class NoInterpMaxIntParameterDrawer : VolumeParameterDrawer
{
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
{
var value = parameter.value;
if (value.propertyType != SerializedPropertyType.Integer)
return false;
var o = parameter.GetObjectRef<NoInterpMaxIntParameter>();
int v = EditorGUILayout.IntField(title, value.intValue);
value.intValue = Mathf.Min(v, o.max);
return true;
}
}
[VolumeParameterDrawer(typeof(ClampedIntParameter))]
sealed class ClampedIntParameterDrawer : VolumeParameterDrawer
{
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
{
var value = parameter.value;
if (value.propertyType != SerializedPropertyType.Integer)
return false;
var o = parameter.GetObjectRef<ClampedIntParameter>();
EditorGUILayout.IntSlider(value, o.min, o.max, title);
value.intValue = Mathf.Clamp(value.intValue, o.min, o.max);
return true;
}
}
[VolumeParameterDrawer(typeof(NoInterpClampedIntParameter))]
sealed class NoInterpClampedIntParameterDrawer : VolumeParameterDrawer
{
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
{
var value = parameter.value;
if (value.propertyType != SerializedPropertyType.Integer)
return false;
var o = parameter.GetObjectRef<NoInterpClampedIntParameter>();
EditorGUILayout.IntSlider(value, o.min, o.max, title);
value.intValue = Mathf.Clamp(value.intValue, o.min, o.max);
return true;
}
}
}

77
ScriptableRenderPipeline/Core/Volume/Editor/Drawers/ClampedFloatParameterDrawer.cs


using UnityEngine;
using UnityEngine.Experimental.Rendering;
namespace UnityEditor.Experimental.Rendering
{
[VolumeParameterDrawer(typeof(ClampedFloatParameter))]
sealed class ClampedFloatParameterDrawer : VolumeParameterDrawer
{
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
{
var value = parameter.value;
if (value.propertyType != SerializedPropertyType.Float)
return false;
var o = parameter.GetObjectRef<ClampedFloatParameter>();
if (o.clampMode == ParameterClampMode.MinMax)
{
EditorGUILayout.Slider(value, o.min, o.max, title);
value.floatValue = Mathf.Clamp(value.floatValue, o.min, o.max);
}
else if (o.clampMode == ParameterClampMode.Min)
{
float v = EditorGUILayout.FloatField(title, value.floatValue);
value.floatValue = Mathf.Max(v, o.min);
}
else if (o.clampMode == ParameterClampMode.Max)
{
float v = EditorGUILayout.FloatField(title, value.floatValue);
value.floatValue = Mathf.Min(v, o.max);
}
else
{
return false;
}
return true;
}
}
[VolumeParameterDrawer(typeof(InstantClampedFloatParameter))]
sealed class InstantClampedFloatParameterDrawer : VolumeParameterDrawer
{
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
{
var value = parameter.value;
if (value.propertyType != SerializedPropertyType.Float)
return false;
var o = parameter.GetObjectRef<InstantClampedFloatParameter>();
if (o.clampMode == ParameterClampMode.MinMax)
{
EditorGUILayout.Slider(value, o.min, o.max, title);
value.floatValue = Mathf.Clamp(value.floatValue, o.min, o.max);
}
else if (o.clampMode == ParameterClampMode.Min)
{
float v = EditorGUILayout.FloatField(title, value.floatValue);
value.floatValue = Mathf.Max(v, o.min);
}
else if (o.clampMode == ParameterClampMode.Max)
{
float v = EditorGUILayout.FloatField(title, value.floatValue);
value.floatValue = Mathf.Min(v, o.max);
}
else
{
return false;
}
return true;
}
}
}

77
ScriptableRenderPipeline/Core/Volume/Editor/Drawers/ClampedIntParameterDrawer.cs


using UnityEngine;
using UnityEngine.Experimental.Rendering;
namespace UnityEditor.Experimental.Rendering
{
[VolumeParameterDrawer(typeof(ClampedIntParameter))]
sealed class ClampedIntParameterDrawer : VolumeParameterDrawer
{
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
{
var value = parameter.value;
if (value.propertyType != SerializedPropertyType.Integer)
return false;
var o = parameter.GetObjectRef<ClampedIntParameter>();
if (o.clampMode == ParameterClampMode.MinMax)
{
EditorGUILayout.IntSlider(value, o.min, o.max, title);
value.intValue = Mathf.Clamp(value.intValue, o.min, o.max);
}
else if (o.clampMode == ParameterClampMode.Min)
{
int v = EditorGUILayout.IntField(title, value.intValue);
value.intValue = Mathf.Max(v, o.min);
}
else if (o.clampMode == ParameterClampMode.Max)
{
int v = EditorGUILayout.IntField(title, value.intValue);
value.intValue = Mathf.Min(v, o.max);
}
else
{
return false;
}
return true;
}
}
[VolumeParameterDrawer(typeof(InstantClampedIntParameter))]
sealed class InstantClampedIntParameterDrawer : VolumeParameterDrawer
{
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
{
var value = parameter.value;
if (value.propertyType != SerializedPropertyType.Integer)
return false;
var o = parameter.GetObjectRef<InstantClampedIntParameter>();
if (o.clampMode == ParameterClampMode.MinMax)
{
EditorGUILayout.IntSlider(value, o.min, o.max, title);
value.intValue = Mathf.Clamp(value.intValue, o.min, o.max);
}
else if (o.clampMode == ParameterClampMode.Min)
{
int v = EditorGUILayout.IntField(title, value.intValue);
value.intValue = Mathf.Max(v, o.min);
}
else if (o.clampMode == ParameterClampMode.Max)
{
int v = EditorGUILayout.IntField(title, value.intValue);
value.intValue = Mathf.Min(v, o.max);
}
else
{
return false;
}
return true;
}
}
}

42
ScriptableRenderPipeline/Core/Volume/Editor/Drawers/RangeParameterDrawer.cs


using UnityEngine;
using UnityEngine.Experimental.Rendering;
namespace UnityEditor.Experimental.Rendering
{
[VolumeParameterDrawer(typeof(RangeParameter))]
sealed class RangeParameterDrawer : VolumeParameterDrawer
{
public override bool OnGUI(SerializedDataParameter parameter, GUIContent title)
{
var value = parameter.value;
if (value.propertyType != SerializedPropertyType.Vector2)
return false;
var o = parameter.GetObjectRef<RangeParameter>();
var v = value.vector2Value;
// The layout system breaks alignement when mixing inspector fields with custom layouted
// fields as soon as a scrollbar is needed in the inspector, so we'll do the layout
// manually instead
const int kFloatFieldWidth = 50;
const int kSeparatorWidth = 5;
float indentOffset = EditorGUI.indentLevel * 15f;
var lineRect = GUILayoutUtility.GetRect(1, EditorGUIUtility.singleLineHeight);
lineRect.xMin += 4f;
lineRect.y += 2f;
var labelRect = new Rect(lineRect.x, lineRect.y, EditorGUIUtility.labelWidth - indentOffset, lineRect.height);
var floatFieldLeft = new Rect(labelRect.xMax, lineRect.y, kFloatFieldWidth + indentOffset, lineRect.height);
var sliderRect = new Rect(floatFieldLeft.xMax + kSeparatorWidth - indentOffset, lineRect.y, lineRect.width - labelRect.width - kFloatFieldWidth * 2 - kSeparatorWidth * 2, lineRect.height);
var floatFieldRight = new Rect(sliderRect.xMax + kSeparatorWidth - indentOffset, lineRect.y, kFloatFieldWidth + indentOffset, lineRect.height);
EditorGUI.PrefixLabel(labelRect, title);
v.x = EditorGUI.FloatField(floatFieldLeft, v.x);
EditorGUI.MinMaxSlider(sliderRect, ref v.x, ref v.y, o.min, o.max);
v.y = EditorGUI.FloatField(floatFieldRight, v.y);
value.vector2Value = v;
return true;
}
}
}

11
ScriptableRenderPipeline/Core/Volume/Editor/Drawers/RangeParameterDrawer.cs.meta


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

/ScriptableRenderPipeline/Core/Volume/Editor/Drawers/ClampedIntParameterDrawer.cs.meta → /ScriptableRenderPipeline/Core/Volume/Editor/Drawers/IntParameterDrawer.cs.meta

/ScriptableRenderPipeline/Core/Volume/Editor/Drawers/ClampedFloatParameterDrawer.cs.meta → /ScriptableRenderPipeline/Core/Volume/Editor/Drawers/FloatParameterDrawer.cs.meta

正在加载...
取消
保存