// Denoiser variant for non history array static public void DenoiseBuffer(CommandBuffer cmd, TemporalFilterParameters tfParameters, TemporalFilterResources tfResources) { // Evaluate the dispatch parameters int areaTileSize = 8; int numTilesX = (tfParameters.texWidth + (areaTileSize - 1)) / areaTileSize; int numTilesY = (tfParameters.texHeight + (areaTileSize - 1)) / areaTileSize; // Now that we have validated our history, let's accumulate // Bind the input buffers cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.temporalAccKernel, HDShaderIDs._DenoiseInputTexture, tfResources.noisyBuffer); cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.temporalAccKernel, HDShaderIDs._HistoryBuffer, tfResources.historyBuffer); cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.temporalAccKernel, HDShaderIDs._DepthTexture, tfResources.depthStencilBuffer); cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.temporalAccKernel, HDShaderIDs._ValidationBuffer, tfResources.validationBuffer); cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.temporalAccKernel, HDShaderIDs._VelocityBuffer, tfResources.velocityBuffer); cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.temporalAccKernel, HDShaderIDs._CameraMotionVectorsTexture, tfResources.motionVectorBuffer); cmd.SetComputeFloatParam(tfParameters.temporalFilterCS, HDShaderIDs._HistoryValidity, tfParameters.historyValidity); // Bind the output buffer cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.temporalAccKernel, HDShaderIDs._DenoiseOutputTextureRW, tfResources.outputBuffer); // Combine signal with history cmd.DispatchCompute(tfParameters.temporalFilterCS, tfParameters.temporalAccKernel, numTilesX, numTilesY, tfParameters.viewCount); // Make sure to copy the new-accumulated signal in our history buffer cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.copyHistoryKernel, HDShaderIDs._DenoiseInputTexture, tfResources.outputBuffer); cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.copyHistoryKernel, HDShaderIDs._DenoiseOutputTextureRW, tfResources.historyBuffer); cmd.DispatchCompute(tfParameters.temporalFilterCS, tfParameters.copyHistoryKernel, numTilesX, numTilesY, tfParameters.viewCount); }
public void DenoiseAO(CommandBuffer cmd, HDCamera hdCamera, RTHandle outputTexture) { var aoSettings = hdCamera.volumeStack.GetComponent <AmbientOcclusion>(); if (aoSettings.denoise) { // Evaluate the history's validity float historyValidity = historyValidity = HDRenderPipeline.ValidRayTracingHistory(hdCamera) ? 1.0f : 0.0f; // Grab the history buffer RTHandle aoHistory = RequestAmbientOcclusionHistoryTexture(hdCamera); // Prepare and execute the temporal filter HDTemporalFilter temporalFilter = m_RenderPipeline.GetTemporalFilter(); TemporalFilterParameters tfParameters = temporalFilter.PrepareTemporalFilterParameters(hdCamera, true, historyValidity); RTHandle validationBuffer = m_RenderPipeline.GetRayTracingBuffer(InternalRayTracingBuffers.R0); TemporalFilterResources tfResources = temporalFilter.PrepareTemporalFilterResources(hdCamera, validationBuffer, m_AOIntermediateBuffer0, aoHistory, m_AOIntermediateBuffer1); HDTemporalFilter.DenoiseBuffer(cmd, tfParameters, tfResources); // Apply the diffuse denoiser HDDiffuseDenoiser diffuseDenoiser = m_RenderPipeline.GetDiffuseDenoiser(); DiffuseDenoiserParameters ddParams = diffuseDenoiser.PrepareDiffuseDenoiserParameters(hdCamera, true, aoSettings.denoiserRadius, false, false); RTHandle intermediateBuffer = m_RenderPipeline.GetRayTracingBuffer(InternalRayTracingBuffers.RGBA0); DiffuseDenoiserResources ddResources = diffuseDenoiser.PrepareDiffuseDenoiserResources(m_AOIntermediateBuffer1, intermediateBuffer, outputTexture); HDDiffuseDenoiser.DenoiseBuffer(cmd, ddParams, ddResources); } else { HDUtils.BlitCameraTexture(cmd, m_AOIntermediateBuffer0, outputTexture); } }
// Denoiser variant for non history array static public void DenoiseBuffer(CommandBuffer cmd, TemporalFilterParameters tfParameters, TemporalFilterResources tfResources) { // If we do not have a depth and normal history buffers, we can skip right away if (tfResources.historyDepthTexture == null || tfResources.historyNormalTexture == null) { HDUtils.BlitCameraTexture(cmd, tfResources.noisyBuffer, tfResources.historyBuffer); HDUtils.BlitCameraTexture(cmd, tfResources.noisyBuffer, tfResources.outputBuffer); return; } // Evaluate the dispatch parameters int areaTileSize = 8; int numTilesX = (tfParameters.texWidth + (areaTileSize - 1)) / areaTileSize; int numTilesY = (tfParameters.texHeight + (areaTileSize - 1)) / areaTileSize; // First of all we need to validate the history to know where we can or cannot use the history signal // Bind the input buffers cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.validateHistoryKernel, HDShaderIDs._DepthTexture, tfResources.depthStencilBuffer); cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.validateHistoryKernel, HDShaderIDs._HistoryDepthTexture, tfResources.historyDepthTexture); cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.validateHistoryKernel, HDShaderIDs._NormalBufferTexture, tfResources.normalBuffer); cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.validateHistoryKernel, HDShaderIDs._HistoryNormalTexture, tfResources.historyNormalTexture); cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.validateHistoryKernel, HDShaderIDs._VelocityBuffer, tfResources.velocityBuffer); cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.validateHistoryKernel, HDShaderIDs._CameraMotionVectorsTexture, tfResources.motionVectorBuffer); // Bind the constants cmd.SetComputeFloatParam(tfParameters.temporalFilterCS, HDShaderIDs._HistoryValidity, tfParameters.historyValidity); cmd.SetComputeFloatParam(tfParameters.temporalFilterCS, HDShaderIDs._PixelSpreadAngleTangent, tfParameters.pixelSpreadTangent); // Bind the output buffer cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.validateHistoryKernel, HDShaderIDs._ValidationBufferRW, tfResources.validationBuffer); // Evaluate the validity cmd.DispatchCompute(tfParameters.temporalFilterCS, tfParameters.validateHistoryKernel, numTilesX, numTilesY, tfParameters.viewCount); // Now that we have validated our history, let's accumulate // Bind the input buffers cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.temporalAccKernel, HDShaderIDs._DenoiseInputTexture, tfResources.noisyBuffer); cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.temporalAccKernel, HDShaderIDs._HistoryBuffer, tfResources.historyBuffer); cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.temporalAccKernel, HDShaderIDs._DepthTexture, tfResources.depthStencilBuffer); cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.temporalAccKernel, HDShaderIDs._ValidationBuffer, tfResources.validationBuffer); cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.temporalAccKernel, HDShaderIDs._VelocityBuffer, tfResources.velocityBuffer); cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.temporalAccKernel, HDShaderIDs._CameraMotionVectorsTexture, tfResources.motionVectorBuffer); // Bind the output buffer cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.temporalAccKernel, HDShaderIDs._DenoiseOutputTextureRW, tfResources.outputBuffer); // Combine signal with history cmd.DispatchCompute(tfParameters.temporalFilterCS, tfParameters.temporalAccKernel, numTilesX, numTilesY, tfParameters.viewCount); // Make sure to copy the new-accumulated signal in our history buffer cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.copyHistoryKernel, HDShaderIDs._DenoiseInputTexture, tfResources.outputBuffer); cmd.SetComputeTextureParam(tfParameters.temporalFilterCS, tfParameters.copyHistoryKernel, HDShaderIDs._DenoiseOutputTextureRW, tfResources.historyBuffer); cmd.DispatchCompute(tfParameters.temporalFilterCS, tfParameters.copyHistoryKernel, numTilesX, numTilesY, tfParameters.viewCount); }
TextureHandle DenoiseRTSSS(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle rayTracedSSS, TextureHandle depthPyramid, TextureHandle normalBuffer, TextureHandle motionVectorBuffer) { // Evaluate the history's validity float historyValidity = HDRenderPipeline.EvaluateHistoryValidity(hdCamera); // Run the temporal denoiser HDTemporalFilter temporalFilter = GetTemporalFilter(); TemporalFilterParameters tfParameters = temporalFilter.PrepareTemporalFilterParameters(hdCamera, false, historyValidity); TextureHandle historyBuffer = renderGraph.ImportTexture(RequestRayTracedSSSHistoryTexture(hdCamera)); return(temporalFilter.Denoise(renderGraph, hdCamera, tfParameters, rayTracedSSS, historyBuffer, depthPyramid, normalBuffer, motionVectorBuffer)); }
public TextureHandle Denoise(RenderGraph renderGraph, HDCamera hdCamera, TemporalFilterParameters tfParameters, TextureHandle noisyBuffer, TextureHandle historyBuffer, TextureHandle depthPyramid, TextureHandle normalBuffer, TextureHandle motionVectorBuffer) { using (var builder = renderGraph.AddRenderPass <TemporalFilterPassData>("TemporalDenoiser", out var passData, ProfilingSampler.Get(HDProfileId.TemporalFilter))) { // Cannot run in async builder.EnableAsyncCompute(false); // Fetch all the resources passData.parameters = tfParameters; // Input Buffers passData.depthStencilBuffer = builder.ReadTexture(depthPyramid); passData.normalBuffer = builder.ReadTexture(normalBuffer); passData.motionVectorBuffer = builder.ReadTexture(motionVectorBuffer); passData.velocityBuffer = renderGraph.defaultResources.blackTextureXR; passData.noisyBuffer = builder.ReadTexture(noisyBuffer); // Temporary buffers passData.validationBuffer = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R8_UNorm, enableRandomWrite = true, name = "ValidationTexture" }); // History buffers passData.historyDepthTexture = builder.ReadTexture(renderGraph.ImportTexture(hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.Depth))); passData.historyNormalTexture = builder.ReadTexture(renderGraph.ImportTexture(hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.Normal))); passData.historyBuffer = builder.ReadTexture(builder.WriteTexture(historyBuffer)); // Output buffers passData.outputBuffer = builder.ReadTexture(builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Temporal Filter Output" }))); builder.SetRenderFunc( (TemporalFilterPassData data, RenderGraphContext ctx) => { TemporalFilterResources tfResources = new TemporalFilterResources(); tfResources.depthStencilBuffer = data.depthStencilBuffer; tfResources.normalBuffer = data.normalBuffer; tfResources.velocityBuffer = data.velocityBuffer; tfResources.motionVectorBuffer = data.motionVectorBuffer; tfResources.historyDepthTexture = data.historyDepthTexture; tfResources.historyNormalTexture = data.historyNormalTexture; tfResources.noisyBuffer = data.noisyBuffer; tfResources.validationBuffer = data.validationBuffer; tfResources.historyBuffer = data.historyBuffer; tfResources.outputBuffer = data.outputBuffer; DenoiseBuffer(ctx.cmd, data.parameters, tfResources); }); return(passData.outputBuffer); } }
void DenoiseIndirectDiffuseBuffer(HDCamera hdCamera, CommandBuffer cmd, GlobalIllumination settings) { // Grab the high frequency history buffer RTHandle indirectDiffuseHistoryHF = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedIndirectDiffuseHF) ?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedIndirectDiffuseHF, IndirectDiffuseHistoryBufferAllocatorFunction, 1); // Request the intermediate textures we will be using RTHandle intermediateBuffer1 = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA1); RTHandle validationBuffer = GetRayTracingBuffer(InternalRayTracingBuffers.R0); // Evaluate the history validity float historyValidity0 = EvaluateIndirectDiffuseHistoryValidity0(hdCamera, settings.fullResolution, true); // Grab the temporal denoiser HDTemporalFilter temporalFilter = GetTemporalFilter(); // Temporal denoising TemporalFilterParameters tfParameters = temporalFilter.PrepareTemporalFilterParameters(hdCamera, false, historyValidity0); TemporalFilterResources tfResources = temporalFilter.PrepareTemporalFilterResources(hdCamera, validationBuffer, m_IndirectDiffuseBuffer0, indirectDiffuseHistoryHF, intermediateBuffer1); HDTemporalFilter.DenoiseBuffer(cmd, tfParameters, tfResources); // Apply the first pass of our denoiser HDDiffuseDenoiser diffuseDenoiser = GetDiffuseDenoiser(); DiffuseDenoiserParameters ddParams = diffuseDenoiser.PrepareDiffuseDenoiserParameters(hdCamera, false, settings.denoiserRadius, settings.halfResolutionDenoiser, settings.secondDenoiserPass); RTHandle intermediateBuffer = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA0); DiffuseDenoiserResources ddResources = diffuseDenoiser.PrepareDiffuseDenoiserResources(intermediateBuffer1, intermediateBuffer, m_IndirectDiffuseBuffer0); HDDiffuseDenoiser.DenoiseBuffer(cmd, ddParams, ddResources); // If the second pass is requested, do it otherwise blit if (settings.secondDenoiserPass) { float historyValidity1 = EvaluateIndirectDiffuseHistoryValidity1(hdCamera, settings.fullResolution, true); // Grab the low frequency history buffer RTHandle indirectDiffuseHistoryLF = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedIndirectDiffuseLF) ?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedIndirectDiffuseLF, IndirectDiffuseHistoryBufferAllocatorFunction, 1); // Run the temporal denoiser tfParameters = temporalFilter.PrepareTemporalFilterParameters(hdCamera, false, historyValidity1); tfResources = temporalFilter.PrepareTemporalFilterResources(hdCamera, validationBuffer, m_IndirectDiffuseBuffer0, indirectDiffuseHistoryLF, intermediateBuffer1); HDTemporalFilter.DenoiseBuffer(cmd, tfParameters, tfResources); // Run the spatial denoiser ddParams = diffuseDenoiser.PrepareDiffuseDenoiserParameters(hdCamera, false, settings.denoiserRadius * 0.5f, settings.halfResolutionDenoiser, false); ddResources = diffuseDenoiser.PrepareDiffuseDenoiserResources(intermediateBuffer1, intermediateBuffer, m_IndirectDiffuseBuffer0); HDDiffuseDenoiser.DenoiseBuffer(cmd, ddParams, ddResources); PropagateIndirectDiffuseHistoryValidity1(hdCamera, settings.fullResolution, true); } // Propagate the history PropagateIndirectDiffuseHistoryValidity0(hdCamera, settings.fullResolution, true); }
public TextureHandle Denoise(RenderGraph renderGraph, HDCamera hdCamera, TemporalFilterParameters tfParameters, TextureHandle noisyBuffer, TextureHandle velocityBuffer, TextureHandle historyBuffer, TextureHandle depthBuffer, TextureHandle normalBuffer, TextureHandle motionVectorBuffer, TextureHandle historyValidationBuffer) { using (var builder = renderGraph.AddRenderPass <TemporalFilterPassData>("TemporalDenoiser", out var passData, ProfilingSampler.Get(HDProfileId.TemporalFilter))) { // Cannot run in async builder.EnableAsyncCompute(false); // Fetch all the resources passData.parameters = tfParameters; // Prepass Buffers passData.depthStencilBuffer = builder.ReadTexture(depthBuffer); passData.normalBuffer = builder.ReadTexture(normalBuffer); passData.motionVectorBuffer = builder.ReadTexture(motionVectorBuffer); // Effect buffers passData.velocityBuffer = builder.ReadTexture(velocityBuffer); passData.noisyBuffer = builder.ReadTexture(noisyBuffer); passData.validationBuffer = builder.ReadTexture(historyValidationBuffer); // History buffer passData.historyBuffer = builder.ReadWriteTexture(historyBuffer); // Output buffers passData.outputBuffer = builder.ReadWriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Temporal Filter Output" })); builder.SetRenderFunc( (TemporalFilterPassData data, RenderGraphContext ctx) => { TemporalFilterResources tfResources = new TemporalFilterResources(); tfResources.depthStencilBuffer = data.depthStencilBuffer; tfResources.normalBuffer = data.normalBuffer; tfResources.velocityBuffer = data.velocityBuffer; tfResources.motionVectorBuffer = data.motionVectorBuffer; tfResources.noisyBuffer = data.noisyBuffer; tfResources.validationBuffer = data.validationBuffer; tfResources.historyBuffer = data.historyBuffer; tfResources.outputBuffer = data.outputBuffer; DenoiseBuffer(ctx.cmd, data.parameters, tfResources); }); return(passData.outputBuffer); } }
void RenderSubsurfaceScatteringRT(HDCamera hdCamera, CommandBuffer cmd, RTHandle colorBufferRT, RTHandle diffuseBufferRT, RTHandle depthStencilBufferRT, RTHandle depthTextureRT) { using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.SubsurfaceScattering))) { // Grab the SSS params var settings = hdCamera.volumeStack.GetComponent <SubSurfaceScattering>(); // Fetch all the intermediate buffers that we need (too much of them to be fair) RTHandle intermediateBuffer0 = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA0); RTHandle intermediateBuffer1 = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA1); RTHandle intermediateBuffer2 = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA2); RTHandle intermediateBuffer3 = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA3); RTHandle intermediateBuffer4 = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA4); RTHandle directionBuffer = GetRayTracingBuffer(InternalRayTracingBuffers.Direction); // Evaluate the lighting for the samples that we need to SSSRayTracingParameters sssrtParams = PrepareSSSRayTracingParameters(hdCamera, settings); SSSRayTracingResources sssrtResources = PrepareSSSRayTracingResources(m_SSSColor, intermediateBuffer0, intermediateBuffer1, intermediateBuffer2, intermediateBuffer3, directionBuffer, intermediateBuffer4); ExecuteRTSubsurfaceScattering(cmd, sssrtParams, sssrtResources); // Grab the history buffer RTHandle subsurfaceHistory = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RayTracedSubSurface) ?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RayTracedSubSurface, SubSurfaceHistoryBufferAllocatorFunction, 1); // Check if we need to invalidate the history float historyValidity = EvaluateHistoryValidity(hdCamera); // Apply temporal filtering to the signal HDTemporalFilter temporalFilter = GetTemporalFilter(); TemporalFilterParameters tfParameters = temporalFilter.PrepareTemporalFilterParameters(hdCamera, false, historyValidity); RTHandle validationBuffer = GetRayTracingBuffer(InternalRayTracingBuffers.R0); TemporalFilterResources tfResources = temporalFilter.PrepareTemporalFilterResources(hdCamera, validationBuffer, intermediateBuffer4, subsurfaceHistory, intermediateBuffer0); HDTemporalFilter.DenoiseBuffer(cmd, tfParameters, tfResources); // Combine the result with the rest of the lighting SSSCombineParameters ssscParams = PrepareSSSCombineParameters(hdCamera); SSSCombineResources ssscResources = PrepareSSSCombineResources(m_SSSColor, colorBufferRT, diffuseBufferRT, intermediateBuffer0, ssscParams.validSSGI); ExecuteCombineSubsurfaceScattering(cmd, ssscParams, ssscResources); // Push this version of the texture for debug PushFullScreenDebugTexture(hdCamera, cmd, diffuseBufferRT, FullScreenDebugMode.RayTracedSubSurface); } }
public TemporalFilterParameters PrepareTemporalFilterParameters(HDCamera hdCamera, bool singleChannel, float historyValidity) { TemporalFilterParameters temporalFilterParameters = new TemporalFilterParameters(); // Camera parameters temporalFilterParameters.texWidth = hdCamera.actualWidth; temporalFilterParameters.texHeight = hdCamera.actualHeight; temporalFilterParameters.viewCount = hdCamera.viewCount; // Denoising parameters temporalFilterParameters.pixelSpreadTangent = HDRenderPipeline.GetPixelSpreadTangent(hdCamera.camera.fieldOfView, hdCamera.actualWidth, hdCamera.actualHeight); temporalFilterParameters.historyValidity = historyValidity; // Kernels temporalFilterParameters.temporalAccKernel = singleChannel ? m_TemporalAccumulationSingleKernel : m_TemporalAccumulationColorKernel; temporalFilterParameters.copyHistoryKernel = singleChannel ? m_CopyHistorySingleKernel : m_CopyHistoryColorKernel; // Other parameters temporalFilterParameters.temporalFilterCS = m_TemporalFilterCS; return(temporalFilterParameters); }
public void DenoiseAO(CommandBuffer cmd, HDCamera hdCamera, AmbientOcclusionDenoiseParameters aoDenoiseParameters, AmbientOcclusionDenoiseResources aoDenoiseResources) { if (aoDenoiseParameters.denoise) { // Prepare and execute the temporal filter HDTemporalFilter temporalFilter = m_RenderPipeline.GetTemporalFilter(); TemporalFilterParameters tfParameters = temporalFilter.PrepareTemporalFilterParameters(hdCamera, true, aoDenoiseParameters.historyValidity); RTHandle validationBuffer = m_RenderPipeline.GetRayTracingBuffer(InternalRayTracingBuffers.R0); TemporalFilterResources tfResources = temporalFilter.PrepareTemporalFilterResources(hdCamera, validationBuffer, aoDenoiseResources.inputTexture, aoDenoiseResources.ambientOcclusionHistory, aoDenoiseResources.intermediateBuffer); HDTemporalFilter.DenoiseBuffer(cmd, tfParameters, tfResources); // Apply the diffuse denoiser HDDiffuseDenoiser diffuseDenoiser = m_RenderPipeline.GetDiffuseDenoiser(); DiffuseDenoiserParameters ddParams = diffuseDenoiser.PrepareDiffuseDenoiserParameters(hdCamera, true, aoDenoiseParameters.denoiserRadius, false); RTHandle intermediateBuffer = m_RenderPipeline.GetRayTracingBuffer(InternalRayTracingBuffers.RGBA0); DiffuseDenoiserResources ddResources = diffuseDenoiser.PrepareDiffuseDenoiserResources(aoDenoiseResources.intermediateBuffer, intermediateBuffer, aoDenoiseResources.outputTexture); HDDiffuseDenoiser.DenoiseBuffer(cmd, ddParams, ddResources); } else { HDUtils.BlitCameraTexture(cmd, aoDenoiseResources.inputTexture, aoDenoiseResources.outputTexture); } }
// Denoiser variant for non history array internal TextureHandle Denoise(RenderGraph renderGraph, HDCamera hdCamera, TemporalFilterParameters filterParams, TextureHandle noisyBuffer, TextureHandle velocityBuffer, TextureHandle historyBuffer, TextureHandle depthBuffer, TextureHandle normalBuffer, TextureHandle motionVectorBuffer, TextureHandle historyValidationBuffer) { using (var builder = renderGraph.AddRenderPass <TemporalFilterPassData>("TemporalDenoiser", out var passData, ProfilingSampler.Get(HDProfileId.TemporalFilter))) { // Cannot run in async builder.EnableAsyncCompute(false); // Camera parameters passData.texWidth = hdCamera.actualWidth; passData.texHeight = hdCamera.actualHeight; passData.viewCount = hdCamera.viewCount; // Denoising parameters passData.pixelSpreadTangent = HDRenderPipeline.GetPixelSpreadTangent(hdCamera.camera.fieldOfView, hdCamera.actualWidth, hdCamera.actualHeight); passData.historyValidity = filterParams.historyValidity; passData.receiverMotionRejection = filterParams.receiverMotionRejection; passData.occluderMotionRejection = filterParams.occluderMotionRejection; passData.exposureControl = filterParams.exposureControl; // Kernels passData.temporalAccKernel = filterParams.singleChannel ? m_TemporalAccumulationSingleKernel : m_TemporalAccumulationColorKernel; passData.copyHistoryKernel = m_CopyHistoryKernel; // Other parameters passData.temporalFilterCS = m_TemporalFilterCS; // Prepass Buffers passData.depthStencilBuffer = builder.ReadTexture(depthBuffer); passData.normalBuffer = builder.ReadTexture(normalBuffer); passData.motionVectorBuffer = builder.ReadTexture(motionVectorBuffer); // Effect buffers passData.velocityBuffer = builder.ReadTexture(velocityBuffer); passData.noisyBuffer = builder.ReadTexture(noisyBuffer); passData.validationBuffer = builder.ReadTexture(historyValidationBuffer); // History buffer passData.historyBuffer = builder.ReadWriteTexture(historyBuffer); // Output buffers passData.outputBuffer = builder.ReadWriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Temporal Filter Output" })); builder.SetRenderFunc( (TemporalFilterPassData data, RenderGraphContext ctx) => { // Evaluate the dispatch parameters int areaTileSize = 8; int numTilesX = (data.texWidth + (areaTileSize - 1)) / areaTileSize; int numTilesY = (data.texHeight + (areaTileSize - 1)) / areaTileSize; // Now that we have validated our history, let's accumulate // Bind the input buffers ctx.cmd.SetComputeTextureParam(data.temporalFilterCS, data.temporalAccKernel, HDShaderIDs._DenoiseInputTexture, data.noisyBuffer); ctx.cmd.SetComputeTextureParam(data.temporalFilterCS, data.temporalAccKernel, HDShaderIDs._HistoryBuffer, data.historyBuffer); ctx.cmd.SetComputeTextureParam(data.temporalFilterCS, data.temporalAccKernel, HDShaderIDs._DepthTexture, data.depthStencilBuffer); ctx.cmd.SetComputeTextureParam(data.temporalFilterCS, data.temporalAccKernel, HDShaderIDs._ValidationBuffer, data.validationBuffer); ctx.cmd.SetComputeTextureParam(data.temporalFilterCS, data.temporalAccKernel, HDShaderIDs._VelocityBuffer, data.velocityBuffer); ctx.cmd.SetComputeTextureParam(data.temporalFilterCS, data.temporalAccKernel, HDShaderIDs._CameraMotionVectorsTexture, data.motionVectorBuffer); ctx.cmd.SetComputeFloatParam(data.temporalFilterCS, HDShaderIDs._HistoryValidity, data.historyValidity); ctx.cmd.SetComputeIntParam(data.temporalFilterCS, HDShaderIDs._ReceiverMotionRejection, data.receiverMotionRejection ? 1 : 0); ctx.cmd.SetComputeIntParam(data.temporalFilterCS, HDShaderIDs._OccluderMotionRejection, data.occluderMotionRejection ? 1 : 0); ctx.cmd.SetComputeFloatParam(data.temporalFilterCS, HDShaderIDs._PixelSpreadAngleTangent, data.pixelSpreadTangent); ctx.cmd.SetComputeFloatParam(data.temporalFilterCS, HDShaderIDs._EnableExposureControl, data.exposureControl); // Bind the output buffer ctx.cmd.SetComputeTextureParam(data.temporalFilterCS, data.temporalAccKernel, HDShaderIDs._AccumulationOutputTextureRW, data.outputBuffer); // Combine signal with history ctx.cmd.DispatchCompute(data.temporalFilterCS, data.temporalAccKernel, numTilesX, numTilesY, data.viewCount); // Make sure to copy the new-accumulated signal in our history buffer ctx.cmd.SetComputeTextureParam(data.temporalFilterCS, data.copyHistoryKernel, HDShaderIDs._DenoiseInputTexture, data.outputBuffer); ctx.cmd.SetComputeTextureParam(data.temporalFilterCS, data.copyHistoryKernel, HDShaderIDs._DenoiseOutputTextureRW, data.historyBuffer); ctx.cmd.DispatchCompute(data.temporalFilterCS, data.copyHistoryKernel, numTilesX, numTilesY, data.viewCount); }); return(passData.outputBuffer); } }