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; } }