// 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);
        }
Exemple #2
0
        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);
        }
Exemple #4
0
        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));
        }
Exemple #5
0
        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);
            }
        }
Exemple #6
0
        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);
        }
Exemple #10
0
        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);
            }
        }