213 lines
8.1 KiB
C#
213 lines
8.1 KiB
C#
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
#if URP
|
|
using UnityEngine.Rendering.Universal;
|
|
|
|
#if UNITY_2022_1_OR_NEWER
|
|
using RenderTarget = UnityEngine.Rendering.RTHandle;
|
|
#else
|
|
using RenderTarget = UnityEngine.Rendering.RenderTargetIdentifier;
|
|
#endif
|
|
|
|
namespace StylizedWater2.UnderwaterRendering
|
|
{
|
|
public class RenderPass : ScriptableRenderPass
|
|
{
|
|
protected UnderwaterResources resources;
|
|
protected UnderwaterRenderFeature.Settings settings;
|
|
protected UnderwaterRenderFeature renderFeature;
|
|
|
|
protected RTHandle cameraColorSource;
|
|
protected RenderTarget cameraColorTarget;
|
|
|
|
protected readonly int sourceTexID = Shader.PropertyToID("_SourceTex");
|
|
|
|
//In the interest of consistency, some one at Unity thinks its a good idea to change parameter names
|
|
#if UNITY_2022_2_OR_NEWER
|
|
private const string BlitInputTexName = "_BlitTexture";
|
|
#else
|
|
private const string BlitInputTexName = "_SourceTex";
|
|
#endif
|
|
|
|
protected readonly int blitInputID = Shader.PropertyToID(BlitInputTexName);
|
|
|
|
protected Material Material;
|
|
private static Material _BlitMaterial;
|
|
private static Material BlitMaterial
|
|
{
|
|
get
|
|
{
|
|
if (!_BlitMaterial)
|
|
{
|
|
_BlitMaterial = CoreUtils.CreateEngineMaterial(Shader.Find("Hidden/Universal Render Pipeline/Blit"));
|
|
}
|
|
|
|
return _BlitMaterial;
|
|
}
|
|
}
|
|
|
|
private bool xrRendering;
|
|
|
|
private const string CopyProfilerTag = "Copy camera color";
|
|
private static readonly ProfilingSampler m_CopyProfilingSampler = new ProfilingSampler(CopyProfilerTag);
|
|
|
|
protected void Initialize(UnderwaterRenderFeature renderFeature, Shader shader)
|
|
{
|
|
this.renderFeature = renderFeature;
|
|
this.settings = renderFeature.settings;
|
|
this.resources = renderFeature.resources;
|
|
|
|
if(shader) Material = CoreUtils.CreateEngineMaterial(shader);
|
|
}
|
|
|
|
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
|
|
{
|
|
if (RenderPass.RTHandleNeedsReAlloc(cameraColorSource, cameraTextureDescriptor, "_SourceTex"))
|
|
{
|
|
//Note: function does a null check, needed for the first allocation
|
|
if(cameraColorSource != null) RTHandles.Release(cameraColorSource);
|
|
cameraColorSource = RTHandles.Alloc(cameraTextureDescriptor.width, cameraTextureDescriptor.height, cameraTextureDescriptor.volumeDepth, DepthBits.None, cameraTextureDescriptor.graphicsFormat, FilterMode.Point, TextureWrapMode.Clamp, cameraTextureDescriptor.dimension, name: "_SourceTex");
|
|
}
|
|
|
|
cmd.SetGlobalTexture(sourceTexID, cameraColorSource);
|
|
|
|
//At this point, the target is unbound. At least for the first frame
|
|
//ConfigureTarget(cameraColorTarget);
|
|
}
|
|
|
|
public static bool RTHandleNeedsReAlloc(RTHandle handle, in RenderTextureDescriptor descriptor, in string name)
|
|
{
|
|
//#if UNITY_2022_1_OR_NEWER
|
|
//Using this results in a depth texture constantly being allocated?!
|
|
//return RenderingUtils.ReAllocateIfNeeded(ref handle, descriptor);
|
|
//#else
|
|
//If not ever being allocated
|
|
if (handle == null || handle.rt == null)
|
|
{
|
|
#if SWS_DEV
|
|
//Debug.Log($"RTHandle {name} null, allocating");
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
//Resolution changes
|
|
if ((handle.rt.width != descriptor.width || handle.rt.height != descriptor.height))
|
|
{
|
|
#if SWS_DEV
|
|
//Debug.Log($"{name} resolution changed. Source:{descriptor.width}x{descriptor.height}. Current:{handle.rt.width}x{handle.rt.height}");
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
//In case XR is initialized at some point
|
|
if (handle.rt.descriptor.dimension != descriptor.dimension)
|
|
{
|
|
#if SWS_DEV
|
|
//Debug.Log($"{name} dimensions changed. Source:{descriptor.dimension}. Current:{handle.rt.descriptor.dimension}");
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private void CheckVR(ref RenderingData renderingData)
|
|
{
|
|
#if UNITY_2020_1_OR_NEWER && ENABLE_VR && ENABLE_XR_MODULE
|
|
xrRendering = renderingData.cameraData.xrRendering;
|
|
#else
|
|
xrRendering = false;
|
|
#endif
|
|
}
|
|
|
|
public virtual void Setup(UnderwaterRenderFeature.Settings settings, ScriptableRenderer renderer)
|
|
{
|
|
#if !UNITY_2020_2_OR_NEWER //URP 10+
|
|
//otherwise fetched in Execute function, no longer allowed from a ScriptableRenderFeature setup function (target may be not be created yet, or was disposed)
|
|
this.cameraColorTarget = renderer.cameraColorTarget;
|
|
#endif
|
|
}
|
|
|
|
protected void GetColorTarget(ref RenderingData renderingData)
|
|
{
|
|
#if UNITY_2020_2_OR_NEWER //URP 10+
|
|
//Color target can now only be fetched inside a ScriptableRenderPass
|
|
|
|
#if UNITY_2022_1_OR_NEWER
|
|
this.cameraColorTarget = renderingData.cameraData.renderer.cameraColorTargetHandle;
|
|
#else
|
|
this.cameraColorTarget = renderingData.cameraData.renderer.cameraColorTarget;
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
private static readonly int _BlitScaleBiasRt = Shader.PropertyToID("_BlitScaleBiasRt");
|
|
private static readonly int _BlitScaleBias = Shader.PropertyToID("_BlitScaleBias");
|
|
private static readonly Vector4 ScaleBias = new Vector4(1, 1, 0, 0);
|
|
|
|
protected void BlitToCamera(CommandBuffer cmd, ref RenderingData renderingData)
|
|
{
|
|
//Required for vertex shader
|
|
cmd.SetGlobalVector(_BlitScaleBiasRt, ScaleBias);
|
|
cmd.SetGlobalVector(_BlitScaleBias, ScaleBias);
|
|
|
|
//Copy camera color source
|
|
//Seemingly always needed when rendering before transparent materials, otherwise breaks the depth buffer
|
|
//+ Always needed for VR. Swap buffer fails to work there.
|
|
using (new ProfilingScope(cmd, m_CopyProfilingSampler))
|
|
{
|
|
//Color copy
|
|
cmd.SetGlobalTexture(blitInputID, cameraColorTarget);
|
|
cmd.SetRenderTarget(cameraColorSource, 0, CubemapFace.Unknown, -1);
|
|
|
|
if (xrRendering)
|
|
{
|
|
cmd.DrawProcedural(Matrix4x4.identity, BlitMaterial, 0, MeshTopology.Quads, 4, 1, null);
|
|
}
|
|
else
|
|
{
|
|
Blit(cmd, cameraColorTarget, cameraColorSource, BlitMaterial, 0);
|
|
}
|
|
}
|
|
|
|
//Blit to camera color target
|
|
cmd.SetGlobalTexture(sourceTexID, cameraColorSource);
|
|
cmd.SetRenderTarget(cameraColorTarget, 0, CubemapFace.Unknown, -1);
|
|
|
|
if (xrRendering)
|
|
{
|
|
cmd.DrawProcedural(Matrix4x4.identity, Material, 0, MeshTopology.Quads, 4, 1, null);
|
|
}
|
|
else
|
|
{
|
|
Blit(cmd, cameraColorSource, cameraColorTarget, Material, 0);
|
|
}
|
|
}
|
|
|
|
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
|
{
|
|
GetColorTarget(ref renderingData);
|
|
|
|
CheckVR(ref renderingData);
|
|
}
|
|
|
|
#if UNITY_2020_1_OR_NEWER //URP 9+
|
|
public override void OnCameraCleanup(CommandBuffer cmd)
|
|
#else
|
|
public override void FrameCleanup(CommandBuffer cmd)
|
|
#endif
|
|
{
|
|
Cleanup(cmd);
|
|
}
|
|
|
|
public virtual void Dispose()
|
|
{
|
|
RTHandles.Release(cameraColorSource);
|
|
}
|
|
|
|
protected virtual void Cleanup(CommandBuffer cmd)
|
|
{
|
|
}
|
|
}
|
|
}
|
|
#endif |