升级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

@@ -13,11 +13,6 @@ namespace WaveHarmonic.Crest
[System.Serializable]
public sealed partial class UnderwaterRenderer
{
[SerializeField, HideInInspector]
#pragma warning disable 414
int _Version = 0;
#pragma warning restore 414
internal const float k_CullLimitMinimum = 0.000001f;
internal const float k_CullLimitMaximum = 0.01f;
@@ -62,7 +57,7 @@ namespace WaveHarmonic.Crest
#if d_UnitySRP
[@Label("Volume")]
[Tooltip("This profile will be weighed in the deeper underwater the camera goes.")]
[@Predicated(RenderPipeline.HighDefinition, hide: true)]
[@Show(RenderPipeline.HighDefinition)]
[@DecoratedField, SerializeField]
VolumeProfile _EnvironmentalLightingVolumeProfile = null;
@@ -72,23 +67,34 @@ namespace WaveHarmonic.Crest
[@Heading("Advanced")]
[Tooltip("Whether to execute for all cameras.\n\nIf disabled, then additionally ignore any camera that is not the view camera or our reflection camera. It will require managing culling masks of all cameras.")]
[Tooltip("Rules to exclude cameras from rendering underwater.\n\nThese are exclusion rules, so for all cameras, select Nothing. These rules are applied on top of the Layer rules.")]
[@DecoratedField]
[@GenerateAPI]
[@DecoratedField, SerializeField]
bool _AllCameras;
[SerializeField]
internal WaterCameraExclusion _CameraExclusions = WaterCameraExclusion.Hidden | WaterCameraExclusion.Reflection;
[Tooltip("Copying parameters each frame ensures underwater appearance stays consistent with the water surface.\n\nHas a small overhead so should be disabled if not needed.")]
[@GenerateAPI]
[@DecoratedField, SerializeField]
bool _CopyWaterMaterialParametersEachFrame = true;
#if !d_Crest_LegacyUnderwater
[@HideInInspector]
#endif
[Tooltip("Adjusts the far plane for horizon line calculation. Helps with horizon line issue.")]
[@Range(0f, 1f)]
[@GenerateAPI]
[SerializeField]
float _FarPlaneMultiplier = 0.68f;
[Tooltip("Whether to enable culling of water chunks when below water.")]
[@GenerateAPI]
[@InlineToggle]
[@SerializeField]
bool _EnableChunkCulling = true;
[Tooltip("Proportion of visibility below which the water surface will be culled when underwater.\n\nThe larger the number, the closer to the camera the water tiles will be culled.")]
[@Enable(nameof(_EnableChunkCulling))]
[@Range(k_CullLimitMinimum, k_CullLimitMaximum)]
[@GenerateAPI]
[SerializeField]
@@ -105,6 +111,9 @@ namespace WaveHarmonic.Crest
[SerializeField]
internal bool _VisualizeMask;
#if !d_Crest_LegacyUnderwater
[@HideInInspector]
#endif
[SerializeField]
internal bool _DisableMask;
@@ -114,6 +123,9 @@ namespace WaveHarmonic.Crest
[SerializeField]
internal bool _DisableHeightAboveWaterOptimization;
#if !d_Crest_LegacyUnderwater
[@HideInInspector]
#endif
[SerializeField]
internal bool _DisableArtifactCorrection;
@@ -132,7 +144,7 @@ namespace WaveHarmonic.Crest
internal bool RenderBeforeTransparency => false;
#else
// Legacy mask works except for negative volumes. Not officially supported.
internal bool UseLegacyMask => _AllCameras;
internal bool UseLegacyMask => false;
internal bool RenderBeforeTransparency => true;
#endif
@@ -142,21 +154,25 @@ namespace WaveHarmonic.Crest
// BUG: NonSerialized as Unity shows a serialization depth warning even though field is internal.
[System.NonSerialized]
internal Portals.PortalRenderer _Portals;
internal bool Portaled => _Portals.Active;
#else
bool Portaled => false;
#endif
bool Portaled => _Water._ActiveModules.HasFlag(WaterRenderer.ActiveModules.Portal);
int _MaterialLastUpdatedFrame = -1;
//
// Camera Loop Flags
//
internal bool UseStencilBuffer { get; set; }
internal enum Pass
{
Culling,
Mask,
Effect,
}
// Force the full-screen mask for Portals that need it.
internal bool RequiresFullScreenMask { get; set; }
// Requested the temporary color texture.
internal bool NeedsColorTexture { get; set; }
// These are the materials we actually use, overridable by Water Body.
Material _SurfaceMaterial;
@@ -253,14 +269,14 @@ namespace WaveHarmonic.Crest
_HorizonMaskMaterial = null;
}
internal bool ShouldRender(Camera camera, Pass pass)
internal bool ShouldRender(Camera camera)
{
if (!_Enabled || _Material == null)
{
return false;
}
// Clear state.
UseStencilBuffer = false;
NeedsColorTexture = false;
RequiresFullScreenMask = true;
if (_Water == null)
if (!_Enabled || _Material == null)
{
return false;
}
@@ -270,35 +286,7 @@ namespace WaveHarmonic.Crest
return false;
}
// Skip entire mask pass if possible.
if (pass == Pass.Mask && !_Water.Surface.Enabled)
{
return false;
}
#if UNITY_EDITOR
if (GL.wireframe)
{
return false;
}
// Skip camera if fog is disabled. Do not skip if mask pass and a portal or volume as we want it to still
// mask the water surface.
if ((pass != Pass.Mask || !Portaled) && !IsFogEnabledForEditorCamera(camera))
{
return false;
}
#endif
var isReflectionCamera = camera.cameraType == CameraType.Reflection;
// Mask or culling is not needed for reflections.
if (isReflectionCamera && pass != Pass.Effect)
{
return false;
}
if (_Debug._OnlyReflectionCameras && !isReflectionCamera)
if (_Debug._OnlyReflectionCameras && camera.cameraType != CameraType.Reflection)
{
return false;
}
@@ -307,12 +295,14 @@ namespace WaveHarmonic.Crest
// Otherwise, filtering depends on the camera's culling mask which is not always
// accessible like with the global "Reflection Probes Camera". But whether those
// cameras triggering camera events is a bug is TBD as it is intermittent.
if (!_AllCameras && camera != _Water.GetViewer(includeSceneCamera: false) && camera.cameraType != CameraType.SceneView && camera != WaterReflections.CurrentCamera)
if (camera != _Water.Reflections.ReflectionCamera && !WaterRenderer.ShouldRender(camera, _CameraExclusions))
{
return false;
}
if (!_Debug._DisableHeightAboveWaterOptimization && !Portaled)
var flags = _Water._ActiveModules;
if (!_Debug._DisableHeightAboveWaterOptimization && !Portaled && flags.HasFlag(WaterRenderer.ActiveModules.Surface))
{
_Water.UpdatePerCameraHeight(camera);
_ViewerWaterHeight = _Water._ViewerHeightAboveWaterPerCamera;
@@ -326,25 +316,17 @@ namespace WaveHarmonic.Crest
return true;
}
void RevertCulling()
{
foreach (var tile in _Water.Surface.Chunks)
{
if (tile.Rend == null || tile._Culled)
{
continue;
}
tile.Rend.enabled = true;
}
}
// Called by WaterRenderer. Camera must have water layer.
internal void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera)
{
OnBeginCameraRendering(camera);
#if UNITY_EDITOR
if (_VolumeMaterial == null)
{
return;
}
// Populated by this point.
if (_VolumeMaterial.shader != WaterResources.Instance.Shaders._UnderwaterEffect)
{
@@ -352,6 +334,7 @@ namespace WaveHarmonic.Crest
}
#endif
#pragma warning disable format
#if d_UnityURP
if (RenderPipelineHelper.IsUniversal)
{
@@ -371,28 +354,11 @@ namespace WaveHarmonic.Crest
{
OnBeforeLegacyRender(camera);
}
#pragma warning restore format
}
internal void OnBeginCameraRendering(Camera camera)
{
if (!ShouldRender(camera, Pass.Culling))
{
return;
}
// Only one camera supported due to LOD center dependency.
if (!UseLegacyMask && ShouldRender(camera, Pass.Mask) && camera == _Water.Viewer)
{
_Water.Surface.UpdateDisplacedSurfaceData(camera);
}
#if d_UnityHDRP
if (RenderPipelineHelper.IsHighDefinition)
{
_Water.UpdateHighDefinitionLighting(camera);
}
#endif
_SurfaceMaterial = _Water.Surface.AboveOrBelowSurfaceMaterial;
_VolumeMaterial = _Material;
@@ -466,9 +432,20 @@ namespace WaveHarmonic.Crest
UpdateEnvironmentalLighting(camera, extinction, _ViewerWaterHeight);
}
if (!_EnableChunkCulling)
{
return;
}
// Only relevant to cameras rendering the surface from here.
if (!_Water._ActiveModules.HasFlag(WaterRenderer.ActiveModules.Surface))
{
return;
}
// Redo culling. Culling is per camera. But chunks are shared.
if (Portaled || _ViewerWaterHeight > -5f)
{
RevertCulling();
return;
}
@@ -489,7 +466,6 @@ namespace WaveHarmonic.Crest
}
else
{
// Previous camera might have culled in underwater pass.
tile.Rend.enabled = true;
}
}
@@ -498,8 +474,6 @@ namespace WaveHarmonic.Crest
internal void OnEndCameraRendering(Camera camera)
{
RestoreEnvironmentalLighting();
RevertCulling();
_DoneMaskRead = false;
if (RenderPipelineHelper.IsLegacy)
{
@@ -507,6 +481,26 @@ namespace WaveHarmonic.Crest
}
}
internal void ExecuteHeightField(Camera camera)
{
if (UseLegacyMask)
{
return;
}
if (!RequiresFullScreenMask)
{
return;
}
if (!_Water._ActiveModules.HasFlag(WaterRenderer.ActiveModules.Surface))
{
return;
}
_Water.Surface.UpdateDisplacedSurfaceData(camera);
}
void SetEnabled(bool previous, bool current)
{
if (previous == current) return;
@@ -537,4 +531,16 @@ namespace WaveHarmonic.Crest
}
#endif
}
// Obsolete / Migration
partial class UnderwaterRenderer : Versioned
{
// No migration as default value for new control is far more effective than this toggle.
[System.Obsolete("Please use Camera Exclusion instead.")]
[Tooltip("Whether to execute for all cameras.\n\nIf disabled, then additionally ignore any camera that is not the view camera or our reflection camera. It will require managing culling masks of all cameras.")]
[@GenerateAPI]
[@DecoratedField, SerializeField]
[HideInInspector]
bool _AllCameras;
}
}