Files
Cielonos/Assets/OtherPlugins/Le Tai's Asset/TranslucentImage/Script/URP/Render Pass/TranslucentImageBlurRenderPass.cs
SoulliesOfficial f7af60351b 阶段性完成
2025-12-08 05:27:53 -05:00

188 lines
6.1 KiB
C#

#if UNITY_2022_3_OR_NEWER
#define HAS_DOUBLEBUFFER_BOTH
#endif
#if UNITY_2023_3_OR_NEWER
#define HAS_RENDERGRAPH
#endif
// ReSharper disable once RedundantUsingDirective
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.Scripting.APIUpdating;
namespace LeTai.Asset.TranslucentImage.UniversalRP
{
enum RendererType
{
Universal,
Renderer2D
}
[MovedFrom("LeTai.Asset.TranslucentImage.LWRP")]
public partial class TranslucentImageBlurRenderPass : ScriptableRenderPass
{
internal struct PassData
{
public IReadOnlyList<TranslucentImageSource> blurSources;
public IBlurAlgorithm blurAlgorithm;
public Rect camPixelRect;
public uint shouldUpdateBlurMask;
public int previewIndex;
public Material previewMaterial;
}
internal struct SRPassData
{
#if !HAS_DOUBLEBUFFER_BOTH
public RendererType rendererType;
public RenderTargetIdentifier cameraColorTarget;
public TranslucentImageBlurSource.RenderOrder renderOrder;
#endif
public bool canvasDisappearWorkaround;
}
public readonly struct PreviewExecutionData
{
public readonly TranslucentImageSource blurSource;
public readonly RenderTargetIdentifier previewTarget;
public readonly Material previewMaterial;
public PreviewExecutionData(
TranslucentImageSource blurSource,
RenderTargetIdentifier previewTarget,
Material previewMaterial
)
{
this.blurSource = blurSource;
this.previewTarget = previewTarget;
this.previewMaterial = previewMaterial;
}
}
private const string PROFILER_TAG = "Translucent Image Source";
readonly URPRendererInternal urpRendererInternal;
PassData currentPassData;
SRPassData currentSRPassData;
internal TranslucentImageBlurRenderPass(URPRendererInternal urpRendererInternal)
{
this.urpRendererInternal = urpRendererInternal;
RenderGraphInit();
#if UNITY_6000_0_OR_NEWER
requiresIntermediateTexture = true;
#endif
}
#if !HAS_DOUBLEBUFFER_BOTH
RenderTargetIdentifier GetAfterPostColor()
{
return urpRendererInternal.GetAfterPostColor();
}
#endif
internal void SetupSRP(SRPassData srPassData)
{
currentSRPassData = srPassData;
}
public void Dispose()
{
RenderGraphDispose();
}
internal void Setup(PassData passData)
{
currentPassData = passData;
#if !UNITY_6000_0_OR_NEWER
// Doesn't seem necessary after pretty comprehensive testing.
// Leaving it out avoids significant cost. Keeping it here in case any problem arises.
// ConfigureInput(ScriptableRenderPassInput.Color);
#endif
}
#if HAS_RENDERGRAPH
[Obsolete("This rendering path is for compatibility mode only (when Render Graph is disabled). Use Render Graph API instead.", false)]
#endif
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
var cmd = CommandBufferPool.Get(PROFILER_TAG);
RenderTargetIdentifier sourceTex;
#if !HAS_DOUBLEBUFFER_BOTH
var isPostProcessEnabled = renderingData.cameraData.postProcessEnabled;
void SetSource2DRenderer()
{
bool useAfterPostTex = isPostProcessEnabled;
useAfterPostTex &= currentSRPassData.renderOrder == TranslucentImageBlurSource.RenderOrder.AfterPostProcessing;
sourceTex = useAfterPostTex
? GetAfterPostColor()
: currentSRPassData.cameraColorTarget;
}
#endif
#if HAS_DOUBLEBUFFER_BOTH
sourceTex = urpRendererInternal.GetBackBuffer();
#else
if (currentSRPassData.rendererType == RendererType.Universal)
{
sourceTex = urpRendererInternal.GetBackBuffer();
}
else
{
SetSource2DRenderer();
}
#endif
bool shouldResetTarget = currentSRPassData.canvasDisappearWorkaround && renderingData.cameraData.resolveFinalTarget;
var blurSources = currentPassData.blurSources;
for (var i = 0; i < blurSources.Count; i++)
{
var blurSource = blurSources[i];
if ((currentPassData.shouldUpdateBlurMask & (1 << i)) == 0)
continue;
blurSource.ReallocateBlurTexIfNeeded(currentPassData.camPixelRect);
currentPassData.blurAlgorithm.Init(blurSource.BlurConfig, false);
var blurExecData = new BlurExecutor.BlurExecutionData(sourceTex,
blurSource,
currentPassData.blurAlgorithm);
BlurExecutor.ExecuteBlurWithTempTextures(cmd, ref blurExecData);
if (shouldResetTarget)
CoreUtils.SetRenderTarget(cmd, BuiltinRenderTextureType.CameraTarget);
}
if (currentPassData.previewIndex != -1)
{
var previewTarget = shouldResetTarget ? BuiltinRenderTextureType.CameraTarget : sourceTex;
var previewExecData = new PreviewExecutionData(blurSources[currentPassData.previewIndex],
previewTarget,
currentPassData.previewMaterial);
ExecutePreview(cmd, ref previewExecData);
}
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
public static void ExecutePreview(CommandBuffer cmd, ref PreviewExecutionData data)
{
var blurSource = data.blurSource;
data.previewMaterial.SetVector(ShaderID.CROP_REGION, RectUtils.ToMinMaxVector(blurSource.BlurRegion));
Blitter.Blit(cmd, blurSource.BlurredScreen, data.previewTarget, data.previewMaterial, 0);
}
}
}