using System; namespace UnityEngine.Rendering.HighDefinition { /// /// Settings for shadows. /// [Serializable, VolumeComponentMenu("Shadowing/Shadows")] [HelpURL(Documentation.baseURL + Documentation.version + Documentation.subURL + "Override-Shadows" + Documentation.endURL)] public class HDShadowSettings : VolumeComponent { float[] m_CascadeShadowSplits = new float[3]; float[] m_CascadeShadowBorders = new float[4]; /// /// Repartition of shadow cascade splits for directional lights. /// public float[] cascadeShadowSplits { get { m_CascadeShadowSplits[0] = cascadeShadowSplit0.value; m_CascadeShadowSplits[1] = cascadeShadowSplit1.value; m_CascadeShadowSplits[2] = cascadeShadowSplit2.value; return m_CascadeShadowSplits; } } /// /// Size of the border between each shadow cascades for directional lights. /// public float[] cascadeShadowBorders { get { m_CascadeShadowBorders[0] = cascadeShadowBorder0.value; m_CascadeShadowBorders[1] = cascadeShadowBorder1.value; m_CascadeShadowBorders[2] = cascadeShadowBorder2.value; m_CascadeShadowBorders[3] = cascadeShadowBorder3.value; // For now we don't use shadow cascade borders but we still want to have the last split fading out. if (!HDRenderPipeline.s_UseCascadeBorders) { m_CascadeShadowBorders[cascadeShadowSplitCount.value - 1] = 0.2f; } return m_CascadeShadowBorders; } } /// Sets the maximum distance HDRP renders shadows for all Light types. [Tooltip("Sets the maximum distance HDRP renders shadows for all Light types.")] public NoInterpMinFloatParameter maxShadowDistance = new NoInterpMinFloatParameter(500.0f, 0.0f); /// Multiplier for thick transmission for directional lights. [Tooltip("Multiplier for thick transmission.")] public ClampedFloatParameter directionalTransmissionMultiplier = new ClampedFloatParameter(1.0f, 0.0f, 1.0f); /// Number of cascades HDRP uses for cascaded shadow maps. [Tooltip("Controls the number of cascades HDRP uses for cascaded shadow maps.")] public NoInterpClampedIntParameter cascadeShadowSplitCount = new NoInterpClampedIntParameter(4, 1, 4); /// Position of the first cascade split as a percentage of Max Distance if the parameter is normalized or as the distance from the camera if it's not normalized. [Tooltip("Sets the position of the first cascade split as a percentage of Max Distance if the parameter is normalized or as the distance from the camera if it's not normalized.")] public CascadePartitionSplitParameter cascadeShadowSplit0 = new CascadePartitionSplitParameter(0.05f); /// Position of the second cascade split as a percentage of Max Distance if the parameter is normalized or as the distance from the camera if it's not normalized. [Tooltip("Sets the position of the second cascade split as a percentage of Max Distance if the parameter is normalized or as the distance from the camera if it's not normalized.")] public CascadePartitionSplitParameter cascadeShadowSplit1 = new CascadePartitionSplitParameter(0.15f); /// Sets the position of the third cascade split as a percentage of Max Distance if the parameter is normalized or as the distance from the camera if it's not normalized. [Tooltip("Sets the position of the third cascade split as a percentage of Max Distance if the parameter is normalized or as the distance from the camera if it's not normalized.")] public CascadePartitionSplitParameter cascadeShadowSplit2 = new CascadePartitionSplitParameter(0.3f); /// Border size between the first and second cascade split. [Tooltip("Sets the border size between the first and second cascade split.")] public CascadeEndBorderParameter cascadeShadowBorder0 = new CascadeEndBorderParameter(0.0f); /// Border size between the second and third cascade split. [Tooltip("Sets the border size between the second and third cascade split.")] public CascadeEndBorderParameter cascadeShadowBorder1 = new CascadeEndBorderParameter(0.0f); /// Border size between the third and last cascade split. [Tooltip("Sets the border size between the third and last cascade split.")] public CascadeEndBorderParameter cascadeShadowBorder2 = new CascadeEndBorderParameter(0.0f); /// Border size at the end of the last cascade split. [Tooltip("Sets the border size at the end of the last cascade split.")] public CascadeEndBorderParameter cascadeShadowBorder3 = new CascadeEndBorderParameter(0.0f); HDShadowSettings() { displayName = "Shadows"; cascadeShadowSplit0.Init(cascadeShadowSplitCount, 2, maxShadowDistance, null, cascadeShadowSplit1); cascadeShadowSplit1.Init(cascadeShadowSplitCount, 3, maxShadowDistance, cascadeShadowSplit0, cascadeShadowSplit2); cascadeShadowSplit2.Init(cascadeShadowSplitCount, 4, maxShadowDistance, cascadeShadowSplit1, null); cascadeShadowBorder0.Init(cascadeShadowSplitCount, 1, maxShadowDistance, null, cascadeShadowSplit0); cascadeShadowBorder1.Init(cascadeShadowSplitCount, 2, maxShadowDistance, cascadeShadowSplit0, cascadeShadowSplit1); cascadeShadowBorder2.Init(cascadeShadowSplitCount, 3, maxShadowDistance, cascadeShadowSplit1, cascadeShadowSplit2); cascadeShadowBorder3.Init(cascadeShadowSplitCount, 4, maxShadowDistance, cascadeShadowSplit2, null); } internal void InitNormalized(bool normalized) { cascadeShadowSplit0.normalized = normalized; cascadeShadowSplit1.normalized = normalized; cascadeShadowSplit2.normalized = normalized; cascadeShadowBorder0.normalized = normalized; cascadeShadowBorder1.normalized = normalized; cascadeShadowBorder2.normalized = normalized; cascadeShadowBorder3.normalized = normalized; } } /// /// Cascade Partition split parameter. /// [Serializable] public class CascadePartitionSplitParameter : VolumeParameter { [NonSerialized] NoInterpMinFloatParameter maxDistance; internal bool normalized; [NonSerialized] CascadePartitionSplitParameter previous; [NonSerialized] CascadePartitionSplitParameter next; [NonSerialized] NoInterpClampedIntParameter cascadeCounts; int minCascadeToAppears; internal float min => previous?.value ?? 0f; internal float max => (cascadeCounts.value > minCascadeToAppears && next != null) ? next.value : 1f; internal float representationDistance => maxDistance.value; /// /// Size of the split. /// public override float value { get => m_Value; set => m_Value = Mathf.Clamp(value, min, max); } /// /// Cascade Partition split parameter constructor. /// /// Initial value. /// Partition is normalized. /// Initial override state. public CascadePartitionSplitParameter(float value, bool normalized = false, bool overrideState = false) : base(value, overrideState) => this.normalized = normalized; internal void Init(NoInterpClampedIntParameter cascadeCounts, int minCascadeToAppears, NoInterpMinFloatParameter maxDistance, CascadePartitionSplitParameter previous, CascadePartitionSplitParameter next) { this.maxDistance = maxDistance; this.previous = previous; this.next = next; this.cascadeCounts = cascadeCounts; this.minCascadeToAppears = minCascadeToAppears; } } /// /// Cascade End Border parameter. /// [Serializable] public class CascadeEndBorderParameter : VolumeParameter { internal bool normalized; [NonSerialized] CascadePartitionSplitParameter min; [NonSerialized] CascadePartitionSplitParameter max; [NonSerialized] NoInterpMinFloatParameter maxDistance; [NonSerialized] NoInterpClampedIntParameter cascadeCounts; int minCascadeToAppears; internal float representationDistance => (((cascadeCounts.value > minCascadeToAppears && max != null) ? max.value : 1f) - (min?.value ?? 0f)) * maxDistance.value; /// /// Size of the border. /// public override float value { get => m_Value; set => m_Value = Mathf.Clamp01(value); } /// /// Cascade End Border parameter constructor. /// /// Initial value. /// Normalized. /// Initial override state. public CascadeEndBorderParameter(float value, bool normalized = false, bool overrideState = false) : base(value, overrideState) => this.normalized = normalized; internal void Init(NoInterpClampedIntParameter cascadeCounts, int minCascadeToAppears, NoInterpMinFloatParameter maxDistance, CascadePartitionSplitParameter min, CascadePartitionSplitParameter max) { this.maxDistance = maxDistance; this.min = min; this.max = max; this.cascadeCounts = cascadeCounts; this.minCascadeToAppears = minCascadeToAppears; } } }