diff --git a/crest/Assets/Crest/Crest/Scripts/WaterBody.cs b/crest/Assets/Crest/Crest/Scripts/WaterBody.cs index d9d323d0e..d03fe6221 100644 --- a/crest/Assets/Crest/Crest/Scripts/WaterBody.cs +++ b/crest/Assets/Crest/Crest/Scripts/WaterBody.cs @@ -7,6 +7,7 @@ using UnityEditor; #endif using UnityEngine; +using UnityEngine.Rendering; namespace Crest { @@ -33,6 +34,9 @@ public partial class WaterBody : MonoBehaviour bool _runValidationOnStart = true; #pragma warning restore 414 + [Tooltip("If clipping is enabled and set to clip everywhere by default, this option will register this water body to ensure its area does not get clipped."), SerializeField] + bool _registerWithClipSurfaceData = true; + public static List WaterBodies => _waterBodies; static List _waterBodies = new List(); @@ -43,16 +47,52 @@ public partial class WaterBody : MonoBehaviour "specified, the default material assigned to the OceanRenderer component will be used.")] public Material _overrideMaterial = null; + class ClipInput : ILodDataInput + { + Material _renderMat; + + // Render to all cascades + public float Wavelength => 0f; + public bool Enabled => true; + + public Matrix4x4 _transform; + + public ClipInput(WaterBody owner) + { + var rotateQuadFaceUp = Matrix4x4.Rotate(Quaternion.AngleAxis(90, Vector3.right)); + _transform = owner.transform.localToWorldMatrix * rotateQuadFaceUp; + + _renderMat = new Material(Shader.Find("Crest/Inputs/Clip Surface/Include Area")); + } + + public void Draw(CommandBuffer buf, float weight, int isTransition, int lodIdx) + { + buf.DrawMesh(RegisterLodDataInputBase.QuadMesh, _transform, _renderMat); + } + } + + ClipInput _clipInput; + private void OnEnable() { CalculateBounds(); _waterBodies.Add(this); + + // Needs to execute after the Ocean Renderer as Update is stripped from builds. + HandleClipInputRegistration(); } private void OnDisable() { _waterBodies.Remove(this); + + if (_clipInput != null) + { + RegisterLodDataInputBase.GetRegistrar(typeof(LodDataMgrClipSurface)).Remove(_clipInput); + + _clipInput = null; + } } private void CalculateBounds() @@ -67,6 +107,30 @@ private void CalculateBounds() AABB = bounds; } + void HandleClipInputRegistration() + { + var registered = _clipInput != null; + var shouldBeRegistered = _registerWithClipSurfaceData && OceanRenderer.Instance && OceanRenderer.Instance.CreateClipSurfaceData + && OceanRenderer.Instance._defaultClippingState == OceanRenderer.DefaultClippingState.EverythingClipped; + + if (registered != shouldBeRegistered) + { + if (shouldBeRegistered) + { + _clipInput = new ClipInput(this); + + var registrar = RegisterLodDataInputBase.GetRegistrar(typeof(LodDataMgrClipSurface)); + registrar.Add(0, _clipInput); + } + else + { + RegisterLodDataInputBase.GetRegistrar(typeof(LodDataMgrClipSurface)).Remove(_clipInput); + + _clipInput = null; + } + } + } + #if UNITY_EDITOR private void Start() { @@ -76,6 +140,17 @@ private void Start() } } + private void Update() + { + HandleClipInputRegistration(); + + if (_clipInput != null) + { + var rotateQuadFaceUp = Matrix4x4.Rotate(Quaternion.AngleAxis(90, Vector3.right)); + _clipInput._transform = transform.localToWorldMatrix * rotateQuadFaceUp; + } + } + private void OnDrawGizmosSelected() { // Required as we're not normally executing in edit mode diff --git a/crest/Assets/Crest/Crest/Scripts/WaterBody.cs.meta b/crest/Assets/Crest/Crest/Scripts/WaterBody.cs.meta index dd75dd203..cccd57c33 100644 --- a/crest/Assets/Crest/Crest/Scripts/WaterBody.cs.meta +++ b/crest/Assets/Crest/Crest/Scripts/WaterBody.cs.meta @@ -4,7 +4,7 @@ MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] - executionOrder: 0 + executionOrder: 203 icon: {instanceID: 0} userData: assetBundleName: diff --git a/docs/about/history.rst b/docs/about/history.rst index 22a514c6c..cab2b6acc 100644 --- a/docs/about/history.rst +++ b/docs/about/history.rst @@ -28,6 +28,7 @@ Changed - Add *Ocean Renderer > Water Body Culling* option so the ocean can ignore culling. Useful if using *Water Body > Override Material* and still want an ocean. - Improve multiple *Water Body* overlapping case when *Water Body > Override Material* option is used. + - Water Body adds an inclusion to clipping (ie unclips) if *Default Clipping State* is *Everything Clipped*. Fixed ^^^^^