Beispiel #1
0
        public SSGIDenoiserOutput Denoise(RenderGraph renderGraph, HDCamera hdCamera,
                                          TextureHandle depthPyramid, TextureHandle normalBuffer, TextureHandle motionVectorsBuffer, TextureHandle inputOutputBuffer0, TextureHandle inputOutputBuffer1,
                                          HDUtils.PackedMipChainInfo depthMipInfo, bool halfResolution = false, float historyValidity = 1.0f)
        {
            using (var builder = renderGraph.AddRenderPass <DenoiseSSGIPassData>("Denoise SSGI", out var passData, ProfilingSampler.Get(HDProfileId.SSGIDenoise)))
            {
                builder.EnableAsyncCompute(false);

                // Input buffers
                passData.depthTexture        = builder.ReadTexture(depthPyramid);
                passData.normalBuffer        = builder.ReadTexture(normalBuffer);
                passData.motionVectorsBuffer = builder.ReadTexture(motionVectorsBuffer);


                // History buffer
                bool     historyRequireClear     = false;
                RTHandle indirectDiffuseHistory0 = RequestIndirectDiffuseHistory0(hdCamera, out historyRequireClear);
                passData.indirectDiffuseHistory0 = builder.ReadWriteTexture(renderGraph.ImportTexture(indirectDiffuseHistory0));
                RTHandle indirectDiffuseHistory1 = RequestIndirectDiffuseHistory1(hdCamera, out historyRequireClear);
                passData.indirectDiffuseHistory1 = builder.ReadWriteTexture(renderGraph.ImportTexture(indirectDiffuseHistory1));
                var historyDepthBuffer = halfResolution ? hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.Depth1) : hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.Depth);
                passData.historyDepthBuffer = historyDepthBuffer != null?builder.ReadTexture(renderGraph.ImportTexture(historyDepthBuffer)) : renderGraph.defaultResources.blackTextureXR;

                passData.intermediateBuffer0 = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
                {
                    colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "SSGI Denoiser Intermediate0"
                });
                passData.intermediateBuffer1 = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
                {
                    colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "SSGI Denoiser Intermediate1"
                });
                passData.inputOutputBuffer0 = builder.ReadWriteTexture(inputOutputBuffer0);
                passData.inputOutputBuffer1 = builder.ReadWriteTexture(inputOutputBuffer1);

                passData.parameters = PrepareSSGIDenoiserParameters(hdCamera, halfResolution, historyValidity, historyRequireClear, depthMipInfo);

                builder.SetRenderFunc(
                    (DenoiseSSGIPassData data, RenderGraphContext ctx) =>
                {
                    // We need to fill the structure that holds the various resources
                    SSGIDenoiserResources resources   = new SSGIDenoiserResources();
                    resources.depthTexture            = data.depthTexture;
                    resources.normalBuffer            = data.normalBuffer;
                    resources.motionVectorsBuffer     = data.motionVectorsBuffer;
                    resources.indirectDiffuseHistory0 = data.indirectDiffuseHistory0;
                    resources.indirectDiffuseHistory1 = data.indirectDiffuseHistory1;
                    resources.historyDepthBuffer      = data.historyDepthBuffer;
                    resources.intermediateBuffer0     = data.intermediateBuffer0;
                    resources.intermediateBuffer1     = data.intermediateBuffer1;
                    resources.inputOutputBuffer0      = data.inputOutputBuffer0;
                    resources.inputOutputBuffer1      = data.inputOutputBuffer1;
                    Denoise(ctx.cmd, data.parameters, resources);
                });

                SSGIDenoiserOutput denoiserOutput = new SSGIDenoiserOutput();
                denoiserOutput.outputBuffer0 = inputOutputBuffer0;
                denoiserOutput.outputBuffer1 = inputOutputBuffer1;
                return(denoiserOutput);
            }
        }
Beispiel #2
0
        public SSGIDenoiserOutput Denoise(RenderGraph renderGraph, HDCamera hdCamera,
                                          TextureHandle depthPyramid, TextureHandle normalBuffer, TextureHandle motionVectorsBuffer, TextureHandle inputBuffer0, TextureHandle inputBuffer1,
                                          HDUtils.PackedMipChainInfo depthMipInfo, bool halfResolution = false, float historyValidity = 1.0f)
        {
            using (var builder = renderGraph.AddRenderPass <DenoiseSSGIPassData>("Denoise SSGI", out var passData, ProfilingSampler.Get(HDProfileId.SSGIDenoise)))
            {
                builder.EnableAsyncCompute(false);

                // Prepass buffers
                passData.depthTexture        = builder.ReadTexture(depthPyramid);
                passData.normalBuffer        = builder.ReadTexture(normalBuffer);
                passData.motionVectorsBuffer = builder.ReadTexture(motionVectorsBuffer);

                // History buffers
                bool     historyRequireClear     = false;
                RTHandle indirectDiffuseHistory0 = RequestIndirectDiffuseHistory0(hdCamera, out historyRequireClear);
                passData.indirectDiffuseHistory0 = builder.ReadWriteTexture(renderGraph.ImportTexture(indirectDiffuseHistory0));
                RTHandle indirectDiffuseHistory1 = RequestIndirectDiffuseHistory1(hdCamera, out historyRequireClear);
                passData.indirectDiffuseHistory1 = builder.ReadWriteTexture(renderGraph.ImportTexture(indirectDiffuseHistory1));
                var historyDepthBuffer = halfResolution ? hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.Depth1) : hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.Depth);
                passData.historyDepthBuffer = historyDepthBuffer != null?builder.ReadTexture(renderGraph.ImportTexture(historyDepthBuffer)) : renderGraph.defaultResources.blackTextureXR;

                // Input buffers
                passData.inputBuffer0 = builder.ReadTexture(inputBuffer0);
                passData.inputBuffer1 = builder.ReadTexture(inputBuffer1);

                // Output buffers
                passData.outputBuffer0 = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
                {
                    colorFormat = GraphicsFormat.B10G11R11_UFloatPack32, enableRandomWrite = true, name = "SSGI Denoised 0"
                }));
                passData.outputBuffer1 = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
                {
                    colorFormat = GraphicsFormat.R16G16_SFloat, enableRandomWrite = true, name = "SSGI Denoised 1"
                }));

                // Parameters
                var giSettings = hdCamera.volumeStack.GetComponent <UnityEngine.Rendering.HighDefinition.GlobalIllumination>();

                // Compute the dispatch parameters based on if we are half res or not
                int tileSize = 8;
                EvaluateDispatchParameters(hdCamera, halfResolution, tileSize, out passData.numTilesX, out passData.numTilesY, out passData.halfScreenSize);
                passData.firstMipOffset.Set(HDShadowUtils.Asfloat((uint)depthMipInfo.mipLevelOffsets[1].x), HDShadowUtils.Asfloat((uint)depthMipInfo.mipLevelOffsets[1].y));
                passData.historyValidity    = historyValidity;
                passData.viewCount          = hdCamera.viewCount;
                passData.pixelSpreadTangent = HDRenderPipeline.GetPixelSpreadTangent(hdCamera.camera.fieldOfView, hdCamera.actualWidth, hdCamera.actualHeight);

                // Denoising parameters
                passData.filterRadius      = giSettings.filterRadius;
                passData.halfResolution    = halfResolution;
                passData.historyValidity   = historyValidity;
                passData.historyNeedsClear = historyRequireClear;
                passData.exclusiveMode     = !hdCamera.frameSettings.IsEnabled(FrameSettingsField.ProbeVolume);

                // Compute shader
                passData.ssgiDenoiserCS = m_SSGIDenoiserCS;

                // Kernels
                passData.spatialFilterKernel  = halfResolution ? m_SpatialFilterHalfKernel : m_SpatialFilterKernel;
                passData.temporalFilterKernel = halfResolution ? m_TemporalFilterHalfKernel : m_TemporalFilterKernel;
                passData.copyHistory          = m_CopyHistory;

                builder.SetRenderFunc(
                    (DenoiseSSGIPassData data, RenderGraphContext ctx) =>
                {
                    int effectiveRadius = data.exclusiveMode ? data.filterRadius / 2 : data.filterRadius;
                    if (data.exclusiveMode)
                    {
                        // Horizontal Filter
                        SpatialFilter(ctx.cmd, data, effectiveRadius, new Vector2(1.0f, 0.0f), data.inputBuffer0, data.inputBuffer1, data.outputBuffer0, data.outputBuffer1);
                        // Vertical Filter
                        SpatialFilter(ctx.cmd, data, effectiveRadius, new Vector2(0.0f, 1.0f), data.outputBuffer0, data.outputBuffer1, data.inputBuffer0, data.inputBuffer1);
                    }

                    // Grab the history buffer
                    if (data.historyNeedsClear)
                    {
                        // clear it to black if this is the first pass to avoid nans
                        CoreUtils.SetRenderTarget(ctx.cmd, data.indirectDiffuseHistory0, ClearFlag.Color, Color.black);
                        CoreUtils.SetRenderTarget(ctx.cmd, data.indirectDiffuseHistory1, ClearFlag.Color, Color.black);
                    }

                    // Bind the input buffers
                    ctx.cmd.SetComputeTextureParam(data.ssgiDenoiserCS, data.temporalFilterKernel, HDShaderIDs._DepthTexture, data.depthTexture);
                    ctx.cmd.SetComputeTextureParam(data.ssgiDenoiserCS, data.temporalFilterKernel, HDShaderIDs._NormalBufferTexture, data.normalBuffer);
                    ctx.cmd.SetComputeTextureParam(data.ssgiDenoiserCS, data.temporalFilterKernel, HDShaderIDs._CameraMotionVectorsTexture, data.motionVectorsBuffer);
                    ctx.cmd.SetComputeFloatParam(data.ssgiDenoiserCS, HDShaderIDs._HistoryValidity, data.historyValidity);
                    if (data.halfResolution)
                    {
                        ctx.cmd.SetComputeTextureParam(data.ssgiDenoiserCS, data.temporalFilterKernel, HDShaderIDs._HistoryDepthTexture, data.historyDepthBuffer);
                        ctx.cmd.SetComputeVectorParam(data.ssgiDenoiserCS, HDShaderIDs._DepthPyramidFirstMipLevelOffset, data.firstMipOffset);
                    }
                    else
                    {
                        ctx.cmd.SetComputeTextureParam(data.ssgiDenoiserCS, data.temporalFilterKernel, HDShaderIDs._HistoryDepthTexture, data.historyDepthBuffer);
                    }
                    ctx.cmd.SetComputeTextureParam(data.ssgiDenoiserCS, data.temporalFilterKernel, HDShaderIDs._HistoryBuffer0, data.indirectDiffuseHistory0);
                    ctx.cmd.SetComputeTextureParam(data.ssgiDenoiserCS, data.temporalFilterKernel, HDShaderIDs._HistoryBuffer1, data.indirectDiffuseHistory1);
                    ctx.cmd.SetComputeTextureParam(data.ssgiDenoiserCS, data.temporalFilterKernel, HDShaderIDs._InputNoisyBuffer0, data.inputBuffer0);
                    ctx.cmd.SetComputeTextureParam(data.ssgiDenoiserCS, data.temporalFilterKernel, HDShaderIDs._InputNoisyBuffer1, data.inputBuffer1);

                    // Bind the output buffer
                    ctx.cmd.SetComputeTextureParam(data.ssgiDenoiserCS, data.temporalFilterKernel, HDShaderIDs._OutputFilteredBuffer0, data.outputBuffer0);
                    ctx.cmd.SetComputeTextureParam(data.ssgiDenoiserCS, data.temporalFilterKernel, HDShaderIDs._OutputFilteredBuffer1, data.outputBuffer1);

                    // Do the temporal pass
                    ctx.cmd.DispatchCompute(data.ssgiDenoiserCS, data.temporalFilterKernel, data.numTilesX, data.numTilesY, data.viewCount);

                    // Copy the new version into the history buffer
                    ctx.cmd.SetComputeTextureParam(data.ssgiDenoiserCS, data.copyHistory, HDShaderIDs._InputNoisyBuffer0, data.outputBuffer0);
                    ctx.cmd.SetComputeTextureParam(data.ssgiDenoiserCS, data.copyHistory, HDShaderIDs._InputNoisyBuffer1, data.outputBuffer1);
                    ctx.cmd.SetComputeTextureParam(data.ssgiDenoiserCS, data.copyHistory, HDShaderIDs._OutputFilteredBuffer0, data.indirectDiffuseHistory0);
                    ctx.cmd.SetComputeTextureParam(data.ssgiDenoiserCS, data.copyHistory, HDShaderIDs._OutputFilteredBuffer1, data.indirectDiffuseHistory1);
                    ctx.cmd.DispatchCompute(data.ssgiDenoiserCS, data.copyHistory, data.numTilesX, data.numTilesY, data.viewCount);

                    // Horizontal Filter
                    SpatialFilter(ctx.cmd, data, effectiveRadius, new Vector2(1.0f, 0.0f), data.outputBuffer0, data.outputBuffer1, data.inputBuffer0, data.inputBuffer1);
                    // Vertical Filter
                    SpatialFilter(ctx.cmd, data, effectiveRadius, new Vector2(0.0f, 1.0f), data.inputBuffer0, data.inputBuffer1, data.outputBuffer0, data.outputBuffer1);
                });

                SSGIDenoiserOutput denoiserOutput = new SSGIDenoiserOutput();
                denoiserOutput.outputBuffer0 = passData.outputBuffer0;
                denoiserOutput.outputBuffer1 = passData.outputBuffer1;
                return(denoiserOutput);
            }
        }