升级水插件
This commit is contained in:
@@ -1,8 +1,13 @@
|
||||
// Crest Water System
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
#if d_UnityURP
|
||||
|
||||
#if !UNITY_6000_3_OR_NEWER
|
||||
#define URP_COMPATIBILITY_MODE
|
||||
#endif
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
@@ -12,98 +17,26 @@ namespace WaveHarmonic.Crest
|
||||
// Universal Render Pipeline
|
||||
partial class WaterRenderer
|
||||
{
|
||||
sealed class ConfigureUniversalRenderer : ScriptableRenderPass
|
||||
internal const RenderPassEvent k_WaterRenderPassEvent = RenderPassEvent.BeforeRenderingTransparents;
|
||||
|
||||
internal sealed class CopyTargetsRenderPass : ScriptableRenderPass
|
||||
{
|
||||
readonly WaterRenderer _Water;
|
||||
public static ConfigureUniversalRenderer Instance { get; set; }
|
||||
|
||||
public ConfigureUniversalRenderer(WaterRenderer water)
|
||||
{
|
||||
_Water = water;
|
||||
renderPassEvent = RenderPassEvent.BeforeRenderingTransparents;
|
||||
ConfigureInput(ScriptableRenderPassInput.Color | ScriptableRenderPassInput.Depth);
|
||||
}
|
||||
|
||||
public static void Enable(WaterRenderer water)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var data = water.Viewer != null ? water.Viewer.GetUniversalAdditionalCameraData() : null;
|
||||
|
||||
// Type is internal.
|
||||
if (data != null && data.scriptableRenderer.GetType().Name == "Renderer2D")
|
||||
{
|
||||
UnityEditor.EditorUtility.DisplayDialog
|
||||
(
|
||||
"Crest Error!",
|
||||
"The project has been detected as a URP 2D project. Crest only supports 3D projects. " +
|
||||
"You may see errors from Crest in the console, and other issues.",
|
||||
"Ok"
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
Instance = new ConfigureUniversalRenderer(water);
|
||||
RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering;
|
||||
RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering;
|
||||
}
|
||||
|
||||
public static void Disable()
|
||||
{
|
||||
RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering;
|
||||
}
|
||||
|
||||
static void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera)
|
||||
{
|
||||
// May cause assertions/exceptions for reflection camera.
|
||||
if (camera.cameraType == CameraType.Reflection) return;
|
||||
|
||||
if (!Helpers.MaskIncludesLayer(camera.cullingMask, Instance._Water.Layer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Could also check RenderType. Which is better?
|
||||
if (!Instance._Water.Material.IsKeywordEnabled("_SURFACE_TYPE_TRANSPARENT"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
camera.GetUniversalAdditionalCameraData().scriptableRenderer.EnqueuePass(Instance);
|
||||
}
|
||||
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
sealed class PassData { }
|
||||
|
||||
public override void RecordRenderGraph(UnityEngine.Rendering.RenderGraphModule.RenderGraph graph, ContextContainer frame)
|
||||
{
|
||||
using (var builder = graph.AddUnsafePass<PassData>("Crest Register Color/Depth Requirements.", out var data))
|
||||
{
|
||||
builder.AllowPassCulling(false);
|
||||
builder.SetRenderFunc<PassData>((data, context) => { });
|
||||
}
|
||||
}
|
||||
|
||||
[System.Obsolete]
|
||||
#endif
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
// Blank
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class UniversalCopyWaterSurfaceDepth : ScriptableRenderPass
|
||||
{
|
||||
readonly WaterRenderer _Water;
|
||||
public static UniversalCopyWaterSurfaceDepth Instance { get; set; }
|
||||
public static CopyTargetsRenderPass Instance { get; set; }
|
||||
|
||||
readonly UnityEngine.Rendering.Universal.Internal.CopyDepthPass _CopyDepthPass;
|
||||
readonly Shader _CopyDepthShader;
|
||||
readonly Material _CopyDepthMaterial;
|
||||
|
||||
public UniversalCopyWaterSurfaceDepth(WaterRenderer water)
|
||||
static readonly System.Reflection.FieldInfo s_OpaqueColor = typeof(UniversalRenderer).GetField("m_OpaqueColor", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
static readonly System.Reflection.FieldInfo s_ActiveRenderPassQueue = typeof(ScriptableRenderer).GetField("m_ActiveRenderPassQueue", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
readonly UnityEngine.Rendering.Universal.Internal.CopyColorPass _CopyColorPass;
|
||||
readonly Material _CopyColorMaterial;
|
||||
readonly Material _SampleColorMaterial;
|
||||
|
||||
public CopyTargetsRenderPass(WaterRenderer water)
|
||||
{
|
||||
_Water = water;
|
||||
renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
|
||||
|
||||
_CopyDepthShader = Shader.Find("Hidden/Universal Render Pipeline/CopyDepth");
|
||||
#if !UNITY_6000_0_OR_NEWER
|
||||
@@ -112,7 +45,7 @@ namespace WaveHarmonic.Crest
|
||||
|
||||
_CopyDepthPass = new
|
||||
(
|
||||
RenderPassEvent.BeforeRenderingPostProcessing,
|
||||
renderPassEvent,
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
_CopyDepthShader,
|
||||
#else
|
||||
@@ -122,52 +55,77 @@ namespace WaveHarmonic.Crest
|
||||
copyToDepth: true,
|
||||
copyResolvedDepth: RenderingUtils.MultisampleDepthResolveSupported(),
|
||||
shouldClear: false
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
, customPassName: "Crest.DrawWater"
|
||||
#endif
|
||||
);
|
||||
|
||||
_CopyColorMaterial = new(Shader.Find("Hidden/Universal/CoreBlit"));
|
||||
_SampleColorMaterial = new(Shader.Find("Hidden/Universal Render Pipeline/Sampling"));
|
||||
|
||||
_CopyColorPass = new
|
||||
(
|
||||
renderPassEvent,
|
||||
_SampleColorMaterial,
|
||||
_CopyColorMaterial
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
, customPassName: "Crest.DrawWater"
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
public static void Enable(WaterRenderer water)
|
||||
{
|
||||
Instance = new UniversalCopyWaterSurfaceDepth(water);
|
||||
RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering;
|
||||
RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering;
|
||||
Instance = new(water);
|
||||
}
|
||||
|
||||
public static void Disable()
|
||||
internal void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera)
|
||||
{
|
||||
RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering;
|
||||
}
|
||||
var water = _Water;
|
||||
|
||||
static void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera)
|
||||
{
|
||||
// May cause assertions/exceptions for reflection camera.
|
||||
if (camera.cameraType == CameraType.Reflection) return;
|
||||
|
||||
if (!Instance._Water._WriteToDepthTexture)
|
||||
if (!ShouldRender(camera, water.Surface.Layer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Helpers.MaskIncludesLayer(camera.cullingMask, Instance._Water.Layer))
|
||||
// Our reflections do not need them.
|
||||
if (camera == WaterReflections.CurrentCamera)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!water.WriteToColorTexture && !water.WriteToDepthTexture)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (water.Surface.Material == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Could also check RenderType. Which is better?
|
||||
if (!Instance._Water.Material.IsKeywordEnabled("_SURFACE_TYPE_TRANSPARENT"))
|
||||
if (!SurfaceRenderer.IsTransparent(water.Surface.Material))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
renderPassEvent = water.RenderBeforeTransparency ? RenderPassEvent.BeforeRenderingTransparents : RenderPassEvent.AfterRenderingTransparents;
|
||||
_CopyColorPass.renderPassEvent = renderPassEvent;
|
||||
_CopyDepthPass.renderPassEvent = renderPassEvent;
|
||||
|
||||
var renderer = camera.GetUniversalAdditionalCameraData().scriptableRenderer;
|
||||
// Needed for OnCameraSetup.
|
||||
renderer.EnqueuePass(Instance);
|
||||
renderer.EnqueuePass(this);
|
||||
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
// Copy depth pass does not support RG directly.
|
||||
if (GraphicsSettings.GetRenderPipelineSettings<RenderGraphSettings>().enableRenderCompatibilityMode)
|
||||
#endif
|
||||
{
|
||||
renderer.EnqueuePass(Instance._CopyDepthPass);
|
||||
if (water.WriteToColorTexture) renderer.EnqueuePass(_CopyColorPass);
|
||||
if (water.WriteToDepthTexture) renderer.EnqueuePass(_CopyDepthPass);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,9 +134,18 @@ namespace WaveHarmonic.Crest
|
||||
{
|
||||
var resources = frame.Get<UniversalResourceData>();
|
||||
var descriptor = resources.cameraDepthTexture.GetDescriptor(graph);
|
||||
// Whether we a writing to color or depth format.
|
||||
_CopyDepthPass.CopyToDepth = descriptor.colorFormat == UnityEngine.Experimental.Rendering.GraphicsFormat.None;
|
||||
_CopyDepthPass.Render(graph, frame, resources.cameraDepthTexture, resources.cameraDepth);
|
||||
|
||||
if (_Water.WriteToColorTexture)
|
||||
{
|
||||
_CopyColorPass.RenderToExistingTexture(graph, frame, resources.cameraOpaqueTexture, resources.cameraColor, UniversalRenderPipeline.asset.opaqueDownsampling);
|
||||
}
|
||||
|
||||
if (_Water.WriteToDepthTexture)
|
||||
{
|
||||
// Whether we a writing to color or depth format.
|
||||
_CopyDepthPass.CopyToDepth = descriptor.colorFormat == UnityEngine.Experimental.Rendering.GraphicsFormat.None;
|
||||
_CopyDepthPass.Render(graph, frame, resources.cameraDepthTexture, resources.cameraDepth);
|
||||
}
|
||||
}
|
||||
|
||||
[System.Obsolete]
|
||||
@@ -186,9 +153,20 @@ namespace WaveHarmonic.Crest
|
||||
public override void OnCameraSetup(CommandBuffer buffer, ref RenderingData data)
|
||||
{
|
||||
var renderer = (UniversalRenderer)data.cameraData.renderer;
|
||||
var opaqueColorHandle = s_OpaqueColor.GetValue(renderer) as RTHandle;
|
||||
|
||||
// Also check internal RT because it can be null on Vulkan for some reason.
|
||||
if (renderer.cameraColorTargetHandle?.rt != null && opaqueColorHandle?.rt != null)
|
||||
{
|
||||
_CopyColorPass.Setup(renderer.cameraColorTargetHandle, opaqueColorHandle, UniversalRenderPipeline.asset.opaqueDownsampling);
|
||||
}
|
||||
else
|
||||
{
|
||||
var queue = s_ActiveRenderPassQueue.GetValue(renderer) as List<ScriptableRenderPass>;
|
||||
queue.Remove(_CopyColorPass);
|
||||
}
|
||||
|
||||
|
||||
#if URP_COMPATIBILITY_MODE
|
||||
// Also check internal RT because it can be null on Vulkan for some reason.
|
||||
if (renderer.cameraDepthTargetHandle?.rt != null && renderer.m_DepthTexture?.rt != null)
|
||||
{
|
||||
@@ -197,6 +175,12 @@ namespace WaveHarmonic.Crest
|
||||
_CopyDepthPass.m_CopyResolvedDepth = false;
|
||||
_CopyDepthPass.Setup(renderer.cameraDepthTargetHandle, renderer.m_DepthTexture);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
var queue = s_ActiveRenderPassQueue.GetValue(renderer) as List<ScriptableRenderPass>;
|
||||
queue.Remove(_CopyDepthPass);
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
|
||||
Reference in New Issue
Block a user