using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; #if UNITY_6000_0_OR_NEWER using UnityEngine.Rendering.RenderGraphModule; #endif namespace Qjjxk.Blur { public class BlurCameraPass : ScriptableRenderPass { private readonly RTHandle _blurRT, _tempRT; private readonly Material _blurMat, _blurMat2; public int iterations; public BlurType blurType; private readonly Material[] _blurMats; public BlurCameraPass(BlurType blurType, RenderTexture blurRT, RenderTexture tempRT, Material[] blurMats, Material mat, Material mat2, int iteration) { renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing; this.blurType = blurType; _tempRT = RTHandles.Alloc(tempRT); _blurRT = RTHandles.Alloc(blurRT); _blurMats = blurMats; _blurMat = mat; _blurMat2 = mat2; iterations = iteration; } #if UNITY_6000_0_OR_NEWER [System.Obsolete] #endif public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { var commandBuffer = CommandBufferPool.Get("CameraCapture"); commandBuffer.Clear(); #if UNITY_2022 var source = renderingData.cameraData.renderer.cameraColorTargetHandle; #else var source = renderingData.cameraData.renderer.cameraColorTarget; #endif if (blurType == BlurType.Gaussian) { Blit(commandBuffer, source, _blurRT, _blurMat); for (var i = 0; i < iterations; i++) { var blurMat = i == 1 ? _blurMat2 : _blurMat; Blit(commandBuffer, _blurRT, _tempRT, blurMat, 1); Blit(commandBuffer, _tempRT, _blurRT, blurMat, 2); } } else if (blurType == BlurType.Kawase) { Blit(commandBuffer, source, _tempRT, _blurMat); for (var i = 0; i < 2 * iterations - 1; i++) { var index = i < iterations ? i : 2 * iterations - i - 2; if (index % 2 == 0) Blit(commandBuffer, _tempRT, _blurRT, _blurMats[index], 4); else Blit(commandBuffer, _blurRT, _tempRT, _blurMats[index], 4); } } else if (blurType == BlurType.Grainy) { Blit(commandBuffer, source, _tempRT, _blurMat); Blit(commandBuffer, _tempRT, _blurRT, _blurMats[0], 3); } context.ExecuteCommandBuffer(commandBuffer); CommandBufferPool.Release(commandBuffer); } #if UNITY_6000_0_OR_NEWER private class BlurPassData { public TextureHandle inputTh; public Material blurMat; public int pass; } public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) { if (_blurRT == null || _blurRT.rt == null || _tempRT == null || _tempRT.rt == null) return; if (_blurMat == null || _blurMat2 == null) return; var resourceData = frameData.Get(); var blurDesc = _blurRT.rt.descriptor; var blurInfo = new RenderTargetInfo { width = blurDesc.width, height = blurDesc.height, volumeDepth = blurDesc.volumeDepth, msaaSamples = blurDesc.msaaSamples, format = blurDesc.graphicsFormat, }; var tempDesc = _tempRT.rt.descriptor; var tempInfo = new RenderTargetInfo { width = tempDesc.width, height = tempDesc.height, volumeDepth = tempDesc.volumeDepth, msaaSamples = tempDesc.msaaSamples, format = tempDesc.graphicsFormat, }; var blurHandle = renderGraph.ImportTexture(_blurRT, blurInfo); var tempHandle = renderGraph.ImportTexture(_tempRT, tempInfo); if (blurType == BlurType.Gaussian) { for (var i = 0; i < iterations * 2 + 1; i++) { using var builder = renderGraph.AddRasterRenderPass("BlurCameraPass", out var passData); passData.blurMat = i is 3 or 4 ? _blurMat2 : _blurMat; if (i == 0) { passData.pass = 0; passData.inputTh = resourceData.activeColorTexture; } else if (i % 2 == 1) { passData.pass = 1; passData.inputTh = blurHandle; } else { passData.pass = 2; passData.inputTh = tempHandle; } builder.SetRenderAttachment(i % 2 == 0 ? blurHandle : tempHandle, 0, AccessFlags.WriteAll); builder.SetRenderFunc((BlurPassData data, RasterGraphContext context) => { if (data.blurMat != null) Blitter.BlitTexture(context.cmd, data.inputTh, new Vector4(1, 1, 0, 0), data.blurMat, data.pass); }); } } else if (blurType == BlurType.Kawase) { if (_blurMats == null) return; for (var i = -1; i < 2 * iterations - 1; i++) { var index = i < iterations ? i : 2 * iterations - i - 2; using var builder = renderGraph.AddRasterRenderPass("BlurCameraPass", out var passData); passData.blurMat = index == -1 ? _blurMat : (index >= 0 && index < _blurMats.Length ? _blurMats[index] : null); if (index == -1) { passData.pass = 0; passData.inputTh = resourceData.activeColorTexture; } else if (index % 2 == 0) { passData.pass = 4; passData.inputTh = tempHandle; } else { passData.pass = 4; passData.inputTh = blurHandle; } builder.SetRenderAttachment(i % 2 == 0 ? blurHandle : tempHandle, 0, AccessFlags.WriteAll); builder.SetRenderFunc((BlurPassData data, RasterGraphContext context) => { if (data.blurMat != null) Blitter.BlitTexture(context.cmd, data.inputTh, new Vector4(1, 1, 0, 0), data.blurMat, data.pass); }); } } else if (blurType == BlurType.Grainy) { if (_blurMats == null || _blurMats.Length == 0) return; using var builder = renderGraph.AddRasterRenderPass("BlurCameraPass", out var passData); passData.blurMat = _blurMats[0]; passData.pass = 3; passData.inputTh = resourceData.activeColorTexture; builder.SetRenderAttachment(blurHandle, 0, AccessFlags.WriteAll); builder.SetRenderFunc((BlurPassData data, RasterGraphContext context) => { if (data.blurMat != null) Blitter.BlitTexture(context.cmd, data.inputTh, new Vector4(1, 1, 0, 0), data.blurMat, data.pass); }); } } #endif } }