using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering.RenderGraphModule; namespace UnityEngine.Rendering.HighDefinition { public partial class HDRenderPipeline { class AlphaUpscalePassData { public ComputeShader alphaUpscaleCS; public int alphaUpscaleKernel; public int width, height; public int viewCount; public TextureHandle source; public TextureHandle depth; public TextureHandle motionVectors; public TextureHandle output; public bool resetHistory; public TextureHandle prevAlpha; public TextureHandle nextAlpha; } TextureHandle UpscaleAlpha(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle source, TextureHandle depth, TextureHandle motionVectors, TextureHandle output) { using (var builder = renderGraph.AddUnsafePass("Alpha Upscale", out var passData, ProfilingSampler.Get(HDProfileId.AlphaCopy))) { Vector2Int finalViewport = DynamicResolutionHandler.instance.finalViewport; passData.alphaUpscaleCS = runtimeShaders.upscaleAlphaCS; passData.alphaUpscaleKernel = passData.alphaUpscaleCS.FindKernel("KMain"); passData.width = finalViewport.x; passData.height = finalViewport.y; passData.viewCount = hdCamera.viewCount; passData.source = source; builder.UseTexture(passData.source); passData.depth = depth; builder.UseTexture(passData.depth); passData.motionVectors = motionVectors; builder.UseTexture(passData.motionVectors); passData.output = output; builder.UseTexture(passData.output, AccessFlags.ReadWrite); bool validHistory = GrabPostProcessHistoryTextures(hdCamera, HDCameraFrameHistoryType.AlphaUpscale, "Alpha History", GraphicsFormat.R8_UNorm, finalViewport, out RTHandle previous, out RTHandle next); passData.resetHistory = !validHistory; passData.prevAlpha = renderGraph.ImportTexture(previous); builder.UseTexture(passData.prevAlpha, validHistory ? AccessFlags.Read : AccessFlags.ReadWrite); passData.nextAlpha = renderGraph.ImportTexture(next); builder.UseTexture(passData.nextAlpha, AccessFlags.Write); builder.SetRenderFunc(static (AlphaUpscalePassData data, UnsafeGraphContext ctx) => { if (data.resetHistory) { ctx.cmd.SetRenderTarget(data.prevAlpha); ctx.cmd.ClearRenderTarget(false, true, Color.clear); } ctx.cmd.SetComputeTextureParam(data.alphaUpscaleCS, data.alphaUpscaleKernel, HDShaderIDs._InputTexture, data.source); ctx.cmd.SetComputeTextureParam(data.alphaUpscaleCS, data.alphaUpscaleKernel, HDShaderIDs._CameraDepthTexture, data.depth); ctx.cmd.SetComputeTextureParam(data.alphaUpscaleCS, data.alphaUpscaleKernel, HDShaderIDs._CameraMotionVectorsTexture, data.motionVectors); ctx.cmd.SetComputeTextureParam(data.alphaUpscaleCS, data.alphaUpscaleKernel, HDShaderIDs._OutputTexture, data.output); ctx.cmd.SetComputeTextureParam(data.alphaUpscaleCS, data.alphaUpscaleKernel, HDShaderIDs._InputHistoryTexture, data.prevAlpha); ctx.cmd.SetComputeTextureParam(data.alphaUpscaleCS, data.alphaUpscaleKernel, HDShaderIDs._OutputHistoryTexture, data.nextAlpha); ctx.cmd.DispatchCompute(data.alphaUpscaleCS, data.alphaUpscaleKernel, (data.width + 7) / 8, (data.height + 7) / 8, data.viewCount); }); return passData.output; } } public bool GrabPostProcessHistoryTextures( HDCamera camera, HDCameraFrameHistoryType historyType, string name, GraphicsFormat format, in Vector2Int viewportSize, out RTHandle previous, out RTHandle next, bool useMips = false) { bool validHistory = true; next = camera.GetCurrentFrameRT((int)historyType); if (next == null || (useMips == true && next.rt.mipmapCount == 1) || next.rt.width != viewportSize.x || next.rt.height != viewportSize.y) { validHistory = false; var textureAllocator = new PostProcessHistoryTextureAllocator(name, viewportSize, format, useMips); if (next != null) camera.ReleaseHistoryFrameRT((int)historyType); next = camera.AllocHistoryFrameRT((int)historyType, textureAllocator.Allocator, 2); } previous = camera.GetPreviousFrameRT((int)historyType); return validHistory; } } }