升级6.4.升级水,升级天气

This commit is contained in:
2026-04-05 00:26:54 +08:00
parent 63bc9b5536
commit 5f7cbfb713
635 changed files with 34718 additions and 22567 deletions

View File

@@ -2,10 +2,15 @@
// Copyright © 2024 Wave Harmonic. All rights reserved.
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
using WaveHarmonic.Crest.Internal;
using WaveHarmonic.Crest.Utility;
#if !UNITY_6000_0_OR_NEWER
using GraphicsFormatUsage = UnityEngine.Experimental.Rendering.FormatUsage;
#endif
namespace WaveHarmonic.Crest
{
/// <summary>
@@ -33,7 +38,9 @@ namespace WaveHarmonic.Crest
[Tooltip("Populates the DepthProbe in Start.")]
OnStart = 0,
// EveryFrame = 1,
/// <inheritdoc cref="Generated.DepthProbeRefreshMode.EveryFrame"/>
[Tooltip("Populates the DepthProbe every frame.")]
EveryFrame = 1,
/// <inheritdoc cref="Generated.DepthProbeRefreshMode.ViaScripting"/>
[Tooltip("Requires manual updating via DepthProbe.Populate.")]
@@ -77,8 +84,13 @@ namespace WaveHarmonic.Crest
[SerializeField]
internal DepthProbeMode _Type = DepthProbeMode.RealTime;
[Tooltip("Controls how the probe is refreshed in the Player.\n\nCall Populate() if scripting.")]
[@Predicated(nameof(_Type), inverted: true, nameof(DepthProbeMode.RealTime), hide: true)]
[Tooltip("Where the Depth Probe is placed.\n\nThe default performs the best.")]
[@GenerateAPI]
[@DecoratedField, SerializeField]
Placement _Placement;
[Tooltip("Controls how the probe is refreshed in the Player.\n\nCall Populate() if scripting.\n\nWhen Placement is not set to Fixed, EveryFrame is still applicable, but the others are not (update only happens on position change).")]
[@Show(nameof(_Type), nameof(DepthProbeMode.RealTime))]
[@GenerateAPI]
[@DecoratedField, SerializeField]
internal DepthProbeRefreshMode _RefreshMode = DepthProbeRefreshMode.OnStart;
@@ -87,26 +99,26 @@ namespace WaveHarmonic.Crest
[@Heading("Capture")]
[Tooltip("The layers to render into the probe.")]
[@Predicated(nameof(_Type), inverted: true, nameof(DepthProbeMode.RealTime))]
[@Enable(nameof(_Type), nameof(DepthProbeMode.RealTime))]
[@GenerateAPI(Setter.Dirty)]
[@DecoratedField, SerializeField]
internal LayerMask _Layers = 1; // Default
[Tooltip("The resolution of the probe.\n\nLower will be more efficient.")]
[@Predicated(nameof(_Type), inverted: true, nameof(DepthProbeMode.RealTime))]
[@Enable(nameof(_Type), nameof(DepthProbeMode.RealTime))]
[@GenerateAPI(Setter.Dirty)]
[@DecoratedField, SerializeField]
internal int _Resolution = 512;
[Tooltip("The far and near plane of the depth probe camera respectively, relative to the transform.\n\nDepth is captured top-down and orthographically. The gizmo will visualize this range as the bottom box.")]
[@Predicated(nameof(_Type), inverted: true, nameof(DepthProbeMode.RealTime))]
[@Enable(nameof(_Type), nameof(DepthProbeMode.RealTime))]
[@Range(-100f, 100f, Range.Clamp.None)]
[@GenerateAPI(Setter.Dirty)]
[SerializeField]
internal Vector2 _CaptureRange = new(-1000f, 1000f);
[Tooltip("Fills holes left by the maximum of the capture range.\n\nSetting the maximum capture range lower than the highest point of geometry can be useful for eliminating depth artifacts from overhangs, but the side effect is there will be a hole in the depth data where geometry is clipped by the near plane. This will only capture where the holes are to fill them in. This height is relative to the maximum capture range. Set to zero to skip.")]
[@Predicated(nameof(_Type), inverted: true, nameof(DepthProbeMode.RealTime))]
[@Enable(nameof(_Type), nameof(DepthProbeMode.RealTime))]
[@Range(0f, 100f, Range.Clamp.Minimum)]
[UnityEngine.Serialization.FormerlySerializedAs("_MaximumHeight")]
[@GenerateAPI(Setter.Dirty)]
@@ -115,14 +127,14 @@ namespace WaveHarmonic.Crest
[@Label("Enable Back-Face Inclusion")]
[Tooltip("Increase coverage by testing mesh back faces within the Fill Holes area.\n\nUses the back-faces to include meshes where the front-face is within the Fill Holes area and the back-face is within the capture area. An example would be an upright cylinder not over a hole but was not captured due to the top being clipped by the near plane.")]
[@Predicated(nameof(_Type), inverted: true, nameof(DepthProbeMode.RealTime))]
[@Predicated(nameof(_FillHolesCaptureHeight), inverted: false, 0f)]
[@Enable(nameof(_Type), nameof(DepthProbeMode.RealTime))]
[@Disable(nameof(_FillHolesCaptureHeight), 0f)]
[@GenerateAPI(Setter.Dirty)]
[@DecoratedField, SerializeField]
bool _EnableBackFaceInclusion = true;
[Tooltip("Overrides global quality settings.")]
[@Predicated(nameof(_Type), inverted: true, nameof(DepthProbeMode.RealTime))]
[@Enable(nameof(_Type), nameof(DepthProbeMode.RealTime))]
[GenerateAPI(Setter.None)]
[@DecoratedField, SerializeField]
QualitySettingsOverride _QualitySettingsOverride = new()
@@ -139,7 +151,7 @@ namespace WaveHarmonic.Crest
[Tooltip("Baked probe.\n\nCan only bake in edit mode.")]
[@Disabled]
[@Predicated(nameof(_Type), inverted: true, nameof(DepthProbeMode.Baked), hide: true)]
[@Show(nameof(_Type), nameof(DepthProbeMode.Baked))]
[@GenerateAPI]
[@DecoratedField, SerializeField]
#pragma warning disable 649
@@ -151,7 +163,7 @@ namespace WaveHarmonic.Crest
[@Label("Generate")]
[Tooltip("Generate a signed distance field for the shoreline.")]
[@Predicated(nameof(_Type), inverted: true, nameof(DepthProbeMode.RealTime))]
[@Enable(nameof(_Type), nameof(DepthProbeMode.RealTime))]
[@GenerateAPI(Setter.Dirty)]
[@DecoratedField, SerializeField]
internal bool _GenerateSignedDistanceField = true;
@@ -159,8 +171,8 @@ namespace WaveHarmonic.Crest
// Additional rounds of JFA, over the standard log2(resolution), can help reduce
// innacuracies from JFA, see paper for details.
[Tooltip("How many additional Jump Flood rounds to use.\n\nThe standard number of rounds is log2(resolution). Additional rounds can reduce innaccuracies.")]
[@Predicated(nameof(_Type), inverted: true, nameof(DepthProbeMode.RealTime))]
[@Predicated(nameof(_GenerateSignedDistanceField))]
[@Enable(nameof(_Type), nameof(DepthProbeMode.RealTime))]
[@Enable(nameof(_GenerateSignedDistanceField))]
[@GenerateAPI(Setter.Dirty)]
[@DecoratedField, SerializeField]
int _AdditionalJumpFloodRounds = 7;
@@ -174,11 +186,6 @@ namespace WaveHarmonic.Crest
[System.Serializable]
internal sealed class DebugFields
{
[Tooltip("Will render into the probe every frame. Intended for debugging, will generate garbage.")]
[@Predicated(nameof(_Type), inverted: true, nameof(DepthProbeMode.RealTime))]
[@DecoratedField, SerializeField]
public bool _ForceAlwaysUpdateDebug;
[Tooltip("Shows hidden objects like the camera which renders into the probe.")]
[@DecoratedField, SerializeField]
public bool _ShowHiddenObjects;
@@ -342,6 +349,11 @@ namespace WaveHarmonic.Crest
if (transform.hasChanged)
{
_RecalculateBounds = true;
if (_Placement == Placement.Transform)
{
UpdatePosition(water, transform);
}
}
}
@@ -351,6 +363,14 @@ namespace WaveHarmonic.Crest
transform.hasChanged = false;
}
void OnBeforeBuildCommandBuffer(WaterRenderer water, Camera camera)
{
if (_Placement == Placement.Viewpoint)
{
UpdatePosition(water, camera.transform);
}
}
internal bool Outdated => _CurrentStateHash != _RenderedStateHash;
bool IsTextureOutdated(RenderTexture texture, bool target)
@@ -358,16 +378,19 @@ namespace WaveHarmonic.Crest
return texture != null &&
texture.width != _Resolution ||
texture.height != _Resolution ||
texture.format != (target ? RenderTextureFormat.Depth : FinalFormat);
texture.graphicsFormat != (target ? SystemInfo.GetGraphicsFormat(DefaultFormat.DepthStencil) : FinalFormat);
}
RenderTextureFormat FinalFormat => _GenerateSignedDistanceField ? RenderTextureFormat.RGFloat : RenderTextureFormat.RFloat;
GraphicsFormat FinalFormat => _GenerateSignedDistanceField
? Helpers.GetCompatibleTextureFormat(GraphicsFormat.R32G32_SFloat, Helpers.s_DataGraphicsFormatUsage, "Depth Probe", randomWrite: true)
: GraphicsFormat.R32_SFloat;
void MakeRT(RenderTexture texture, bool target)
{
var format = target ? RenderTextureFormat.Depth : FinalFormat;
var format = target ? SystemInfo.GetGraphicsFormat(DefaultFormat.DepthStencil) : FinalFormat;
var descriptor = texture.descriptor;
descriptor.colorFormat = format;
descriptor.graphicsFormat = target ? GraphicsFormat.None : format;
descriptor.depthStencilFormat = target ? format : GraphicsFormat.None;
descriptor.width = descriptor.height = _Resolution;
descriptor.depthBufferBits = target ? 24 : 0;
descriptor.useMipMap = false;
@@ -375,7 +398,11 @@ namespace WaveHarmonic.Crest
descriptor.enableRandomWrite = !target;
texture.descriptor = descriptor;
texture.Create();
Debug.Assert(SystemInfo.SupportsRenderTextureFormat(format), "Crest: The graphics device does not support the render texture format " + format.ToString());
if (!target)
{
Debug.Assert(SystemInfo.IsFormatSupported(format, GraphicsFormatUsage.Sample), "Crest: The graphics device does not support the render texture format " + format.ToString());
}
}
bool InitObjects()
@@ -704,7 +731,7 @@ namespace WaveHarmonic.Crest
var descriptor = new RenderTextureDescriptor(_Resolution, _Resolution)
{
autoGenerateMips = false,
colorFormat = RenderTextureFormat.RGHalf,
graphicsFormat = Helpers.GetCompatibleTextureFormat(GraphicsFormat.R16G16_SFloat, Helpers.s_DataGraphicsFormatUsage, "Depth Probe SDF", randomWrite: true),
useMipMap = false,
enableRandomWrite = true,
depthBufferBits = 0,
@@ -838,6 +865,9 @@ namespace WaveHarmonic.Crest
ILodInput.Attach(_Input, DepthLod.s_Inputs);
HashState(ref _CurrentStateHash);
WaterRenderer.s_OnBeforeBuildCommandBuffer -= OnBeforeBuildCommandBuffer;
WaterRenderer.s_OnBeforeBuildCommandBuffer += OnBeforeBuildCommandBuffer;
#if CREST_DEBUG
if (_Debug._ShowSimulationDataInScene)
{
@@ -852,6 +882,8 @@ namespace WaveHarmonic.Crest
base.OnDisable();
ILodInput.Detach(_Input, DepthLod.s_Inputs);
WaterRenderer.s_OnBeforeBuildCommandBuffer -= OnBeforeBuildCommandBuffer;
#if CREST_DEBUG
if (_Debug._ShowSimulationDataInScene)
{
@@ -926,6 +958,29 @@ namespace WaveHarmonic.Crest
}
}
sealed partial class DepthProbe
{
Vector3 _PreviousPosition;
void UpdatePosition(WaterRenderer water, Transform target)
{
var position = target.position.XNZ(water.transform.position.y);
var texelSize = Scale / _Resolution;
position.x = Mathf.Round(position.x / texelSize.x) * texelSize.x;
position.z = Mathf.Round(position.z / texelSize.y) * texelSize.y;
if ((_Placement == Placement.Viewpoint && !water.IsSingleViewpointMode) || _RefreshMode == DepthProbeRefreshMode.EveryFrame || _PreviousPosition != position)
{
Managed = true;
OverridePosition = true;
Position = position;
Scale = new(transform.lossyScale.x, transform.lossyScale.z);
Populate();
_PreviousPosition = position;
}
}
}
sealed partial class DepthProbe
{
// Hash is used to notify whether the probe is outdated in the UI.
@@ -974,7 +1029,7 @@ namespace WaveHarmonic.Crest
void Update()
{
if (_Debug._ForceAlwaysUpdateDebug && _Type != DepthProbeMode.Baked)
if (_RefreshMode == DepthProbeRefreshMode.EveryFrame && _Placement == Placement.Fixed && _Type != DepthProbeMode.Baked)
{
Populate();
}
@@ -987,30 +1042,21 @@ namespace WaveHarmonic.Crest
#endif
}
partial class DepthProbe : ISerializationCallbackReceiver
partial class DepthProbe
{
[SerializeField, HideInInspector]
#pragma warning disable 414
int _Version = 1;
#pragma warning restore 414
private protected override int Version => Mathf.Max(base.Version, 1);
/// <inheritdoc/>
void ISerializationCallbackReceiver.OnAfterDeserialize()
private protected override void OnMigrate()
{
base.OnMigrate();
// Version 1 (2024.06.04)
// - Added new capture options replacing Maximum Height's behaviour.
if (_Version < 1)
{
_CaptureRange.y = _FillHolesCaptureHeight;
_FillHolesCaptureHeight = 0f;
_Version = 1;
}
}
/// <inheritdoc/>
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
}
}