158 lines
5.8 KiB
C#
158 lines
5.8 KiB
C#
// Crest Water System
|
|
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
|
|
|
#if d_UnityHDRP
|
|
|
|
using UnityEngine;
|
|
using UnityEngine.Experimental.Rendering;
|
|
using UnityEngine.Rendering;
|
|
using UnityEngine.Rendering.HighDefinition;
|
|
|
|
namespace WaveHarmonic.Crest
|
|
{
|
|
sealed class UnderwaterEffectPassHDRP : CustomPass
|
|
{
|
|
const string k_Name = "Underwater Effect";
|
|
|
|
static UnderwaterRenderer s_Renderer;
|
|
static UnderwaterEffectPass s_UnderwaterEffectPass;
|
|
internal static UnderwaterEffectPassHDRP s_Instance;
|
|
static CopyDepthBufferPassHDRP s_CopyDepthBufferPassHDRP;
|
|
|
|
static ShaderTagId[] s_ForwardShaderTags;
|
|
|
|
public static void Enable(UnderwaterRenderer renderer)
|
|
{
|
|
var gameObject = CustomPassHelpers.CreateOrUpdate
|
|
(
|
|
parent: renderer._Water.Container.transform,
|
|
k_Name,
|
|
hide: !renderer._Water._Debug._ShowHiddenObjects
|
|
);
|
|
|
|
CustomPassHelpers.CreateOrUpdate
|
|
(
|
|
gameObject,
|
|
ref s_CopyDepthBufferPassHDRP,
|
|
UnderwaterRenderer.k_DrawVolume,
|
|
CustomPassInjectionPoint.AfterOpaqueDepthAndNormal
|
|
);
|
|
|
|
var isBeforeTransparentPass = renderer.RenderBeforeTransparency;
|
|
|
|
CustomPassHelpers.CreateOrUpdate
|
|
(
|
|
gameObject,
|
|
ref s_Instance,
|
|
UnderwaterRenderer.k_DrawVolume,
|
|
GetInjectionPoint(isBeforeTransparentPass),
|
|
// Higher number (priority) means execute earlier. Volume executes first.
|
|
priority: 1
|
|
);
|
|
|
|
s_Renderer = renderer;
|
|
s_UnderwaterEffectPass = new(renderer);
|
|
}
|
|
|
|
public static void Disable()
|
|
{
|
|
// It should be safe to rely on this reference for this reference to fail.
|
|
if (s_Instance != null && s_Instance._GameObject != null)
|
|
{
|
|
// Will also trigger Cleanup below.
|
|
s_Instance._GameObject.SetActive(false);
|
|
}
|
|
}
|
|
|
|
static CustomPassInjectionPoint GetInjectionPoint(bool isBeforeTransparentPass)
|
|
{
|
|
return isBeforeTransparentPass
|
|
? CustomPassInjectionPoint.BeforeTransparent
|
|
: CustomPassInjectionPoint.BeforePostProcess;
|
|
}
|
|
|
|
internal void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera)
|
|
{
|
|
s_CopyDepthBufferPassHDRP.enabled = s_Renderer.UseStencilBuffer;
|
|
s_Instance._Volume.injectionPoint = GetInjectionPoint(s_Renderer.RenderBeforeTransparency);
|
|
}
|
|
|
|
protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)
|
|
{
|
|
var asset = GraphicsSettings.currentRenderPipeline as HDRenderPipelineAsset;
|
|
|
|
// Developers have a choice with the color buffer format. There is also a custom buffer buffer format but
|
|
// that is not relevant here. This will not cover the format change when scene filtering as Setup/Cleanup is
|
|
// not executed for this change.
|
|
s_UnderwaterEffectPass.Allocate((GraphicsFormat)asset.currentPlatformRenderPipelineSettings.colorBufferFormat);
|
|
|
|
// Taken from:
|
|
// https://github.com/Unity-Technologies/Graphics/blob/778ddac6207ade1689999b95380cd835b0669f2d/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/DrawRenderersCustomPass.cs#L136-L142
|
|
s_ForwardShaderTags ??= new[]
|
|
{
|
|
HDShaderPassNames.s_ForwardName, // HD Lit shader
|
|
HDShaderPassNames.s_ForwardOnlyName, // HD Unlit shader
|
|
HDShaderPassNames.s_SRPDefaultUnlitName, // Cross SRP Unlit shader
|
|
};
|
|
}
|
|
|
|
protected override void Cleanup()
|
|
{
|
|
s_UnderwaterEffectPass?.Release();
|
|
}
|
|
|
|
protected override void Execute(CustomPassContext context)
|
|
{
|
|
var camera = context.hdCamera.camera;
|
|
|
|
if (!s_Renderer.ShouldRender(camera, UnderwaterRenderer.Pass.Effect))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Allocate here in case user changes options and we skipped allocation in Setup.
|
|
s_UnderwaterEffectPass.Allocate(context.cameraColorBuffer.rt.graphicsFormat);
|
|
|
|
// Create a separate stencil buffer context by using a depth buffer copy if needed.
|
|
var depthBuffer = s_Renderer.UseStencilBuffer
|
|
? s_CopyDepthBufferPassHDRP._DepthBufferCopy
|
|
: context.cameraDepthBuffer;
|
|
|
|
s_UnderwaterEffectPass.Execute(camera, context.cmd, context.cameraColorBuffer, depthBuffer, context.propertyBlock);
|
|
}
|
|
}
|
|
|
|
sealed class CopyDepthBufferPassHDRP : CustomPass
|
|
{
|
|
public RTHandle _DepthBufferCopy;
|
|
|
|
protected override void Execute(CustomPassContext context)
|
|
{
|
|
// Multiple cameras could have different settings.
|
|
RenderPipelineCompatibilityHelper.ReAllocateIfNeeded
|
|
(
|
|
ref _DepthBufferCopy,
|
|
context.cameraDepthBuffer.rt.descriptor,
|
|
FilterMode.Point,
|
|
name: "_Crest_UnderwaterCopiedDepthBuffer"
|
|
);
|
|
|
|
var buffer = context.cmd;
|
|
|
|
// NOTE: previously we cleared the target depth first due to artifacts.
|
|
buffer.CopyTexture(context.cameraDepthBuffer.rt, _DepthBufferCopy.rt);
|
|
|
|
// Clear the stencil component just in case.
|
|
CoreUtils.SetRenderTarget(buffer, BuiltinRenderTextureType.None, _DepthBufferCopy, ClearFlag.Stencil);
|
|
}
|
|
|
|
protected override void Cleanup()
|
|
{
|
|
_DepthBufferCopy?.Release();
|
|
_DepthBufferCopy = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif // d_UnityHDRP
|