升级6.4.升级水,升级天气
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using WaveHarmonic.Crest.Internal;
|
||||
|
||||
@@ -9,12 +8,12 @@ namespace WaveHarmonic.Crest
|
||||
{
|
||||
interface IReportsHeight
|
||||
{
|
||||
bool ReportHeight(ref Rect bounds, ref float minimum, ref float maximum);
|
||||
bool ReportHeight(WaterRenderer water, ref Rect bounds, ref float minimum, ref float maximum);
|
||||
}
|
||||
|
||||
interface IReportsDisplacement
|
||||
{
|
||||
bool ReportDisplacement(ref Rect bounds, ref float horizontal, ref float vertical);
|
||||
bool ReportDisplacement(WaterRenderer water, ref Rect bounds, ref float horizontal, ref float vertical);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -24,7 +23,7 @@ namespace WaveHarmonic.Crest
|
||||
[AddComponentMenu("")]
|
||||
#endif
|
||||
[@ExecuteDuringEditMode]
|
||||
sealed class WaterChunkRenderer : ManagedBehaviour<WaterRenderer>
|
||||
sealed partial class WaterChunkRenderer : ManagedBehaviour<WaterRenderer>
|
||||
{
|
||||
[SerializeField]
|
||||
internal bool _DrawRenderBounds = false;
|
||||
@@ -46,7 +45,13 @@ namespace WaveHarmonic.Crest
|
||||
internal Rect _UnexpandedBoundsXZ = new();
|
||||
public Rect UnexpandedBoundsXZ => _UnexpandedBoundsXZ;
|
||||
|
||||
internal Bounds _LocalBounds;
|
||||
internal float _LocalScale;
|
||||
|
||||
// WaterBody culling.
|
||||
internal bool _Culled;
|
||||
|
||||
// Frustum visibility.
|
||||
internal bool _Visible;
|
||||
|
||||
internal WaterRenderer _Water;
|
||||
@@ -59,10 +64,8 @@ namespace WaveHarmonic.Crest
|
||||
// contiguous surface.
|
||||
internal bool _WaterDataHasBeenBound = true;
|
||||
|
||||
int _LodIndex = -1;
|
||||
internal int _LodIndex = -1;
|
||||
|
||||
public static List<IReportsHeight> HeightReporters { get; } = new();
|
||||
public static List<IReportsDisplacement> DisplacementReporters { get; } = new();
|
||||
|
||||
// There is a 1-frame delay with Initialized in edit mode due to setting
|
||||
// enableInEditMode in EditorApplication.update. This only really affect this
|
||||
@@ -73,7 +76,6 @@ namespace WaveHarmonic.Crest
|
||||
_LodIndex = index;
|
||||
Rend = renderer;
|
||||
_Mesh = mesh;
|
||||
_PreviousObjectToWorld = _CurrentObjectToWorld = transform.localToWorldMatrix;
|
||||
_Transform = transform;
|
||||
}
|
||||
|
||||
@@ -118,8 +120,9 @@ namespace WaveHarmonic.Crest
|
||||
|
||||
internal void OnLateUpdate()
|
||||
{
|
||||
_PreviousObjectToWorld = _CurrentObjectToWorld;
|
||||
_PreviousObjectToWorld = _Water.Surface.PreviousObjectToWorld[_SiblingIndex];
|
||||
_CurrentObjectToWorld = _Transform.localToWorldMatrix;
|
||||
_Water.Surface.PreviousObjectToWorld[_SiblingIndex] = _CurrentObjectToWorld;
|
||||
}
|
||||
|
||||
internal void RenderMotionVectors(SurfaceRenderer surface, Camera camera)
|
||||
@@ -144,6 +147,7 @@ namespace WaveHarmonic.Crest
|
||||
matProps = _MaterialPropertyBlock,
|
||||
worldBounds = Rend.bounds,
|
||||
layer = surface.Layer,
|
||||
renderingLayerMask = (uint)surface.Layer,
|
||||
receiveShadows = false,
|
||||
shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off,
|
||||
lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off,
|
||||
@@ -158,37 +162,26 @@ namespace WaveHarmonic.Crest
|
||||
{
|
||||
s_UpdateMeshBoundsMarker.Begin(this);
|
||||
|
||||
var bounds = _Mesh.bounds;
|
||||
var bounds = _LocalBounds;
|
||||
|
||||
if (WaterBody.WaterBodies.Count > 0)
|
||||
bounds = ComputeBounds(_Transform, bounds);
|
||||
|
||||
_UnexpandedBoundsXZ = new(0, 0, bounds.size.x, bounds.size.z)
|
||||
{
|
||||
_UnexpandedBoundsXZ = ComputeBoundsXZ(_Transform, bounds);
|
||||
}
|
||||
center = bounds.center.XZ(),
|
||||
};
|
||||
|
||||
bounds = ExpandBoundsForDisplacements(_Transform, bounds);
|
||||
|
||||
Rend.localBounds = bounds;
|
||||
Rend.bounds = bounds;
|
||||
|
||||
s_UpdateMeshBoundsMarker.End();
|
||||
}
|
||||
|
||||
public static Rect ComputeBoundsXZ(Transform transform, Bounds bounds)
|
||||
{
|
||||
// Since chunks are axis-aligned it is safe to rotate the bounds.
|
||||
var center = transform.rotation * bounds.center * transform.lossyScale.x + transform.position;
|
||||
var size = transform.rotation * bounds.size * transform.lossyScale.x;
|
||||
// Rotation can make size negative.
|
||||
return new(0, 0, Mathf.Abs(size.x), Mathf.Abs(size.z))
|
||||
{
|
||||
center = center.XZ(),
|
||||
};
|
||||
}
|
||||
|
||||
// Used by the water mask system if we need to render the water mask in situations
|
||||
// where the water itself doesn't need to be rendered or has otherwise been disabled
|
||||
internal void Bind()
|
||||
{
|
||||
_MaterialPropertyBlock = _Water.Surface._PerCascadeMPB.Current[_LodIndex];
|
||||
_MaterialPropertyBlock = _Water.Surface.PerCascadeMPB[_LodIndex];
|
||||
new PropertyWrapperMPB(_MaterialPropertyBlock).SetSHCoefficients(_Transform.position);
|
||||
Rend.SetPropertyBlock(_MaterialPropertyBlock);
|
||||
|
||||
_WaterDataHasBeenBound = true;
|
||||
@@ -197,6 +190,7 @@ namespace WaveHarmonic.Crest
|
||||
void OnDestroy()
|
||||
{
|
||||
Helpers.Destroy(_Mesh);
|
||||
_Mesh = null;
|
||||
}
|
||||
|
||||
// Called when visible to a camera
|
||||
@@ -207,6 +201,14 @@ namespace WaveHarmonic.Crest
|
||||
return;
|
||||
}
|
||||
|
||||
#if CREST_DEBUG
|
||||
if (_Water._Debug._VisualizeData)
|
||||
{
|
||||
Rend.sharedMaterial = _Water.Surface.VisualizeDataMaterial;
|
||||
MaterialOverridden = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!MaterialOverridden && Rend.sharedMaterial != _Water.Surface.Material)
|
||||
{
|
||||
Rend.sharedMaterial = _Water.Surface.Material;
|
||||
@@ -217,13 +219,28 @@ namespace WaveHarmonic.Crest
|
||||
{
|
||||
Bind();
|
||||
}
|
||||
|
||||
if (_DrawRenderBounds)
|
||||
{
|
||||
Rend.bounds.DebugDraw();
|
||||
}
|
||||
}
|
||||
|
||||
public Bounds ComputeBounds(Transform transform, Bounds bounds)
|
||||
{
|
||||
var extents = bounds.extents;
|
||||
var center = bounds.center;
|
||||
|
||||
// Apply transform. Rotation already done.
|
||||
var scale = _LocalScale * _Water.Scale;
|
||||
extents.x *= scale;
|
||||
extents.z *= scale;
|
||||
center.x *= scale;
|
||||
center.z *= scale;
|
||||
center += transform.position;
|
||||
|
||||
bounds.center = center;
|
||||
bounds.extents = extents;
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
// this is called every frame because the bounds are given in world space and depend on the transform scale, which
|
||||
// can change depending on view altitude
|
||||
public Bounds ExpandBoundsForDisplacements(Transform transform, Bounds bounds)
|
||||
@@ -231,99 +248,53 @@ namespace WaveHarmonic.Crest
|
||||
var extents = bounds.extents;
|
||||
var center = bounds.center;
|
||||
|
||||
var scale = transform.lossyScale;
|
||||
var rotation = transform.rotation;
|
||||
|
||||
var boundsPadding = _Water.MaximumHorizontalDisplacement;
|
||||
var expandXZ = boundsPadding / scale.x;
|
||||
var boundsY = _Water.MaximumVerticalDisplacement;
|
||||
var rect = _UnexpandedBoundsXZ;
|
||||
|
||||
// Extend the kinematic bounds slightly to give room for dynamic waves.
|
||||
if (_Water._DynamicWavesLod.Enabled)
|
||||
{
|
||||
boundsY += 5f;
|
||||
}
|
||||
|
||||
// Extend bounds by global waves.
|
||||
extents.x += expandXZ;
|
||||
extents.y += boundsY;
|
||||
extents.z += expandXZ;
|
||||
|
||||
// Get XZ bounds. Doing this manually bypasses updating render bounds call.
|
||||
Rect rect;
|
||||
{
|
||||
var p1 = transform.position;
|
||||
var p2 = rotation * new Vector3(center.x, 0f, center.z);
|
||||
var s1 = scale;
|
||||
var s2 = rotation * (extents.XNZ(0f) * 2f);
|
||||
|
||||
rect = new(0, 0, Mathf.Abs(s1.x * s2.x), Mathf.Abs(s1.z * s2.z))
|
||||
{
|
||||
center = new(p1.x + p2.x, p1.z + p2.z)
|
||||
};
|
||||
var settings = _Water.DynamicWavesLod.Settings;
|
||||
extents.x += settings._HorizontalDisplace;
|
||||
extents.y += settings._VerticalDisplacementCullingContributions;
|
||||
extents.z += settings._HorizontalDisplace;
|
||||
}
|
||||
|
||||
// Extend bounds by local waves.
|
||||
{
|
||||
var totalHorizontal = 0f;
|
||||
var totalVertical = 0f;
|
||||
var horizontal = 0f;
|
||||
var vertical = 0f;
|
||||
|
||||
foreach (var reporter in DisplacementReporters)
|
||||
foreach (var (key, input) in AnimatedWavesLod.s_Inputs)
|
||||
{
|
||||
var horizontal = 0f;
|
||||
var vertical = 0f;
|
||||
if (reporter.ReportDisplacement(ref rect, ref horizontal, ref vertical))
|
||||
{
|
||||
totalHorizontal += horizontal;
|
||||
totalVertical += vertical;
|
||||
}
|
||||
input.DisplacementReporter?.ReportDisplacement(_Water, ref rect, ref horizontal, ref vertical);
|
||||
}
|
||||
|
||||
boundsPadding = totalHorizontal;
|
||||
expandXZ = boundsPadding / scale.x;
|
||||
boundsY = totalVertical;
|
||||
|
||||
extents.x += expandXZ;
|
||||
extents.y += boundsY;
|
||||
extents.z += expandXZ;
|
||||
extents.x += horizontal;
|
||||
extents.y += vertical;
|
||||
extents.z += horizontal;
|
||||
}
|
||||
|
||||
// Expand and offset bounds by height.
|
||||
{
|
||||
var minimumWaterLevelBounds = 0f;
|
||||
var maximumWaterLevelBounds = 0f;
|
||||
var minimum = 0f;
|
||||
var maximum = 0f;
|
||||
|
||||
foreach (var reporter in HeightReporters)
|
||||
foreach (var (key, input) in LevelLod.s_Inputs)
|
||||
{
|
||||
var minimum = 0f;
|
||||
var maximum = 0f;
|
||||
if (reporter.ReportHeight(ref rect, ref minimum, ref maximum))
|
||||
{
|
||||
minimumWaterLevelBounds = Mathf.Max(minimumWaterLevelBounds, Mathf.Abs(Mathf.Min(minimum, _Water.SeaLevel) - _Water.SeaLevel));
|
||||
maximumWaterLevelBounds = Mathf.Max(maximumWaterLevelBounds, Mathf.Abs(Mathf.Max(maximum, _Water.SeaLevel) - _Water.SeaLevel));
|
||||
}
|
||||
input.HeightReporter?.ReportHeight(_Water, ref rect, ref minimum, ref maximum);
|
||||
}
|
||||
|
||||
minimumWaterLevelBounds *= 0.5f;
|
||||
maximumWaterLevelBounds *= 0.5f;
|
||||
extents.y += Mathf.Abs((minimum - maximum) * 0.5f);
|
||||
|
||||
boundsY = minimumWaterLevelBounds + maximumWaterLevelBounds;
|
||||
extents.y += boundsY;
|
||||
bounds.extents = extents;
|
||||
|
||||
var offset = maximumWaterLevelBounds - minimumWaterLevelBounds;
|
||||
var offset = Mathf.Lerp(minimum, maximum, 0.5f);
|
||||
center.y += offset;
|
||||
bounds.center = center;
|
||||
}
|
||||
|
||||
return bounds;
|
||||
}
|
||||
// Get XZ bounds. Doing this manually bypasses updating render bounds call.
|
||||
bounds.center = center;
|
||||
bounds.extents = extents;
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
||||
static void InitStatics()
|
||||
{
|
||||
HeightReporters.Clear();
|
||||
DisplacementReporters.Clear();
|
||||
return bounds;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user