Files
Northbound/Assets/FlatKit/[Render Pipeline] URP/RenderFeatures/Common/BlitTexturePass.cs
2026-01-25 11:27:33 +09:00

128 lines
5.6 KiB
C#

#if !UNITY_2022_3_OR_NEWER
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace FlatKit {
internal class BlitTexturePass : ScriptableRenderPass {
public static readonly string CopyEffectShaderName = "Hidden/FlatKit/CopyTexture";
private readonly ProfilingSampler _profilingSampler;
private readonly Material _effectMaterial;
private readonly ScriptableRenderPassInput _passInput;
private readonly Material _copyMaterial;
#if UNITY_2022_1_OR_NEWER
private RTHandle _temporaryColorTexture;
#else
private RenderTargetHandle _temporaryColorTexture;
#endif
public BlitTexturePass(Material effectMaterial, bool useDepth, bool useNormals, bool useColor) {
_effectMaterial = effectMaterial;
var name = effectMaterial.name.Substring(effectMaterial.name.LastIndexOf('/') + 1);
_profilingSampler = new ProfilingSampler($"Blit {name}");
_passInput = (useColor ? ScriptableRenderPassInput.Color : ScriptableRenderPassInput.None) |
(useDepth ? ScriptableRenderPassInput.Depth : ScriptableRenderPassInput.None) |
(useNormals ? ScriptableRenderPassInput.Normal : ScriptableRenderPassInput.None);
#if !UNITY_2022_1_OR_NEWER
_copyMaterial = CoreUtils.CreateEngineMaterial(CopyEffectShaderName);
#endif
}
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) {
ConfigureInput(_passInput);
base.Configure(cmd, cameraTextureDescriptor);
}
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) {
#if !UNITY_2022_1_OR_NEWER
ConfigureTarget(new RenderTargetIdentifier(renderingData.cameraData.renderer.cameraColorTarget, 0,
CubemapFace.Unknown, -1));
_temporaryColorTexture.Init("_EffectTexture");
#endif
}
public void Setup(RenderingData renderingData) {
#if UNITY_2022_1_OR_NEWER
var descriptor = renderingData.cameraData.cameraTargetDescriptor;
descriptor.depthBufferBits = 0;
RenderingUtils.ReAllocateIfNeeded(ref _temporaryColorTexture, descriptor, wrapMode: TextureWrapMode.Clamp,
name: "_EffectTexture");
#endif
}
public void Dispose() {
#if UNITY_2022_1_OR_NEWER
_temporaryColorTexture?.Release();
#endif
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) {
if (_effectMaterial == null) return;
CommandBuffer cmd = CommandBufferPool.Get();
using (new ProfilingScope(cmd, _profilingSampler)) {
var descriptor = renderingData.cameraData.cameraTargetDescriptor;
descriptor.depthBufferBits = 0;
SetSourceSize(cmd, descriptor);
#if UNITY_2022_1_OR_NEWER
var cameraTargetHandle = renderingData.cameraData.renderer.cameraColorTargetHandle;
// cmd.GetTemporaryRT(Shader.PropertyToID(_temporaryColorTexture.name), descriptor);
#else
var cameraTargetHandle = renderingData.cameraData.renderer.cameraColorTarget;
cmd.GetTemporaryRT(_temporaryColorTexture.id, descriptor);
#endif
// Also seen as `renderingData.cameraData.xr.enabled` and `#if ENABLE_VR && ENABLE_XR_MODULE`.
if (renderingData.cameraData.xrRendering) {
_effectMaterial.EnableKeyword("_USE_DRAW_PROCEDURAL"); // `UniversalRenderPipelineCore.cs`.
#if UNITY_2022_1_OR_NEWER
#pragma warning disable CS0618
cmd.SetRenderTarget(_temporaryColorTexture);
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, _effectMaterial, 0, 0);
cmd.SetGlobalTexture("_EffectTexture", _temporaryColorTexture);
cmd.SetRenderTarget(new RenderTargetIdentifier(cameraTargetHandle, 0, CubemapFace.Unknown, -1));
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, _copyMaterial, 0, 0);
#else
cmd.SetRenderTarget(_temporaryColorTexture.Identifier());
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, _effectMaterial, 0, 0);
cmd.SetGlobalTexture("_EffectTexture", _temporaryColorTexture.Identifier());
cmd.SetRenderTarget(new RenderTargetIdentifier(cameraTargetHandle, 0, CubemapFace.Unknown, -1));
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, _copyMaterial, 0, 0);
#endif
} else {
_effectMaterial.DisableKeyword("_USE_DRAW_PROCEDURAL");
// Note: `FinalBlitPass` has `cmd.SetRenderTarget` at this point, but it's unclear what that does.
#if UNITY_2022_1_OR_NEWER
cmd.Blit(cameraTargetHandle, _temporaryColorTexture, _effectMaterial, 0);
cmd.Blit(_temporaryColorTexture, cameraTargetHandle);
#else
cmd.Blit(cameraTargetHandle, _temporaryColorTexture.Identifier(), _effectMaterial, 0);
cmd.Blit(_temporaryColorTexture.Identifier(), cameraTargetHandle);
#endif
}
}
context.ExecuteCommandBuffer(cmd);
cmd.Clear();
CommandBufferPool.Release(cmd);
}
// Copied from `PostProcessUtils.cs`.
private static void SetSourceSize(CommandBuffer cmd, RenderTextureDescriptor desc) {
float width = desc.width;
float height = desc.height;
if (desc.useDynamicScale) {
width *= ScalableBufferManager.widthScaleFactor;
height *= ScalableBufferManager.heightScaleFactor;
}
cmd.SetGlobalVector("_SourceSize", new Vector4(width, height, 1.0f / width, 1.0f / height));
}
}
}
#endif