Files
ichni_Official/Packages/NB_FX/NBPostProcessing/Runtime/DisturbanceMaskRenderPass.cs

388 lines
17 KiB
C#
Raw Normal View History

2026-07-17 17:46:16 -04:00
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using System.Collections.Generic;
#if UNIVERSAL_RP_17_0_OR_NEWER
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering.RenderGraphModule;
using UnityEngine.Rendering.RenderGraphModule.Util;
#endif
namespace NBShader
{
public class DisturbanceMaskRenderPass : ScriptableRenderPass
{
private ProfilingSampler _profilingSampler;
#if UNIVERSAL_RP_13_1_2_OR_NEWER
private RTHandle _DisturbanceMaskRTHandle;
private RTHandle _cameraDepthRTHandle;
private RTHandle _DownRT;
#else
private static readonly int _DisturbanceMaskRTID = Shader.PropertyToID("_DisturbanceMaskRT");
private static readonly int _DownRTID = Shader.PropertyToID("_DisturbanceMaskTex");
private RenderTargetIdentifier _DisturbanceMaskRTHandle = new RenderTargetIdentifier (_DisturbanceMaskRTID);
private RenderTargetIdentifier _cameraDepthRTHandle;
private RenderTargetIdentifier _DownRT = new RenderTargetIdentifier (_DownRTID);
#endif
private Material tempMat;
private readonly Downsampling _downSampling;
private Material _renderMaskMat ;
// public LayerMask _DisturbanceMaskLayer = 1 << 25;
private FilteringSettings _Filtering;
private static readonly int CameraTexture = Shader.PropertyToID("_CameraTexture");
private static readonly int SampleOffset = Shader.PropertyToID("_SampleOffset");
private static readonly int DisturbanceMaskTex = Shader.PropertyToID("_DisturbanceMaskTex");
private readonly Color _clearDisturbanceMaskColor = new Color(0f, 0f, 0f, 1f);
private readonly List<ShaderTagId> _shaderTag = new List<ShaderTagId>()
{
// new ShaderTagId("UniversalForward"),
// new ShaderTagId("SRPDefaultUnlit"),
// new ShaderTagId("UniversalForwardOnly")
new ShaderTagId("NBDeferredDistortPass")
};
public DisturbanceMaskRenderPass(ProfilingSampler profilingSampler,Material DisturbanceMaskMat, Downsampling downSampling)
{
_profilingSampler = profilingSampler;
_renderMaskMat = DisturbanceMaskMat;
_downSampling = downSampling;
}
#if UNIVERSAL_RP_17_0_OR_NEWER
private class RenderGraphMaskPassData
{
public RendererListHandle rendererListHandle;
}
private class GlobalTexturePassData
{
public TextureHandle texture;
public int nameID;
}
private static bool IsSupportedCamera(CameraType cameraType)
{
return cameraType == CameraType.Game || cameraType == CameraType.SceneView;
}
private static void SetGlobalTextureAfterPass(RenderGraph renderGraph, TextureHandle texture, int nameID, string passName)
{
using (var builder = renderGraph.AddRasterRenderPass<GlobalTexturePassData>(passName, out var passData))
{
passData.texture = texture;
passData.nameID = nameID;
builder.UseTexture(texture, AccessFlags.Read);
builder.AllowPassCulling(false);
builder.AllowGlobalStateModification(true);
builder.SetGlobalTextureAfterPass(texture, nameID);
builder.SetRenderFunc(static (GlobalTexturePassData data, RasterGraphContext context) =>
{
});
}
}
private void ApplyDownsampling(ref TextureDesc descriptor)
{
switch (_downSampling)
{
case Downsampling._2xBilinear:
descriptor.width = Mathf.Max(1, descriptor.width / 2);
descriptor.height = Mathf.Max(1, descriptor.height / 2);
break;
case Downsampling._4xBilinear:
case Downsampling._4xBox:
descriptor.width = Mathf.Max(1, descriptor.width / 4);
descriptor.height = Mathf.Max(1, descriptor.height / 4);
break;
}
}
private int GetDownsamplePassIndex()
{
return _downSampling == Downsampling._4xBox ? 1 : 0;
}
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
{
UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
if (!IsSupportedCamera(cameraData.cameraType) || _renderMaskMat == null)
return;
UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
if (!resourceData.activeColorTexture.IsValid())
return;
UniversalRenderingData universalRenderingData = frameData.Get<UniversalRenderingData>();
UniversalLightData lightData = frameData.Get<UniversalLightData>();
TextureDesc maskDescriptor = renderGraph.GetTextureDesc(resourceData.activeColorTexture);
maskDescriptor.name = "DisturbanceMaskRT";
maskDescriptor.colorFormat = GraphicsFormat.R16G16_SFloat;
maskDescriptor.depthBufferBits = DepthBits.None;
maskDescriptor.clearBuffer = true;
maskDescriptor.clearColor = _clearDisturbanceMaskColor;
TextureHandle maskTexture = renderGraph.CreateTexture(maskDescriptor);
using (var builder = renderGraph.AddRasterRenderPass<RenderGraphMaskPassData>("DisturbanceRender", out var passData))
{
DrawingSettings drawingSettings = RenderingUtils.CreateDrawingSettings(
_shaderTag,
universalRenderingData,
cameraData,
lightData,
cameraData.defaultOpaqueSortFlags);
FilteringSettings filteringSettings = new FilteringSettings(RenderQueueRange.all);
RendererListParams rendererListParameters = new RendererListParams(
universalRenderingData.cullResults,
drawingSettings,
filteringSettings);
passData.rendererListHandle = renderGraph.CreateRendererList(rendererListParameters);
builder.UseRendererList(passData.rendererListHandle);
builder.SetRenderAttachment(maskTexture, 0, AccessFlags.ReadWrite);
if (resourceData.activeDepthTexture.IsValid())
builder.SetRenderAttachmentDepth(resourceData.activeDepthTexture, AccessFlags.ReadWrite);
if (_downSampling == Downsampling.None)
builder.SetGlobalTextureAfterPass(maskTexture, DisturbanceMaskTex);
builder.SetRenderFunc(static (RenderGraphMaskPassData data, RasterGraphContext context) =>
{
context.cmd.DrawRendererList(data.rendererListHandle);
});
}
if (_downSampling == Downsampling.None)
return;
TextureDesc downsampleDescriptor = maskDescriptor;
downsampleDescriptor.name = "MaskDownCopyRT";
downsampleDescriptor.clearBuffer = false;
ApplyDownsampling(ref downsampleDescriptor);
TextureHandle downsampleTexture = renderGraph.CreateTexture(downsampleDescriptor);
if (_downSampling == Downsampling._4xBox)
_renderMaskMat.SetFloat(SampleOffset, 2);
RenderGraphUtils.BlitMaterialParameters blitParameters =
new RenderGraphUtils.BlitMaterialParameters(maskTexture, downsampleTexture, _renderMaskMat, GetDownsamplePassIndex());
blitParameters.sourceTexturePropertyID = CameraTexture;
renderGraph.AddBlitPass(blitParameters, "DisturbanceMaskDownsample");
SetGlobalTextureAfterPass(renderGraph, downsampleTexture, DisturbanceMaskTex, "Set Disturbance Mask");
}
#endif
#if UNIVERSAL_RP_13_1_2_OR_NEWER
public void SetUp ( RTHandle cameraRTHandle )
{
#if !UNITY_6000_3_OR_NEWER || (URP_COMPATIBILITY_MODE && !UNITY_6000_4_OR_NEWER)
#pragma warning disable CS0618
RenderTextureDescriptor descrip = cameraRTHandle.rt.descriptor;
descrip.colorFormat = RenderTextureFormat.RGHalf;
descrip.depthBufferBits = 0;
RenderingUtils.ReAllocateIfNeeded(ref _DisturbanceMaskRTHandle, descrip, name: "DisturbanceMaskRT");
switch (_downSampling)
{
case Downsampling._2xBilinear:
descrip.width /= 2;
descrip.height /= 2;
break;
case Downsampling._4xBilinear:
descrip.width /= 4;
descrip.height /= 4;
break;
case Downsampling._4xBox:
descrip.width /= 4;
descrip.height /= 4;
break;
}
if (_downSampling != Downsampling.None)
RenderingUtils.ReAllocateIfNeeded(ref _DownRT, descrip, name:"MaskDownCopyRT");
#pragma warning restore CS0618
#endif
}
#else
#if !UNITY_6000_3_OR_NEWER || (URP_COMPATIBILITY_MODE && !UNITY_6000_4_OR_NEWER)
//在AddPass之前触发
public void SetUpDisturbanceMask(RenderTextureDescriptor descrip ,CommandBuffer cmd)
{
descrip.colorFormat = RenderTextureFormat.RGHalf;
descrip.depthBufferBits = 0;
cmd.GetTemporaryRT(_DisturbanceMaskRTID, descrip,FilterMode.Bilinear);
switch (_downSampling)
{
case Downsampling._2xBilinear:
descrip.width /= 2;
descrip.height /= 2;
break;
case Downsampling._4xBilinear:
descrip.width /= 4;
descrip.height /= 4;
break;
case Downsampling._4xBox:
descrip.width /= 4;
descrip.height /= 4;
break;
}
if (_downSampling != Downsampling.None)
cmd.GetTemporaryRT(_DownRTID, descrip,FilterMode.Bilinear);
}
#endif
#endif
#if !UNITY_6000_3_OR_NEWER || (URP_COMPATIBILITY_MODE && !UNITY_6000_4_OR_NEWER)
#pragma warning disable CS0618, CS0672
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
_Filtering = new FilteringSettings(RenderQueueRange.all);
#if UNIVERSAL_RP_13_1_2_OR_NEWER
_cameraDepthRTHandle = renderingData.cameraData.renderer.cameraDepthTargetHandle;
#else
_cameraDepthRTHandle = renderingData.cameraData.renderer.cameraDepthTarget;
SetUpDisturbanceMask(renderingData.cameraData.cameraTargetDescriptor,cmd);
#endif
}
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
{
#if UNIVERSAL_RP_13_1_2_OR_NEWER
ConfigureTarget(_DisturbanceMaskRTHandle, _cameraDepthRTHandle);
#else
ConfigureTarget(_DisturbanceMaskRTID, _cameraDepthRTHandle);
#endif
//将RT清空
ConfigureClear(ClearFlag.Color, _clearDisturbanceMaskColor);
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
if (!(renderingData.cameraData.cameraType == CameraType.Game || renderingData.cameraData.cameraType == CameraType.SceneView))
return;
if (!_renderMaskMat)
{
return;
}
var DisturbanceDraw = CreateDrawingSettings(_shaderTag, ref renderingData, renderingData.cameraData.defaultOpaqueSortFlags);
CommandBuffer cmd = CommandBufferPool.Get();
using (new ProfilingScope(cmd, _profilingSampler))
{
context.DrawRenderers(renderingData.cullResults, ref DisturbanceDraw, ref _Filtering);
#if UNIVERSAL_RP_13_1_2_OR_NEWER
if (_downSampling == Downsampling.None)
{
cmd.SetGlobalTexture(DisturbanceMaskTex, _DisturbanceMaskRTHandle);
}
else
{
_renderMaskMat.SetTexture(CameraTexture, _DisturbanceMaskRTHandle);
cmd.SetRenderTarget((RenderTargetIdentifier)_DownRT);
switch (_downSampling)
{
case Downsampling._2xBilinear:
Blitter.BlitTexture(cmd, _DisturbanceMaskRTHandle, Vector2.one, _renderMaskMat, 0);
break;
case Downsampling._4xBilinear:
Blitter.BlitTexture(cmd, _DisturbanceMaskRTHandle, Vector2.one, _renderMaskMat, 0);
break;
case Downsampling._4xBox:
_renderMaskMat.SetFloat(SampleOffset, 2);
Blitter.BlitTexture(cmd, _DisturbanceMaskRTHandle, Vector2.one, _renderMaskMat, 1);
break;
}
cmd.SetGlobalTexture(DisturbanceMaskTex, _DownRT);
}
#else
if (_downSampling == Downsampling.None)
{
cmd.SetGlobalTexture(DisturbanceMaskTex, _DisturbanceMaskRTHandle);
}
else
{
// cmd.SetGlobalTexture(_DisturbanceMaskRTID, _DisturbanceMaskRTHandle);
//Bug:在非播放状态时_DisturbanceMaskRTID在这里会经常丢失。造成画面闪烁。但是只要有一个DistortObject在Scene中并LockInspector就不会闪烁非常奇怪。
cmd.SetGlobalTexture(CameraTexture, _DisturbanceMaskRTHandle);
// _renderMaskMat.SetTexture(CameraTexture, Shader.GetGlobalTexture(_DisturbanceMaskRTID));
cmd.SetRenderTarget(_DownRT);
switch (_downSampling)
{
case Downsampling._2xBilinear:
// Blitter.BlitTexture(cmd, _DisturbanceMaskRTHandle, _DownRT, _renderMaskMat, 0);
// cmd.Blit(_DisturbanceMaskRTHandle, _DownRT, _renderMaskMat, 0);
// cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, _renderMaskMat, 0, 2);
Blit(cmd, _DisturbanceMaskRTHandle,_DownRT,_renderMaskMat,0);
break;
case Downsampling._4xBilinear:
// Blitter.BlitTexture(cmd, _DisturbanceMaskRTHandle, _DownRT, _renderMaskMat, 0);
// cmd.Blit(_DisturbanceMaskRTHandle, _DownRT, _renderMaskMat, 0);
// cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, _renderMaskMat, 0, 2);
Blit(cmd, _DisturbanceMaskRTHandle,_DownRT,_renderMaskMat,0);
break;
case Downsampling._4xBox:
_renderMaskMat.SetFloat(SampleOffset, 2);
// Blitter.BlitTexture(cmd, _DisturbanceMaskRTHandle, _DownRT, _renderMaskMat, 1);
// cmd.Blit(_DisturbanceMaskRTHandle, _DownRT, _renderMaskMat, 1);
// cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, _renderMaskMat, 0, 3);
Blit(cmd, _DisturbanceMaskRTHandle,_DownRT,_renderMaskMat,1);
break;
}
cmd.SetGlobalTexture(DisturbanceMaskTex, _DownRT);
}
#endif
}
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
#pragma warning restore CS0618, CS0672
#endif
#if !UNIVERSAL_RP_13_1_2_OR_NEWER && (!UNITY_6000_3_OR_NEWER || (URP_COMPATIBILITY_MODE && !UNITY_6000_4_OR_NEWER))
// Cleanup any allocated resources that were created during the execution of this render pass.
public override void OnCameraCleanup(CommandBuffer cmd)
{
cmd.ReleaseTemporaryRT(_DisturbanceMaskRTID);
if (_downSampling != Downsampling.None)
cmd.ReleaseTemporaryRT(_DownRTID);
}
//JustForSimple
public void Dispose()
{
}
#else
public void Dispose()
{
_DisturbanceMaskRTHandle?.Release();
_DownRT?.Release();
}
#endif
}
}