using System.Collections.Generic; namespace UnityEngine.Rendering.HighDefinition { /// /// Controls the type of the procedural water deformer. /// [GenerateHLSL(PackingRules.Exact)] public enum WaterDeformerType { /// /// Sphere deformer. /// Sphere = 0, /// /// Box deformer. /// Box = 1, /// /// Bow Wave deformer. /// BowWave = 2, /// /// Shore Wave deformer. /// ShoreWave = 3, /// /// Texture deformer. /// Texture = 4, /// /// Material deformer. /// Material = 5, } /// /// Water deformer component. /// [DisallowMultipleComponent] [HDRPHelpURL("WaterSystem-waterdeformer")] [ExecuteInEditMode] public partial class WaterDeformer : MonoBehaviour { internal enum PassType { Deformer = 0, FoamGenerator = 1, } #region General /// /// Specifies the type of the deformer. This parameter defines which parameters will be used to render it. /// public WaterDeformerType type = WaterDeformerType.Sphere; /// /// Specifies the amplitude of the deformer. This parameter is used differently based on the deformer type. /// public float amplitude = 2.0f; /// /// Specifies the size of the deformer in meters. /// public Vector2 regionSize = new Vector2(20.0f, 20.0f); /// /// The scaling mode to apply to this Foam Generator. /// [Tooltip("Specify the scaling mode")] public DecalScaleMode scaleMode = DecalScaleMode.ScaleInvariant; #endregion #region Box Deformer /// /// Specifies the range that is used to blend the box deformer. /// [Min(0.0f)] public Vector2 boxBlend; /// /// When enabled, the box deformer will have a cubic blend on the edges (instead of procedural). /// public bool cubicBlend = true; #endregion #region Shore Wave Deformer /// /// Specifies the wave length of the individual waves of the shore wave deformer. /// [Min(1.0f)] public float waveLength = 3.0f; /// /// Specifies the wave repetition of the waves. A higher value implies that additional waves will be skipped. /// [Min(1)] public int waveRepetition = 10; /// /// Specifies the speed of the waves in kilometers per hour. /// public float waveSpeed = 15.0f; /// /// Specifies the offset in the waves' position. /// public float waveOffset = 0.0f; /// /// Specifies the blend size on the length of the deformer's region. /// public Vector2 waveBlend = new Vector2(0.3f, 0.6f); /// /// Specifies the range in which the waves break and generate surface foam. /// public Vector2 breakingRange = new Vector2(0.7f, 0.8f); /// /// Specifies the range in which the waves generate deep foam. /// public Vector2 deepFoamRange = new Vector2(0.5f, 0.8f); #endregion #region BowWave Deformer /// /// Specifies the elevation of outer part of the bow wave. /// public float bowWaveElevation = 1.0f; #endregion #region Texture Deformer /// /// Specifies the range of the texture deformer /// public Vector2 range = new Vector2(0.0f, 1.0f); /// /// Specifies the texture used for the deformer. /// [Tooltip("Specifies the texture used for the deformer.")] public Texture texture = null; #endregion #region Material Deformer /// /// Specifies the resolution when written inside the atlas. /// public Vector2Int resolution = new Vector2Int(256, 256); /// /// Frequency of update of the Material in the atlas. /// [Tooltip("Frequency of update of the Material in the atlas.")] public CustomRenderTextureUpdateMode updateMode = CustomRenderTextureUpdateMode.OnLoad; /// /// Specifies the material used for the deformer. /// [Tooltip("Specifies the material used for the deformer.")] public Material material = null; internal bool shouldUpdate = false; /// /// Triggers a render of the material in the deformer atlas. /// public void RequestUpdate() { shouldUpdate = true; } internal MaterialPropertyBlock mpb; /// /// Override per-deformer material parameters. This is more memory efficient than having one complete distinct Material per deformer but is recommended when only a few properties of a Material overriden. /// /// Property block with values you want to override. public void SetPropertyBlock(MaterialPropertyBlock properties) { mpb = properties; } /// /// Returns true if the Deformer has a material property block attached via SetPropertyBlock. /// /// Returns true if the Deformer has a material property block attached via SetPropertyBlock. public bool HasPropertyBlock() { return mpb != null; } internal bool IsValidMaterial() { #if UNITY_EDITOR return material != null && material.GetTag("ShaderGraphTargetId", false, null) == "WaterDecalSubTarget"; #else return true; #endif } internal int GetMaterialAtlasingId() { // If material has a property block, we can't reuse the atlas slot if (HasPropertyBlock()) return GetInstanceID(); else return material.GetInstanceID(); } #endregion #region Foam /// /// Specifies the dimmer for the deep foam generated by the deformer. /// [Range(0.0f, 1.0f)] public float deepFoamDimmer = 1.0f; /// /// Specifies the dimmer for the surface foam generated by the deformer. /// [Range(0.0f, 1.0f)] public float surfaceFoamDimmer = 1.0f; #endregion #region Instance Management // Management to avoid memory allocations at fetch time internal static HashSet instances = new HashSet(); internal static WaterDeformer[] instancesAsArray = null; internal static int instanceCount = 0; internal static void RegisterInstance(WaterDeformer deformer) { instances.Add(deformer); instanceCount = instances.Count; if (instanceCount > 0) { instancesAsArray = new WaterDeformer[instanceCount]; instances.CopyTo(instancesAsArray); } else { instancesAsArray = null; } } internal static void UnregisterInstance(WaterDeformer deformer) { instances.Remove(deformer); instanceCount = instances.Count; if (instanceCount > 0) { instancesAsArray = new WaterDeformer[instanceCount]; instances.CopyTo(instancesAsArray); } else { instancesAsArray = null; } } #endregion #region MonoBehavior Methods private void Start() { // Add this water surface to the internal surface management RegisterInstance(this); } private void Awake() { // Add this water surface to the internal surface management RegisterInstance(this); } private void OnEnable() { // Add this water surface to the internal surface management RegisterInstance(this); if (updateMode == CustomRenderTextureUpdateMode.OnLoad) shouldUpdate = true; } private void OnDisable() { // Remove this water surface from the internal surface management UnregisterInstance(this); } void OnDestroy() { // Remove this water surface from the internal surface management UnregisterInstance(this); } #endregion } }