using FidelityFX; using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering.RenderGraphModule; namespace UnityEngine.Rendering.HighDefinition { public partial class HDRenderPipeline { struct RenderCacaoParameters { public bool runAsync; public Vector2Int resolution; public bool downsample; public Cacao.Settings settings; public Matrix4x4 projectionMatrix; public Matrix4x4 cameraToWorldMatrix; public Vector4 rtHandleScale; } class RenderCacaoPassData { public CacaoContext cacaoContext; public TextureHandle depthBuffer; public TextureHandle normalBuffer; public Matrix4x4 projectionMatrix; public Matrix4x4 normalsToView; public Vector4 rtHandleScale; public TextureHandle aoOutput; } TextureHandle RenderCacao(RenderGraph renderGraph, HDCamera hdCamera, in RenderCacaoParameters parameters, TextureHandle depthBuffer, TextureHandle normalBuffer) { if (hdCamera.cacaoContext == null) { hdCamera.cacaoContext = new CacaoContext(); hdCamera.cacaoContext.Init(new CacaoShaders { clearLoadCounter = runtimeShaders.cacaoClearLoadCounter, prepareDepths = runtimeShaders.cacaoPrepareDepths, prepareNormals = runtimeShaders.cacaoPrepareNormals, generateImportanceMap = runtimeShaders.cacaoGenerateImportanceMap, generateSsao = runtimeShaders.cacaoGenerateSsao, edgeSensitiveBlur = runtimeShaders.cacaoEdgeSensitiveBlur, bilateralUpscale = runtimeShaders.cacaoBilateralUpscale, reinterleave = runtimeShaders.cacaoReinterleave, }); hdCamera.cacaoPrevResolution = Vector2Int.zero; } // Detect changes in resolution parameters and reinitialize context if necessary if (parameters.resolution.x != hdCamera.cacaoPrevResolution.x || parameters.resolution.y != hdCamera.cacaoPrevResolution.y || parameters.downsample != hdCamera.cacaoPrevDownsample) { hdCamera.cacaoContext.DestroyScreenSizeDependentResources(); hdCamera.cacaoContext.InitScreenSizeDependentResources(new Cacao.ScreenSizeInfo { Width = (uint)parameters.resolution.x, Height = (uint)parameters.resolution.y, UseDownsampledSsao = parameters.downsample, }); hdCamera.cacaoPrevResolution = parameters.resolution; hdCamera.cacaoPrevDownsample = parameters.downsample; } hdCamera.cacaoContext.UpdateSettings(parameters.settings); using (var builder = renderGraph.AddUnsafePass("FidelityFX CACAO", out var passData, ProfilingSampler.Get(HDProfileId.AmbientOcclusion))) { builder.EnableAsyncCompute(parameters.runAsync); passData.aoOutput = CreateAmbientOcclusionTexture(renderGraph, true); builder.UseTexture(passData.aoOutput, AccessFlags.Write); passData.cacaoContext = hdCamera.cacaoContext; passData.depthBuffer = depthBuffer; passData.normalBuffer = normalBuffer; passData.projectionMatrix = parameters.projectionMatrix; passData.normalsToView = parameters.cameraToWorldMatrix * Cacao.UnityToCacaoViewMatrix; passData.rtHandleScale = parameters.rtHandleScale; builder.SetRenderFunc((RenderCacaoPassData data, UnsafeGraphContext ctx) => { var dispatchInfo = new Cacao.DispatchInfo { DepthView = new Cacao.ResourceView(data.depthBuffer), NormalsView = new Cacao.ResourceView(data.normalBuffer), OutputView = new Cacao.ResourceView(data.aoOutput), }; ctx.cmd.SetGlobalTexture("_CameraDepthTexture", data.depthBuffer); ctx.cmd.SetGlobalTexture("_NormalBufferTexture", data.normalBuffer); ctx.cmd.SetGlobalTexture("_OcclusionTexture", data.aoOutput); data.cacaoContext.Draw(CommandBufferHelpers.GetNativeCommandBuffer(ctx.cmd), dispatchInfo, data.projectionMatrix, data.normalsToView, data.rtHandleScale); }); return passData.aoOutput; } } } }