388 lines
17 KiB
C#
388 lines
17 KiB
C#
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
|
||
}
|
||
}
|