using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace UnityEngine.Rendering
{
///
/// The base class for all parameter types stored in a .
///
/// This class serves as a base for different parameter types that are used within the Volume system, such as those controlling post-processing effects, lighting settings, and other volume-related parameters.
///
/// The class implements the interface, enabling cloning of the parameter's values for later use or manipulation.
///
///
/// The class is an abstract base class, and cannot be instantiated directly.
/// Derived classes like represent specific parameter types, such as float, vector, or color values, and can be used to configure individual settings in a Volume component.
///
/// It is important to note that this class is designed to allow various parameter types to be stored and managed collectively.
/// This mechanism enables developers to create complex and configurable Volume components that can be customized with different parameter types (e.g., sliders for float values, color pickers for color values, etc.).
///
///
///
///
///
///
public abstract class VolumeParameter : ICloneable
{
#if UNITY_EDITOR || DEVELOPMENT_BUILD
internal string debugId { get; set; }
#endif
///
/// A beautified string for debugger output. This is set on a DebuggerDisplay on every
/// parameter types.
///
public const string k_DebuggerDisplay = "{m_Value} ({m_OverrideState})";
///
/// The current override state for this parameter. The Volume system considers overriden parameters
/// for blending, and ignores non-overriden ones.
///
///
[SerializeField]
protected bool m_OverrideState;
///
/// The current override state for this parameter. The Volume system considers overriden parameters
/// for blending, and ignores non-overriden ones. It is also used in the VolumeStack to determine whether
/// a given parameter has been overridden and thus needs to be reset to its default state in the next update.
///
///
/// You can override this property to define custom behaviors when the override state
/// changes.
///
///
public virtual bool overrideState
{
get => m_OverrideState;
set => m_OverrideState = value;
}
internal abstract void Interp(VolumeParameter from, VolumeParameter to, float t);
///
/// Casts and gets the typed value of this parameter.
///
/// The type of the value stored in this parameter
/// A value of type .
///
/// This method is unsafe and does not do any type checking.
///
public T GetValue()
{
return ((VolumeParameter)this).value;
}
///
/// Sets the value of this parameter to the value in .
///
/// The to copy the value from.
public abstract void SetValue(VolumeParameter parameter);
///
/// Unity calls this method when the parent loads.
///
///
/// Use this if you need to access fields and properties that you can not access in
/// the constructor of a ScriptableObject. ( are
/// generally declared and initialized in a , which is a
/// ScriptableObject). Unity calls this right after it constructs the parent
/// , thus allowing access to previously
/// inaccessible fields and properties.
///
protected internal virtual void OnEnable()
{
}
///
/// Unity calls this method when the parent goes out of scope.
///
protected internal virtual void OnDisable()
{
}
///
/// Checks if a given type is an .
///
/// The type to check.
/// true if is an ,
/// false otherwise.
public static bool IsObjectParameter(Type type)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ObjectParameter<>))
return true;
return type.BaseType != null
&& IsObjectParameter(type.BaseType);
}
///
/// Override this method to free all allocated resources
///
public virtual void Release() { }
///
/// Clones the current instance of the
///
/// A new created instance with the same values as the current instance of
public abstract object Clone();
}
///
/// A generic implementation of . Custom parameters should derive
/// from this class and implement their own behavior.
///
/// The type of value to hold in this parameter.
///
/// should a serializable type.
/// Due to limitations with the serialization system in Unity, you should not use this class
/// directly to declare parameters in a . Instead, use one of the
/// pre-flatten types (like , or make your own by extending this
/// class.
///
///
/// This sample code shows how to make a custom parameter holding a float:
///
/// using UnityEngine.Rendering;
///
/// [Serializable]
/// public sealed class MyFloatParameter : VolumeParameter<float>
/// {
/// public MyFloatParameter(float value, bool overrideState = false)
/// : base(value, overrideState) { }
///
/// public sealed override void Interp(float from, float to, float t)
/// {
/// m_Value = from + (to - from) * t;
/// }
/// }
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class VolumeParameter : VolumeParameter, IEquatable>
{
///
/// The value stored and serialized by this parameter.
///
[SerializeField]
protected T m_Value;
///
/// The value that this parameter stores.
///
///
/// You can override this property to define custom behaviors when the value is changed.
///
public virtual T value
{
get => m_Value;
set => m_Value = value;
}
///
/// Creates a new instance.
///
public VolumeParameter()
: this(default, false)
{
}
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
protected VolumeParameter(T value, bool overrideState = false)
{
m_Value = value;
this.overrideState = overrideState;
}
internal override void Interp(VolumeParameter from, VolumeParameter to, float t)
{
// Note: this is relatively unsafe (assumes that from and to are both holding type T)
Interp((from as VolumeParameter).value, (to as VolumeParameter).value, t);
}
///
/// Interpolates two values using a factor .
///
///
/// By default, this method does a "snap" interpolation, meaning it returns the value
/// if is higher than 0, and
/// otherwise.
///
/// The start value.
/// The end value.
/// The interpolation factor in range [0,1].
public virtual void Interp(T from, T to, float t)
{
// Default interpolation is naive
m_Value = t > 0f ? to : from;
}
///
/// Sets the value for this parameter and sets its override state to true.
///
/// The value to assign to this parameter.
public void Override(T x)
{
overrideState = true;
m_Value = x;
}
///
/// Sets the value of this parameter to the value in .
///
/// The to copy the value from.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void SetValue(VolumeParameter parameter)
{
m_Value = ((VolumeParameter)parameter).m_Value;
}
///
/// Returns a hash code for the current object.
///
/// A hash code for the current object.
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + overrideState.GetHashCode();
if (!EqualityComparer.Default.Equals(value, default)) // Catches null for references with boxing of value types
hash = hash * 23 + value.GetHashCode();
return hash;
}
}
///
/// Returns a string that represents the current object.
///
/// A string that represents the current object.
public override string ToString() => $"{value} ({overrideState})";
///
/// Compares the value in a parameter with another value of the same type.
///
/// The first value in a .
/// The second value.
/// true if both values are equal, false otherwise.
public static bool operator ==(VolumeParameter lhs, T rhs) => lhs != null && !ReferenceEquals(lhs.value, null) && lhs.value.Equals(rhs);
///
/// Compares the value store in a parameter with another value of the same type.
///
/// The first value in a .
/// The second value.
/// false if both values are equal, true otherwise
public static bool operator !=(VolumeParameter lhs, T rhs) => !(lhs == rhs);
///
/// Checks if this parameter is equal to another.
///
/// The other parameter to check against.
/// true if both parameters are equal, false otherwise
public bool Equals(VolumeParameter other)
{
if (ReferenceEquals(null, other))
return false;
if (ReferenceEquals(this, other))
return true;
return EqualityComparer.Default.Equals(m_Value, other.m_Value);
}
///
/// Determines whether two object instances are equal.
///
/// The object to compare with the current object.
/// true if the specified object is equal to the current object, false otherwise.
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
return false;
if (ReferenceEquals(this, obj))
return true;
if (obj.GetType() != GetType())
return false;
return Equals((VolumeParameter)obj);
}
///
public override object Clone()
{
return new VolumeParameter(GetValue(), overrideState);
}
///
/// Explicitly downcast a to a value of type
/// .
///
/// The parameter to downcast.
/// A value of type .
public static explicit operator T(VolumeParameter prop) => prop.m_Value;
}
///
/// Generic Enum volume parameter.
///
/// The type of value to hold in this parameter.
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class EnumParameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public EnumParameter(T value, bool overrideState = false)
: base(value, overrideState) { }
}
///
/// A that holds a bool value.
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class BoolParameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter
/// The initial override state for the parameter
public BoolParameter(bool value, bool overrideState = false)
: base(value, overrideState)
{
}
///
/// Creates a new instance.
///
/// The initial value to store in the parameter
/// The display type to use for the parameter
/// The initial override state for the parameter
public BoolParameter(bool value, DisplayType displayType, bool overrideState = false)
: base(value, overrideState)
{
this.displayType = displayType;
}
///
/// Boolean widget type.
///
public enum DisplayType
{
/// Display boolean parameter as checkbox.
Checkbox,
/// Display boolean parameter as enum popup with Disabled/Enabled options.
EnumPopup
}
///
/// Type of widget used to display the in the UI.
///
[NonSerialized]
public DisplayType displayType = DisplayType.Checkbox;
}
///
/// A that holds a LayerMask value.
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class LayerMaskParameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public LayerMaskParameter(LayerMask value, bool overrideState = false)
: base(value, overrideState) { }
}
///
/// A that holds a LayerMask value.
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class RenderingLayerMaskParameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public RenderingLayerMaskParameter(RenderingLayerMask value, bool overrideState = false)
: base(value, overrideState) { }
}
///
/// A that holds an int value.
///
///
///
///
///
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class IntParameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public IntParameter(int value, bool overrideState = false)
: base(value, overrideState) { }
///
/// Interpolates between two int values.
///
/// The start value
/// The end value
/// The interpolation factor in range [0,1]
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).
m_Value = (int)(from + (to - from) * t);
}
}
///
/// A that holds a non-interpolating int value.
///
///
///
///
///
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class NoInterpIntParameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public NoInterpIntParameter(int value, bool overrideState = false)
: base(value, overrideState) { }
}
///
/// A that holds an int value clamped to a
/// minimum value.
///
///
///
///
///
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class MinIntParameter : IntParameter
{
///
/// The minimum value to clamp this parameter to.
///
[NonSerialized]
public int min;
///
/// The value that this parameter stores.
///
///
/// You can override this property to define custom behaviors when the value is changed.
///
public override int value
{
get => m_Value;
set => m_Value = Mathf.Max(value, min);
}
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The minimum value to clamp the parameter to.
/// The initial override state for the parameter.
public MinIntParameter(int value, int min, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
}
}
///
/// A that holds a non-interpolating int value that
/// clamped to a minimum value.
///
///
///
///
///
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class NoInterpMinIntParameter : VolumeParameter
{
///
/// The minimum value to clamp this parameter to.
///
[NonSerialized]
public int min;
///
/// The value that this parameter stores.
///
///
/// You can override this property to define custom behaviors when the value is changed.
///
public override int value
{
get => m_Value;
set => m_Value = Mathf.Max(value, min);
}
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The minimum value to clamp the parameter to.
/// The initial override state for the parameter.
public NoInterpMinIntParameter(int value, int min, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
}
}
///
/// A that holds an int value clamped to a
/// maximum value.
///
///
///
///
///
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class MaxIntParameter : IntParameter
{
///
/// The maximum value to clamp this parameter to.
///
[NonSerialized]
public int max;
///
/// The value that this parameter stores.
///
///
/// You can override this property to define custom behaviors when the value is changed.
///
public override int value
{
get => m_Value;
set => m_Value = Mathf.Min(value, max);
}
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The maximum value to clamp the parameter to.
/// The initial override state for the parameter.
public MaxIntParameter(int value, int max, bool overrideState = false)
: base(value, overrideState)
{
this.max = max;
}
}
///
/// A that holds a non-interpolating int value that
/// clamped to a maximum value.
///
///
///
///
///
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class NoInterpMaxIntParameter : VolumeParameter
{
///
/// The maximum value to clamp this parameter to.
///
[NonSerialized]
public int max;
///
/// The value that this parameter stores.
///
///
/// You can override this property to define custom behaviors when the value is changed.
///
public override int value
{
get => m_Value;
set => m_Value = Mathf.Min(value, max);
}
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The maximum value to clamp the parameter to.
/// The initial override state for the parameter.
public NoInterpMaxIntParameter(int value, int max, bool overrideState = false)
: base(value, overrideState)
{
this.max = max;
}
}
///
/// A that holds an int value clamped between a
/// minimum and a maximum value.
///
///
///
///
///
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class ClampedIntParameter : IntParameter
{
///
/// The minimum value to clamp this parameter to.
///
[NonSerialized]
public int min;
///
/// The maximum value to clamp this parameter to.
///
[NonSerialized]
public int max;
///
/// The value that this parameter stores.
///
///
/// You can override this property to define custom behaviors when the value is changed.
///
public override int value
{
get => m_Value;
set => m_Value = Mathf.Clamp(value, min, max);
}
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The minimum value to clamp the parameter to
/// The maximum value to clamp the parameter to.
/// The initial override state for the parameter.
public ClampedIntParameter(int value, int min, int max, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
this.max = max;
}
}
///
/// A that holds a non-interpolating int value
/// clamped between a minimum and a maximum value.
///
///
///
///
///
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class NoInterpClampedIntParameter : VolumeParameter
{
///
/// The minimum value to clamp this parameter to.
///
[NonSerialized]
public int min;
///
/// The maximum value to clamp this parameter to.
///
[NonSerialized]
public int max;
///
/// The value that this parameter stores.
///
///
/// You can override this property to define custom behaviors when the value is changed.
///
public override int value
{
get => m_Value;
set => m_Value = Mathf.Clamp(value, min, max);
}
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The minimum value to clamp the parameter to
/// The maximum value to clamp the parameter to.
/// The initial override state for the parameter.
public NoInterpClampedIntParameter(int value, int min, int max, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
this.max = max;
}
}
///
/// A that holds a float value.
///
///
///
///
///
///
///
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class FloatParameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter
/// The initial override state for the parameter
public FloatParameter(float value, bool overrideState = false)
: base(value, overrideState) { }
///
/// Interpolates between two float values.
///
/// The start value
/// The end value
/// The interpolation factor in range [0,1]
public sealed override void Interp(float from, float to, float t)
{
m_Value = from + (to - from) * t;
}
}
///
/// A that holds a non-interpolating float value.
///
///
///
///
///
///
///
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class NoInterpFloatParameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter
/// The initial override state for the parameter.
public NoInterpFloatParameter(float value, bool overrideState = false)
: base(value, overrideState) { }
}
///
/// A that holds a float value clamped to a minimum value.
///
///
///
///
///
///
///
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class MinFloatParameter : FloatParameter
{
///
/// The minimum value to clamp this parameter to.
///
[NonSerialized]
public float min;
///
/// The value that this parameter stores.
///
///
/// You can override this property to define custom behaviors when the value is changed.
///
public override float value
{
get => m_Value;
set => m_Value = Mathf.Max(value, min);
}
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The minimum value to clamp the parameter to.
/// The initial override state for the parameter.
public MinFloatParameter(float value, float min, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
}
}
///
/// A that holds a non-interpolating float value clamped to
/// a minimum value.
///
///
///
///
///
///
///
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class NoInterpMinFloatParameter : VolumeParameter
{
///
/// The minimum value to clamp this parameter to.
///
[NonSerialized]
public float min;
///
/// The value that this parameter stores.
///
///
/// You can override this property to define custom behaviors when the value is changed.
///
public override float value
{
get => m_Value;
set => m_Value = Mathf.Max(value, min);
}
///
/// Creates a new instance.
///
/// The initial value to storedin the parameter.
/// The minimum value to clamp the parameter to.
/// The initial override state for the parameter.
public NoInterpMinFloatParameter(float value, float min, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
}
}
///
/// A that holds a float value clamped to a max value.
///
///
///
///
///
///
///
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class MaxFloatParameter : FloatParameter
{
///
/// The maximum value to clamp this parameter to.
///
[NonSerialized]
public float max;
///
/// The value that this parameter stores.
///
///
/// You can override this property to define custom behaviors when the value is changed.
///
public override float value
{
get => m_Value;
set => m_Value = Mathf.Min(value, max);
}
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The maximum value to clamp the parameter to.
/// The initial override state for the parameter.
public MaxFloatParameter(float value, float max, bool overrideState = false)
: base(value, overrideState)
{
this.max = max;
}
}
///
/// A that holds a non-interpolating float value clamped to
/// a maximum value.
///
///
///
///
///
///
///
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class NoInterpMaxFloatParameter : VolumeParameter
{
///
/// The maximum value to clamp this parameter to.
///
[NonSerialized]
public float max;
///
/// The value that this parameter stores.
///
///
/// You can override this property to define custom behaviors when the value is changed.
///
public override float value
{
get => m_Value;
set => m_Value = Mathf.Min(value, max);
}
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The maximum value to clamp the parameter to.
/// The initial override state for the parameter.
public NoInterpMaxFloatParameter(float value, float max, bool overrideState = false)
: base(value, overrideState)
{
this.max = max;
}
}
///
/// A that holds a float value clamped between a minimum and a
/// maximum value.
///
///
///
///
///
///
///
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class ClampedFloatParameter : FloatParameter
{
///
/// The minimum value to clamp this parameter to.
///
[NonSerialized]
public float min;
///
/// The maximum value to clamp this parameter to.
///
[NonSerialized]
public float max;
///
/// The value that this parameter stores.
///
///
/// You can override this property to define custom behaviors when the value is changed.
///
public override float value
{
get => m_Value;
set => m_Value = Mathf.Clamp(value, min, max);
}
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The minimum value to clamp the parameter to
/// The maximum value to clamp the parameter to.
/// The initial override state for the parameter.
public ClampedFloatParameter(float value, float min, float max, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
this.max = max;
}
}
///
/// A that holds a non-interpolating float value clamped between
/// a minimum and a maximum value.
///
///
///
///
///
///
///
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class NoInterpClampedFloatParameter : VolumeParameter
{
///
/// The minimum value to clamp this parameter to.
///
[NonSerialized]
public float min;
///
/// The maximum value to clamp this parameter to.
///
[NonSerialized]
public float max;
///
/// The value that this parameter stores.
///
///
/// You can override this property to define custom behaviors when the value is changed.
///
public override float value
{
get => m_Value;
set => m_Value = Mathf.Clamp(value, min, max);
}
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The minimum value to clamp the parameter to
/// The maximum value to clamp the parameter to.
/// The initial override state for the parameter.
public NoInterpClampedFloatParameter(float value, float min, float max, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
this.max = max;
}
}
///
/// A that holds a Vector2 value holding a range of two
/// float values clamped between a minimum and a maximum value.
///
///
///
///
///
///
///
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class FloatRangeParameter : VolumeParameter
{
///
/// The minimum value to clamp this parameter to.
///
[NonSerialized]
public float min;
///
/// The maximum value to clamp this parameter to.
///
[NonSerialized]
public float max;
///
/// The value that this parameter stores.
///
///
/// You can override this property to define custom behaviors when the value is changed.
///
public override Vector2 value
{
get => m_Value;
set
{
m_Value.x = Mathf.Max(value.x, min);
m_Value.y = Mathf.Min(value.y, max);
}
}
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The minimum value to clamp the parameter to
/// The maximum value to clamp the parameter to.
/// The initial override state for the parameter.
public FloatRangeParameter(Vector2 value, float min, float max, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
this.max = max;
}
///
/// Interpolates between two Vector2 values.
///
/// The start value
/// The end value
/// The interpolation factor in range [0,1]
public override void Interp(Vector2 from, Vector2 to, float t)
{
m_Value.x = from.x + (to.x - from.x) * t;
m_Value.y = from.y + (to.y - from.y) * t;
}
}
///
/// A that holds a non-interpolating Vector2 value holding
/// a range of two float values clamped between a minimum and a maximum value.
///
///
///
///
///
///
///
///
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class NoInterpFloatRangeParameter : VolumeParameter
{
///
/// The minimum value to clamp this parameter to.
///
[NonSerialized]
public float min;
///
/// The maximum value to clamp this parameter to.
///
[NonSerialized]
public float max;
///
/// The value that this parameter stores.
///
///
/// You can override this property to define custom behaviors when the value is changed.
///
public override Vector2 value
{
get => m_Value;
set
{
m_Value.x = Mathf.Max(value.x, min);
m_Value.y = Mathf.Min(value.y, max);
}
}
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The minimum value to clamp the parameter to
/// The maximum value to clamp the parameter to.
/// The initial override state for the parameter.
public NoInterpFloatRangeParameter(Vector2 value, float min, float max, bool overrideState = false)
: base(value, overrideState)
{
this.min = min;
this.max = max;
}
}
///
/// A that holds a Color value.
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class ColorParameter : VolumeParameter
{
///
/// Is this color HDR?
///
[NonSerialized]
public bool hdr = false;
///
/// Should the alpha channel be editable in the editor?
///
[NonSerialized]
public bool showAlpha = true;
///
/// Should the eye dropper be visible in the editor?
///
[NonSerialized]
public bool showEyeDropper = true;
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public ColorParameter(Color value, bool overrideState = false)
: base(value, overrideState) { }
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// Specifies whether the color is HDR or not.
/// Specifies whether you can edit the alpha channel in the Inspector or not.
/// Specifies whether the eye dropper is visible in the editor or not.
/// The initial override state for the parameter.
public ColorParameter(Color value, bool hdr, bool showAlpha, bool showEyeDropper, bool overrideState = false)
: base(value, overrideState)
{
this.hdr = hdr;
this.showAlpha = showAlpha;
this.showEyeDropper = showEyeDropper;
this.overrideState = overrideState;
}
///
/// Interpolates between two Color values.
///
///
/// For performance reasons, this function interpolates the RGBA channels directly.
///
/// The start value.
/// The end value.
/// The interpolation factor in range [0,1].
public override void Interp(Color from, Color to, float t)
{
// Lerping color values is a sensitive subject... We looked into lerping colors using
// HSV and LCH but they have some downsides that make them not work correctly in all
// situations, so we stick with RGB lerping for now, at least its behavior is
// predictable despite looking desaturated when `t ~= 0.5` and it's faster anyway.
m_Value.r = from.r + (to.r - from.r) * t;
m_Value.g = from.g + (to.g - from.g) * t;
m_Value.b = from.b + (to.b - from.b) * t;
m_Value.a = from.a + (to.a - from.a) * t;
}
}
///
/// A that holds a non-interpolating Color value.
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class NoInterpColorParameter : VolumeParameter
{
///
/// Specifies whether the color is HDR or not.
///
public bool hdr = false;
///
/// Specifies whether you can edit the alpha channel in the Inspector or not.
///
[NonSerialized]
public bool showAlpha = true;
///
/// Specifies whether the eye dropper is visible in the editor or not.
///
[NonSerialized]
public bool showEyeDropper = true;
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public NoInterpColorParameter(Color value, bool overrideState = false)
: base(value, overrideState) { }
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// Specifies whether the color is HDR or not.
/// Specifies whether you can edit the alpha channel in the Inspector or not.
/// Specifies whether the eye dropper is visible in the editor or not.
/// The initial override state for the parameter.
public NoInterpColorParameter(Color value, bool hdr, bool showAlpha, bool showEyeDropper, bool overrideState = false)
: base(value, overrideState)
{
this.hdr = hdr;
this.showAlpha = showAlpha;
this.showEyeDropper = showEyeDropper;
this.overrideState = overrideState;
}
}
///
/// A that holds a Vector2 value.
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class Vector2Parameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public Vector2Parameter(Vector2 value, bool overrideState = false)
: base(value, overrideState) { }
///
/// Interpolates between two Vector2 values.
///
/// The start value.
/// The end value.
/// The interpolation factor in range [0,1].
public override void Interp(Vector2 from, Vector2 to, float t)
{
m_Value.x = from.x + (to.x - from.x) * t;
m_Value.y = from.y + (to.y - from.y) * t;
}
}
///
/// A that holds a non-interpolating Vector2 value.
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class NoInterpVector2Parameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public NoInterpVector2Parameter(Vector2 value, bool overrideState = false)
: base(value, overrideState) { }
}
///
/// A that holds a Vector3 value.
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class Vector3Parameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public Vector3Parameter(Vector3 value, bool overrideState = false)
: base(value, overrideState) { }
///
/// Interpolates between two Vector3 values.
///
/// The start value.
/// The end value.
/// The interpolation factor in range [0,1].
public override void Interp(Vector3 from, Vector3 to, float t)
{
m_Value.x = from.x + (to.x - from.x) * t;
m_Value.y = from.y + (to.y - from.y) * t;
m_Value.z = from.z + (to.z - from.z) * t;
}
}
///
/// A that holds a non-interpolating Vector3 value.
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class NoInterpVector3Parameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public NoInterpVector3Parameter(Vector3 value, bool overrideState = false)
: base(value, overrideState) { }
}
///
/// A that holds a Vector4 value.
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class Vector4Parameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public Vector4Parameter(Vector4 value, bool overrideState = false)
: base(value, overrideState) { }
///
/// Interpolates between two Vector4 values.
///
/// The start value.
/// The end value.
/// The interpolation factor in range [0,1].
public override void Interp(Vector4 from, Vector4 to, float t)
{
m_Value.x = from.x + (to.x - from.x) * t;
m_Value.y = from.y + (to.y - from.y) * t;
m_Value.z = from.z + (to.z - from.z) * t;
m_Value.w = from.w + (to.w - from.w) * t;
}
}
///
/// A that holds a non-interpolating Vector4 value.
///
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class NoInterpVector4Parameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public NoInterpVector4Parameter(Vector4 value, bool overrideState = false)
: base(value, overrideState) { }
}
///
/// A that holds a Texture value.
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class TextureParameter : VolumeParameter
{
///
/// The accepted dimension of textures.
///
public TextureDimension dimension;
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public TextureParameter(Texture value, bool overrideState = false)
: this(value, TextureDimension.Any, overrideState) { }
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The accepted dimension of textures.
/// The initial override state for the parameter.
public TextureParameter(Texture value, TextureDimension dimension, bool overrideState = false)
: base(value, overrideState)
{
this.dimension = dimension;
}
// TODO: Texture interpolation
///
/// Returns a hash code for the current object.
///
/// A hash code for the current object.
public override int GetHashCode()
{
int hash = base.GetHashCode();
unchecked
{
if (value != null)
hash = 23 * CoreUtils.GetTextureHash(value);
}
return hash;
}
}
///
/// A that holds a non-interpolating Texture value.
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class NoInterpTextureParameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public NoInterpTextureParameter(Texture value, bool overrideState = false)
: base(value, overrideState) { }
///
/// Returns a hash code for the current object.
///
/// A hash code for the current object.
public override int GetHashCode()
{
int hash = base.GetHashCode();
unchecked
{
if (value != null)
hash = 23 * CoreUtils.GetTextureHash(value);
}
return hash;
}
}
///
/// A that holds a 2D Texture value.
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class Texture2DParameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public Texture2DParameter(Texture value, bool overrideState = false)
: base(value, overrideState) { }
///
/// Returns a hash code for the current object.
///
/// A hash code for the current object.
public override int GetHashCode()
{
int hash = base.GetHashCode();
unchecked
{
if (value != null)
hash = 23 * CoreUtils.GetTextureHash(value);
}
return hash;
}
}
///
/// A that holds a 3D Texture value.
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class Texture3DParameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public Texture3DParameter(Texture value, bool overrideState = false)
: base(value, overrideState) { }
///
/// Returns a hash code for the current object.
///
/// A hash code for the current object.
public override int GetHashCode()
{
int hash = base.GetHashCode();
unchecked
{
if (value != null)
hash = 23 * CoreUtils.GetTextureHash(value);
}
return hash;
}
}
///
/// A that holds a RenderTexture value.
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class RenderTextureParameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public RenderTextureParameter(RenderTexture value, bool overrideState = false)
: base(value, overrideState) { }
// TODO: RenderTexture interpolation
///
/// Returns a hash code for the current object.
///
/// A hash code for the current object.
public override int GetHashCode()
{
int hash = base.GetHashCode();
unchecked
{
if (value != null)
hash = 23 * CoreUtils.GetTextureHash(value);
}
return hash;
}
}
///
/// A that holds a non-interpolating RenderTexture value.
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class NoInterpRenderTextureParameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public NoInterpRenderTextureParameter(RenderTexture value, bool overrideState = false)
: base(value, overrideState) { }
///
/// Returns a hash code for the current object.
///
/// A hash code for the current object.
public override int GetHashCode()
{
int hash = base.GetHashCode();
unchecked
{
if (value != null)
hash = 23 * CoreUtils.GetTextureHash(value);
}
return hash;
}
}
///
/// A that holds a Cubemap value.
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class CubemapParameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public CubemapParameter(Texture value, bool overrideState = false)
: base(value, overrideState) { }
// TODO: Cubemap interpolation
///
/// Returns a hash code for the current object.
///
/// A hash code for the current object.
public override int GetHashCode()
{
int hash = base.GetHashCode();
unchecked
{
if (value != null)
hash = 23 * CoreUtils.GetTextureHash(value);
}
return hash;
}
}
///
/// A that holds a non-interpolating Cubemap value.
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class NoInterpCubemapParameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
/// The initial override state for the parameter.
public NoInterpCubemapParameter(Cubemap value, bool overrideState = false)
: base(value, overrideState) { }
///
/// Returns a hash code for the current object.
///
/// A hash code for the current object.
public override int GetHashCode()
{
int hash = base.GetHashCode();
unchecked
{
if (value != null)
hash = 23 * CoreUtils.GetTextureHash(value);
}
return hash;
}
}
///
/// A that holds a serializable class or struct.
///
/// The type of serializable object or struct to hold in this parameter.
///
// TODO: ObjectParameter doesn't seem to be working as expect, debug me
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class ObjectParameter : VolumeParameter
{
internal ReadOnlyCollection parameters { get; private set; }
///
/// The current override state for this parameter. Note that this is always forced enabled
/// on .
///
public sealed override bool overrideState
{
get => true;
set => m_OverrideState = true;
}
///
/// The value stored by this parameter.
///
public sealed override T value
{
get => m_Value;
set
{
m_Value = value;
if (m_Value == null)
{
parameters = null;
return;
}
// Automatically grab all fields of type VolumeParameter contained in this instance
parameters = m_Value.GetType()
.GetFields(BindingFlags.Public | BindingFlags.Instance)
.Where(t => t.FieldType.IsSubclassOf(typeof(VolumeParameter)))
.OrderBy(t => t.MetadataToken) // Guaranteed order
.Select(t => (VolumeParameter)t.GetValue(m_Value))
.ToList()
.AsReadOnly();
}
}
///
/// Creates a new instance.
///
/// The initial value to store in the parameter.
public ObjectParameter(T value)
{
m_OverrideState = true;
this.value = value;
}
internal override void Interp(VolumeParameter from, VolumeParameter to, float t)
{
if (m_Value == null)
return;
var paramOrigin = parameters;
var paramFrom = ((ObjectParameter)from).parameters;
var paramTo = ((ObjectParameter)to).parameters;
for (int i = 0; i < paramFrom.Count; i++)
{
// Keep track of the override state for debugging purpose
paramOrigin[i].overrideState = paramTo[i].overrideState;
if (paramTo[i].overrideState)
paramOrigin[i].Interp(paramFrom[i], paramTo[i], t);
}
}
}
///
/// A that holds an AnimationCurve value.
///
[Serializable]
public class AnimationCurveParameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to be stored in the parameter
/// The initial override state for the parameter
public AnimationCurveParameter(AnimationCurve value, bool overrideState = false)
: base(value, overrideState) { }
///
/// Interpolates between two AnimationCurve values. Note that it will overwrite the values in lhsCurve,
/// whereas rhsCurve data will be unchanged. Thus, it is legal to call it as:
/// stateParam.Interp(stateParam, toParam, interpFactor);
/// However, It should NOT be called when the lhsCurve parameter needs to be preserved. But the current
/// framework modifies it anyway in VolumeComponent.Override for all types of VolumeParameters
///
/// The start value.
/// The end value.
/// The interpolation factor in range [0,1].
public override void Interp(AnimationCurve lhsCurve, AnimationCurve rhsCurve, float t)
{
m_Value = lhsCurve;
KeyframeUtility.InterpAnimationCurve(ref m_Value, rhsCurve, t);
}
///
public override void SetValue(VolumeParameter parameter)
{
m_Value.CopyFrom(((AnimationCurveParameter)parameter).m_Value);
}
///
public override object Clone()
{
return new AnimationCurveParameter(new AnimationCurve(GetValue().keys), overrideState);
}
///
/// Returns a hash code for the animationCurve.
///
/// A hash code for the animationCurve.
public override int GetHashCode()
{
unchecked
{
var hash = overrideState.GetHashCode();
return hash * 23 + value.GetHashCode();
}
}
}
///
/// A that holds a value.
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public class MaterialParameter : VolumeParameter
{
///
/// Creates a new instance.
///
/// The initial value to store in the parameter
/// The initial override state for the parameter
public MaterialParameter(Material value, bool overrideState = false)
: base(value, overrideState) { }
}
}