using System;
using System.Diagnostics;
namespace UnityEngine.Rendering.HighDefinition
{
///
/// Rendering space used for planetary effects
///
public enum RenderingSpace
{
///
/// Always centered around the camera
///
Camera,
///
/// Rendered in world space
///
World,
};
///
/// Visual Environment Volume Component.
/// This component setups the sky used for rendering as well as the way ambient probe should be computed.
///
[Serializable, VolumeComponentMenu("Visual Environment")]
[SupportedOnRenderPipeline(typeof(HDRenderPipelineAsset))]
[HDRPHelpURL("Override-Visual-Environment")]
public sealed partial class VisualEnvironment : VolumeComponent
{
internal const float k_DefaultEarthRadius = 6.3781f * 1000000;
///
/// Specifies how the planet center is computed
///
public enum PlanetMode
{
///
/// Top of the planet is located at the world origin.
///
Automatic,
///
/// Arbitrary position in space.
///
Manual,
};
/// Type of sky that should be used for rendering.
[Header("Sky")]
public NoInterpIntParameter skyType = new NoInterpIntParameter(0);
/// Type of clouds that should be used for rendering.
public NoInterpIntParameter cloudType = new NoInterpIntParameter(0);
/// Defines the way the ambient probe should be computed.
public SkyAmbientModeParameter skyAmbientMode = new SkyAmbientModeParameter(SkyAmbientMode.Dynamic);
/// Radius of the planet (distance from the center of the planet to the sea level). Units: kilometers.
[Header("Planet")]
public MinFloatParameter planetRadius = new MinFloatParameter(k_DefaultEarthRadius, 0);
/// When in Camera Space, sky and clouds will be centered on the camera. When in World Space, the camera can navigate through the atmosphere and the clouds.
[Tooltip("When in Camera Space, sky and clouds will be centered on the camera.\nWhen in World Space, the camera can navigate through the atmosphere and the clouds.")]
public EnumParameter renderingSpace = new(RenderingSpace.World);
/// The center is used when defining where the planets surface is. In automatic mode, the surface is at the world's origin and the center is derived from the planet radius.
[AdditionalProperty]
public EnumParameter centerMode = new(PlanetMode.Automatic);
/// Position of the center of the planet in world space. Units: kilometers.
[AdditionalProperty]
public Vector3Parameter planetCenter = new Vector3Parameter(new Vector3(0, -k_DefaultEarthRadius, 0));
/// Controls the global orientation of the wind relative to the X world vector.
[Header("Wind")]
public ClampedFloatParameter windOrientation = new ClampedFloatParameter(0.0f, 0.0f, 360.0f);
/// Controls the global wind speed in kilometers per hour.
public FloatParameter windSpeed = new FloatParameter(0.0f);
// Deprecated, kept for migration
[SerializeField]
internal FogTypeParameter fogType = new FogTypeParameter(FogType.None);
}
///
/// Informative enumeration containing SkyUniqeIDs already used by HDRP.
/// When users write their own sky type, they can use any ID not present in this enumeration or in their project.
///
public enum SkyType
{
/// HDRI Sky Unique ID.
HDRI = 1,
/// Procedural Sky Unique ID.
Procedural = 2,
/// Gradient Sky Unique ID.
Gradient = 3,
/// Physically Based Sky Unique ID.
PhysicallyBased = 4,
}
///
/// Informative enumeration containing CloudUniqeIDs already used by HDRP.
/// When users write their own cloud type, they can use any ID not present in this enumeration or in their project.
///
public enum CloudType
{
/// Cloud Layer Unique ID.
CloudLayer = 1,
}
///
/// Sky Ambient Mode.
///
public enum SkyAmbientMode
{
/// HDRP will use the static lighting sky setup in the lighting panel to compute the global ambient probe.
Static,
/// HDRP will use the current sky used for lighting (either the one setup in the Visual Environment component or the Sky Lighting Override) to compute the global ambient probe.
Dynamic,
}
///
/// Sky Ambient Mode volume parameter.
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class SkyAmbientModeParameter : VolumeParameter
{
///
/// Sky Ambient Mode volume parameter constructor.
///
/// Sky Ambient Mode parameter.
/// Initial override value.
public SkyAmbientModeParameter(SkyAmbientMode value, bool overrideState = false)
: base(value, overrideState) { }
}
///
/// Generic wind volume parameter.
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public abstract class WindParameter : VolumeParameter
{
/// Parameter override mode.
public enum WindOverrideMode
{
/// Custom value.
Custom,
/// Use the value from the Visual Environment.
Global,
/// Add a custom amount to the value from the Visual Environment.
Additive,
/// Multiply the value from the Visual Environment by a custom factor.
Multiply
}
/// Wind parameter value.
[Serializable]
public struct WindParamaterValue
{
/// Override mode.
public WindOverrideMode mode;
/// Value for the Custom mode.
public float customValue;
/// Value for the Additive mode.
public float additiveValue;
/// Value for the Multiply mode.
public float multiplyValue;
/// Returns a string that represents the current object.
/// A string that represents the current object.
public override string ToString()
{
if (mode == WindOverrideMode.Global)
return mode.ToString();
string str = null;
if (mode == WindOverrideMode.Custom)
str = customValue.ToString();
if (mode == WindOverrideMode.Additive)
str = additiveValue.ToString();
if (mode == WindOverrideMode.Multiply)
str = multiplyValue.ToString();
return str + " (" + mode.ToString() + ")";
}
}
/// Wind volume parameter constructor.
/// Initial value.
/// Initial override mode.
/// Initial override state.
public WindParameter(float value = 0.0f, WindOverrideMode mode = WindOverrideMode.Global, bool overrideState = false)
: base(default, overrideState)
{
this.value = new WindParamaterValue
{
mode = mode,
customValue = mode <= WindOverrideMode.Global ? value : 0.0f,
additiveValue = mode == WindOverrideMode.Additive ? value : 0.0f,
multiplyValue = mode == WindOverrideMode.Multiply ? value : 1.0f,
};
}
/// Interpolates between two values.
/// The start value
/// The end value
/// The interpolation factor in range [0,1]
public override void Interp(WindParamaterValue from, WindParamaterValue to, float t)
{
m_Value.mode = t > 0f ? to.mode : from.mode;
m_Value.customValue = from.customValue + (to.customValue - from.customValue) * t;
m_Value.additiveValue = from.additiveValue + (to.additiveValue - from.additiveValue) * t;
m_Value.multiplyValue = from.multiplyValue + (to.multiplyValue - from.multiplyValue) * t;
}
/// 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();
hash = hash * 23 + value.mode.GetHashCode();
hash = hash * 23 + value.customValue.GetHashCode();
hash = hash * 23 + value.additiveValue.GetHashCode();
hash = hash * 23 + value.multiplyValue.GetHashCode();
return hash;
}
}
/// Returns interpolated value from the visual environment.
/// The camera containing the volume stack to evaluate
/// The value for this parameter.
public virtual float GetValue(HDCamera camera)
{
if (value.mode == WindOverrideMode.Custom)
return value.customValue;
float globalValue = GetGlobalValue(camera);
if (value.mode == WindOverrideMode.Additive)
return globalValue + value.additiveValue;
if (value.mode == WindOverrideMode.Multiply)
return globalValue * value.multiplyValue;
return globalValue;
}
/// Returns the value stored in the volume.
/// The camera containing the volume stack to evaluate
/// The value for this parameter.
protected abstract float GetGlobalValue(HDCamera camera);
}
///
/// Wind Orientation parameter.
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class WindOrientationParameter : WindParameter
{
///
/// Wind orientation volume parameter constructor.
///
/// Sky Ambient Mode parameter.
/// Initial override mode.
/// Initial override value.
public WindOrientationParameter(float value = 0.0f, WindOverrideMode mode = WindOverrideMode.Global, bool overrideState = false)
: base(value, mode, overrideState) { }
/// Returns the value stored in the volume.
/// The camera containing the volume stack to evaluate
/// The value for this parameter.
protected override float GetGlobalValue(HDCamera camera) =>
camera.volumeStack.GetComponent().windOrientation.value;
/// Interpolates between two values.
/// The start value
/// The end value
/// The interpolation factor in range [0,1]
public override void Interp(WindParamaterValue from, WindParamaterValue to, float t)
{
// These are not used
m_Value.multiplyValue = 0;
// Binary state that cannot be blended
m_Value.mode = t > 0f ? to.mode : from.mode;
// Override the orientation specific values
m_Value.additiveValue = from.additiveValue + (to.additiveValue - from.additiveValue) * t;
m_Value.customValue = HDUtils.InterpolateOrientation(from.customValue, to.customValue, t);
}
/// Returns interpolated value from the visual environment.
/// The camera containing the volume stack to evaluate
/// The value for this parameter.
public override float GetValue(HDCamera camera)
{
// Multiply mode is not supported for wind orientation
if (value.mode == WindOverrideMode.Multiply)
throw new NotSupportedException("Texture format not supported");
// Otherwise we want the base behavior
return base.GetValue(camera);
}
}
///
/// Wind speed parameter.
///
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class WindSpeedParameter : WindParameter
{
///
/// Wind speed volume parameter constructor.
///
/// Sky Ambient Mode parameter.
/// Initial override mode.
/// Initial override value.
public WindSpeedParameter(float value = 100.0f, WindOverrideMode mode = WindOverrideMode.Global, bool overrideState = false)
: base(value, mode, overrideState) { }
/// Returns the value stored in the volume.
/// The camera containing the volume stack to evaluate
/// The value for this parameter.
protected override float GetGlobalValue(HDCamera camera) =>
camera.volumeStack.GetComponent().windSpeed.value;
}
}