升级水插件

This commit is contained in:
2026-01-08 22:30:55 +08:00
parent febff82d24
commit ca68084264
415 changed files with 18138 additions and 7134 deletions

View File

@@ -3,7 +3,6 @@
#if d_UnityURP
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
@@ -13,12 +12,11 @@ namespace WaveHarmonic.Crest
{
sealed partial class UnderwaterEffectPassURP : ScriptableRenderPass
{
const string k_Name = "Crest Underwater Effect";
const string k_Name = "Crest.DrawWater/Volume";
UnderwaterRenderer _Renderer;
static UnderwaterEffectPassURP s_Instance;
RenderObjectsWithoutFogPass _ApplyFogToTransparentObjects;
internal static UnderwaterEffectPassURP s_Instance;
UnderwaterEffectPass _UnderwaterEffectPass;
CopyDepthBufferPassURP _CopyDepthBufferPass;
@@ -27,7 +25,6 @@ namespace WaveHarmonic.Crest
public UnderwaterEffectPassURP()
{
renderPassEvent = RenderPassEvent.AfterRenderingTransparents;
ConfigureInput(ScriptableRenderPassInput.Color | ScriptableRenderPassInput.Depth);
}
@@ -38,18 +35,14 @@ namespace WaveHarmonic.Crest
s_Instance = new();
s_Instance._Renderer = renderer;
s_Instance._CopyDepthBufferPass = new(RenderPassEvent.AfterRenderingOpaques);
s_Instance._ApplyFogToTransparentObjects = new();
}
RenderPipelineManager.beginCameraRendering -= s_Instance.EnqueuePass;
RenderPipelineManager.beginCameraRendering += s_Instance.EnqueuePass;
RenderPipelineManager.activeRenderPipelineTypeChanged -= Disable;
RenderPipelineManager.activeRenderPipelineTypeChanged += Disable;
}
public static void Disable()
{
if (s_Instance != null) RenderPipelineManager.beginCameraRendering -= s_Instance.EnqueuePass;
RenderPipelineManager.activeRenderPipelineTypeChanged -= Disable;
s_Instance?._UnderwaterEffectPass?.Release();
@@ -57,13 +50,15 @@ namespace WaveHarmonic.Crest
s_Instance = null;
}
void EnqueuePass(ScriptableRenderContext context, Camera camera)
internal void EnqueuePass(ScriptableRenderContext context, Camera camera)
{
if (!_Renderer.ShouldRender(camera, UnderwaterRenderer.Pass.Effect))
{
return;
}
s_Instance.renderPassEvent = _Renderer.RenderBeforeTransparency ? WaterRenderer.k_WaterRenderPassEvent : RenderPassEvent.AfterRenderingTransparents;
var renderer = camera.GetUniversalAdditionalCameraData().scriptableRenderer;
#if UNITY_EDITOR
@@ -80,25 +75,40 @@ namespace WaveHarmonic.Crest
_UnderwaterEffectPass ??= new(_Renderer);
renderer.EnqueuePass(s_Instance);
if (_Renderer.EnableShaderAPI)
{
renderer.EnqueuePass(_ApplyFogToTransparentObjects);
}
}
#if UNITY_6000_0_OR_NEWER
void OnSetup(CommandBuffer buffer, PassData data)
bool _ErrorMissingColorTarget;
void OnSetup(CommandBuffer buffer, RenderGraphHelper.PassData data)
{
_ColorBuffer = data.colorTargetHandle.Texture;
_DepthBuffer = data.depthTargetHandle.Texture;
// Unity bug
if (_ColorBuffer?.rt == null)
{
if (!_ErrorMissingColorTarget)
{
Debug.LogError($"Crest: Your current URP setup has a Unity bug which prevents underwater from rendering on this camera ({data.cameraData.camera.name}). It is too complicated for us to advise which combination of settings are the issue (sorry), but they will be on either the URP asset or renderer file.");
_ErrorMissingColorTarget = true;
}
return;
}
// TODO: renderingData.cameraData.cameraTargetDescriptor?
_UnderwaterEffectPass.ReAllocate(_ColorBuffer.rt.descriptor);
}
void Execute(ScriptableRenderContext context, CommandBuffer buffer, PassData data)
void Execute(ScriptableRenderContext context, CommandBuffer buffer, RenderGraphHelper.PassData data)
{
// Unity bug
if (_ColorBuffer?.rt == null)
{
return;
}
if (_Renderer.UseStencilBuffer)
{
_DepthBuffer = _CopyDepthBufferPass._DepthBufferCopy;
@@ -131,120 +141,13 @@ namespace WaveHarmonic.Crest
CommandBufferPool.Release(buffer);
}
#endif
// Renders transparent objects after the underwater effect. Using the correct
// shader, the above water portion of the object is rendered normally (in the
// transparent pass), and the below water portion is rendered here with underwater
// applied.
sealed partial class RenderObjectsWithoutFogPass : ScriptableRenderPass
{
FilteringSettings _FilteringSettings;
static readonly List<ShaderTagId> s_ShaderTagIdList = new()
{
new("SRPDefaultUnlit"),
new("UniversalForward"),
new("UniversalForwardOnly"),
new("LightweightForward"),
};
public RenderObjectsWithoutFogPass()
{
renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
_FilteringSettings = new(RenderQueueRange.transparent, 0);
}
#if UNITY_6000_0_OR_NEWER
void Execute(ScriptableRenderContext context, CommandBuffer buffer, PassData renderingData)
#else
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
#endif
{
_FilteringSettings.layerMask = s_Instance._Renderer._TransparentObjectLayers;
#if !UNITY_6000_0_OR_NEWER
var buffer = CommandBufferPool.Get("Crest Underwater Objects");
#endif
// Disable Unity's fog keywords as there is no option to ignore fog for the Shader Graph.
if (RenderSettings.fog)
{
switch (RenderSettings.fogMode)
{
case FogMode.Exponential:
buffer.DisableShaderKeyword("FOG_EXP");
break;
case FogMode.Linear:
buffer.DisableShaderKeyword("FOG_LINEAR");
break;
case FogMode.ExponentialSquared:
buffer.DisableShaderKeyword("FOG_EXP2");
break;
}
}
buffer.EnableShaderKeyword(UnderwaterRenderer.k_KeywordUnderwaterObjects);
// If we want anything to apply to DrawRenderers, it has to be executed before:
// https://docs.unity3d.com/ScriptReference/Rendering.ScriptableRenderContext.DrawRenderers.html
context.ExecuteCommandBuffer(buffer);
buffer.Clear();
#if UNITY_6000_0_OR_NEWER
var drawingSettings = RenderingUtils.CreateDrawingSettings
(
s_ShaderTagIdList,
renderingData.renderingData,
renderingData.cameraData,
renderingData.lightData,
SortingCriteria.CommonTransparent
);
var parameters = new RendererListParams(renderingData.cullResults, drawingSettings, _FilteringSettings);
var list = context.CreateRendererList(ref parameters);
buffer.DrawRendererList(list);
#else
var drawingSettings = CreateDrawingSettings
(
s_ShaderTagIdList,
ref renderingData,
SortingCriteria.CommonTransparent
);
context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref _FilteringSettings);
#endif
// Revert fog keywords.
if (RenderSettings.fog)
{
switch (RenderSettings.fogMode)
{
case FogMode.Exponential:
buffer.EnableShaderKeyword("FOG_EXP");
break;
case FogMode.Linear:
buffer.EnableShaderKeyword("FOG_LINEAR");
break;
case FogMode.ExponentialSquared:
buffer.EnableShaderKeyword("FOG_EXP2");
break;
}
}
buffer.DisableShaderKeyword(UnderwaterRenderer.k_KeywordUnderwaterObjects);
#if !UNITY_6000_0_OR_NEWER
context.ExecuteCommandBuffer(buffer);
CommandBufferPool.Release(buffer);
#endif
}
}
}
// Copies the depth buffer to avoid conflicts when using the stencil buffer.
sealed partial class CopyDepthBufferPassURP : ScriptableRenderPass
{
const string k_Name = "Crest Copy Depth Buffer";
RTHandle _ColorBuffer;
RTHandle _DepthBuffer;
public RTHandle _DepthBufferCopy;
@@ -264,9 +167,11 @@ namespace WaveHarmonic.Crest
descriptor.bindMS = descriptor.msaaSamples > 1;
#if UNITY_6000_0_OR_NEWER
RenderingUtils.ReAllocateHandleIfNeeded(ref _DepthBufferCopy, descriptor, FilterMode.Point, name: "Crest Copied Depth Buffer");
_ColorBuffer = data.colorTargetHandle;
_DepthBuffer = data.depthTargetHandle;
#else
RenderingUtils.ReAllocateIfNeeded(ref _DepthBufferCopy, descriptor, FilterMode.Point, name: "Crest Copied Depth Buffer");
_ColorBuffer = data.cameraData.renderer.cameraColorTargetHandle;
_DepthBuffer = data.cameraData.renderer.cameraDepthTargetHandle;
#endif
}
@@ -277,19 +182,26 @@ namespace WaveHarmonic.Crest
public override void Execute(ScriptableRenderContext context, ref RenderingData data)
#endif
{
// Just in case.
if (_ColorBuffer == null || _DepthBuffer == null)
{
return;
}
#if !UNITY_6000_0_OR_NEWER
var buffer = CommandBufferPool.Get(k_Name);
#endif
// Must clear even though we are overwriting or there will be strange artifacts on new writes.
// This could be a Unity bug and may be worth reporting.
buffer.SetRenderTarget(BuiltinRenderTextureType.None, _DepthBufferCopy);
buffer.ClearRenderTarget(RTClearFlags.Depth, Color.black, 1, 0);
// NOTE: previously we cleared the target depth first due to artifacts.
buffer.CopyTexture(_DepthBuffer.rt, _DepthBufferCopy.rt);
// Clear the stencil component just in case.
buffer.ClearRenderTarget(RTClearFlags.Stencil, Color.black, 1, 0);
// Previously we passed BuiltinRenderTextureType.None for color but this made the
// scene disappear in the scene view on DX11 only.
CoreUtils.SetRenderTarget(buffer, _ColorBuffer, _DepthBufferCopy, ClearFlag.Stencil);
// Required for Unity 6+.
CoreUtils.SetRenderTarget(buffer, _ColorBuffer, _DepthBuffer);
#if !UNITY_6000_0_OR_NEWER
context.ExecuteCommandBuffer(buffer);