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