internal void InitializeForRendering(RenderGraph renderGraph)
        {
            blackTexture = renderGraph.ImportTexture(m_BlackTexture2D);
            whiteTexture = renderGraph.ImportTexture(m_WhiteTexture2D);

            clearTextureXR      = renderGraph.ImportTexture(TextureXR.GetClearTexture());
            magentaTextureXR    = renderGraph.ImportTexture(TextureXR.GetMagentaTexture());
            blackTextureXR      = renderGraph.ImportTexture(TextureXR.GetBlackTexture());
            blackTextureArrayXR = renderGraph.ImportTexture(TextureXR.GetBlackTextureArray());
            blackUIntTextureXR  = renderGraph.ImportTexture(TextureXR.GetBlackUIntTexture());
            blackTexture3DXR    = renderGraph.ImportTexture(TextureXR.GetBlackTexture3D());
            whiteTextureXR      = renderGraph.ImportTexture(TextureXR.GetWhiteTexture());
        }
        public override void BindBufferAsTextures(CommandBuffer cmd)
        {
            for (int i = 0; i < m_BufferCount; ++i)
            {
                cmd.SetGlobalTexture(m_TextureShaderIDs[i], m_RTs[i]);
            }

            // Bind alias for gbuffer usage to simplify shader code (not need to check which gbuffer is the shadowmask or lightlayers)
            if (m_ShadowMaskIndex >= 0)
            {
                cmd.SetGlobalTexture(HDShaderIDs._ShadowMaskTexture, m_RTs[m_ShadowMaskIndex]);
            }
            if (m_LightLayers >= 0)
            {
                cmd.SetGlobalTexture(HDShaderIDs._LightLayersTexture, m_RTs[m_LightLayers]);
            }
            else
            {
                cmd.SetGlobalTexture(HDShaderIDs._LightLayersTexture, TextureXR.GetWhiteTexture()); // This is never use but need to be bind as the read is inside a if
            }
        }
        public void Render(RenderGraph renderGraph,
                           HDCamera hdCamera,
                           BlueNoise blueNoise,
                           TextureHandle colorBuffer,
                           TextureHandle afterPostProcessTexture,
                           TextureHandle depthBuffer,
                           TextureHandle finalRT,
                           bool flipY)
        {
            var dynResHandler = DynamicResolutionHandler.instance;

            bool isSceneView = hdCamera.camera.cameraType == CameraType.SceneView;

            // TODO: Implement
            TextureHandle alphaTexture = new TextureHandle();
            //// Save the alpha and apply it back into the final pass if working in fp16
            //if (m_KeepAlpha)
            //{
            //    using (new ProfilingSample(cmd, "Alpha Copy", CustomSamplerId.AlphaCopy.GetSampler()))
            //    {
            //        DoCopyAlpha(cmd, hdCamera, colorBuffer);
            //    }
            //}

            var source = colorBuffer;

            //if (m_PostProcessEnabled)
            //{
            // Guard bands (also known as "horrible hack") to avoid bleeding previous RTHandle
            // content into smaller viewports with some effects like Bloom that rely on bilinear
            // filtering and can't use clamp sampler and the likes
            // Note: some platforms can't clear a partial render target so we directly draw black triangles
            //{
            //    int w = hdCamera.actualWidth;
            //    int h = hdCamera.actualHeight;
            //    cmd.SetRenderTarget(source, 0, CubemapFace.Unknown, -1);

            //    if (w < source.rt.width || h < source.rt.height)
            //    {
            //        cmd.SetViewport(new Rect(w, 0, k_RTGuardBandSize, h));
            //        cmd.DrawProcedural(Matrix4x4.identity, m_ClearBlackMaterial, 0, MeshTopology.Triangles, 3, 1);
            //        cmd.SetViewport(new Rect(0, h, w + k_RTGuardBandSize, k_RTGuardBandSize));
            //        cmd.DrawProcedural(Matrix4x4.identity, m_ClearBlackMaterial, 0, MeshTopology.Triangles, 3, 1);
            //    }
            //}

//                // Optional NaN killer before post-processing kicks in
//                bool stopNaNs = hdCamera.stopNaNs && m_StopNaNFS;

//#if UNITY_EDITOR
//                if (isSceneView)
//                    stopNaNs = HDRenderPipelinePreferences.sceneViewStopNaNs;
//#endif

//                if (stopNaNs)
//                {
//                    using (new ProfilingSample(cmd, "Stop NaNs", CustomSamplerId.StopNaNs.GetSampler()))
//                    {
//                        var destination = m_Pool.Get(Vector2.one, k_ColorFormat);
//                        DoStopNaNs(cmd, hdCamera, source, destination);
//                        PoolSource(ref source, destination);
//                    }
//                }
            //}

            //// Dynamic exposure - will be applied in the next frame
            //// Not considered as a post-process so it's not affected by its enabled state
            //if (!IsExposureFixed() && m_ExposureControlFS)
            //{
            //    using (new ProfilingSample(cmd, "Dynamic Exposure", CustomSamplerId.Exposure.GetSampler()))
            //    {
            //        DoDynamicExposure(cmd, hdCamera, source);
            //    }
            //}

            //if (m_PostProcessEnabled)
            //{
            //    // Temporal anti-aliasing goes first
            //    bool taaEnabled = false;

            //    if (m_AntialiasingFS)
            //    {
            //        taaEnabled = hdCamera.antialiasing == AntialiasingMode.TemporalAntialiasing;

            //        if (taaEnabled)
            //        {
            //            using (new ProfilingSample(cmd, "Temporal Anti-aliasing", CustomSamplerId.TemporalAntialiasing.GetSampler()))
            //            {
            //                var destination = m_Pool.Get(Vector2.one, k_ColorFormat);
            //                DoTemporalAntialiasing(cmd, hdCamera, source, destination, depthBuffer);
            //                PoolSource(ref source, destination);
            //            }
            //        }
            //        else if (hdCamera.antialiasing == AntialiasingMode.SubpixelMorphologicalAntiAliasing)
            //        {
            //            using (new ProfilingSample(cmd, "SMAA", CustomSamplerId.SMAA.GetSampler()))
            //            {
            //                var destination = m_Pool.Get(Vector2.one, k_ColorFormat);
            //                DoSMAA(cmd, hdCamera, source, destination, depthBuffer);
            //                PoolSource(ref source, destination);
            //            }
            //        }
            //    }

            //    if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.CustomPostProcess))
            //    {
            //        using (new ProfilingSample(cmd, "Custom Post Processes Before PP", CustomSamplerId.CustomPostProcessBeforePP.GetSampler()))
            //        {
            //            foreach (var typeString in HDRenderPipeline.currentAsset.beforePostProcessCustomPostProcesses)
            //                RenderCustomPostProcess(cmd, hdCamera, ref source, colorBuffer, Type.GetType(typeString));
            //        }
            //    }

            //    // Depth of Field is done right after TAA as it's easier to just re-project the CoC
            //    // map rather than having to deal with all the implications of doing it before TAA
            //    if (m_DepthOfField.IsActive() && !isSceneView && m_DepthOfFieldFS)
            //    {
            //        using (new ProfilingSample(cmd, "Depth of Field", CustomSamplerId.DepthOfField.GetSampler()))
            //        {
            //            var destination = m_Pool.Get(Vector2.one, k_ColorFormat);
            //            DoDepthOfField(cmd, hdCamera, source, destination, taaEnabled);
            //            PoolSource(ref source, destination);
            //        }
            //    }

            //    // Motion blur after depth of field for aesthetic reasons (better to see motion
            //    // blurred bokeh rather than out of focus motion blur)
            //    if (m_MotionBlur.IsActive() && m_AnimatedMaterialsEnabled && !m_ResetHistory && m_MotionBlurFS)
            //    {
            //        using (new ProfilingSample(cmd, "Motion Blur", CustomSamplerId.MotionBlur.GetSampler()))
            //        {
            //            var destination = m_Pool.Get(Vector2.one, k_ColorFormat);
            //            DoMotionBlur(cmd, hdCamera, source, destination);
            //            PoolSource(ref source, destination);
            //        }
            //    }

            //    // Panini projection is done as a fullscreen pass after all depth-based effects are
            //    // done and before bloom kicks in
            //    // This is one effect that would benefit from an overscan mode or supersampling in
            //    // HDRP to reduce the amount of resolution lost at the center of the screen
            //    if (m_PaniniProjection.IsActive() && !isSceneView && m_PaniniProjectionFS)
            //    {
            //        using (new ProfilingSample(cmd, "Panini Projection", CustomSamplerId.PaniniProjection.GetSampler()))
            //        {
            //            var destination = m_Pool.Get(Vector2.one, k_ColorFormat);
            //            DoPaniniProjection(cmd, hdCamera, source, destination);
            //            PoolSource(ref source, destination);
            //        }
            //    }

            //    // Combined post-processing stack - always runs if postfx is enabled
            //    using (new ProfilingSample(cmd, "Uber", CustomSamplerId.UberPost.GetSampler()))
            //    {
            //        // Feature flags are passed to all effects and it's their responsibility to check
            //        // if they are used or not so they can set default values if needed
            //        var cs = m_Resources.shaders.uberPostCS;
            //        var featureFlags = GetUberFeatureFlags(isSceneView);
            //        int kernel = GetUberKernel(cs, featureFlags);

            //        // Generate the bloom texture
            //        bool bloomActive = m_Bloom.IsActive() && m_BloomFS;

            //        if (bloomActive)
            //        {
            //            using (new ProfilingSample(cmd, "Bloom", CustomSamplerId.Bloom.GetSampler()))
            //            {
            //                DoBloom(cmd, hdCamera, source, cs, kernel);
            //            }
            //        }
            //        else
            //        {
            //            cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._BloomTexture, TextureXR.GetBlackTexture());
            //            cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._BloomDirtTexture, Texture2D.blackTexture);
            //            cmd.SetComputeVectorParam(cs, HDShaderIDs._BloomParams, Vector4.zero);
            //        }

            //        // Build the color grading lut
            //        using (new ProfilingSample(cmd, "Color Grading LUT Builder", CustomSamplerId.ColorGradingLUTBuilder.GetSampler()))
            //        {
            //            DoColorGrading(cmd, cs, kernel);
            //        }

            //        // Setup the rest of the effects
            //        DoLensDistortion(cmd, cs, kernel, featureFlags);
            //        DoChromaticAberration(cmd, cs, kernel, featureFlags);
            //        DoVignette(cmd, cs, kernel, featureFlags);

            //        // Run
            //        var destination = m_Pool.Get(Vector2.one, k_ColorFormat);

            //        bool outputColorLog = m_HDInstance.m_CurrentDebugDisplaySettings.data.fullScreenDebugMode == FullScreenDebugMode.ColorLog;
            //        cmd.SetComputeVectorParam(cs, "_DebugFlags", new Vector4(outputColorLog ? 1 : 0, 0, 0, 0));
            //        cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._InputTexture, source);
            //        cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._OutputTexture, destination);
            //        cmd.DispatchCompute(cs, kernel, (hdCamera.actualWidth + 7) / 8, (hdCamera.actualHeight + 7) / 8, hdCamera.viewCount);
            //        m_HDInstance.PushFullScreenDebugTexture(hdCamera, cmd, destination, FullScreenDebugMode.ColorLog);

            //        // Cleanup
            //        if (bloomActive) m_Pool.Recycle(m_BloomTexture);
            //        m_BloomTexture = null;

            //        PoolSource(ref source, destination);
            //    }

            //    if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.CustomPostProcess))
            //    {
            //        using (new ProfilingSample(cmd, "Custom Post Processes After PP", CustomSamplerId.CustomPostProcessAfterPP.GetSampler()))
            //        {
            //            foreach (var typeString in HDRenderPipeline.currentAsset.afterPostProcessCustomPostProcesses)
            //                RenderCustomPostProcess(cmd, hdCamera, ref source, colorBuffer, Type.GetType(typeString));
            //        }
            //    }
            //}

            //if (dynResHandler.DynamicResolutionEnabled() &&     // Dynamic resolution is on.
            //    hdCamera.antialiasing == AntialiasingMode.FastApproximateAntialiasing &&
            //    m_AntialiasingFS)
            //{
            //    using (new ProfilingSample(cmd, "FXAA", CustomSamplerId.FXAA.GetSampler()))
            //    {
            //        var destination = m_Pool.Get(Vector2.one, k_ColorFormat);
            //        DoFXAA(cmd, hdCamera, source, destination);
            //        PoolSource(ref source, destination);
            //    }
            //}

            using (var builder = renderGraph.AddRenderPass <FinalPassData>("Final Pass", out var passData, ProfilingSampler.Get(HDProfileId.FinalPost)))
            {
                passData.parameters = PrepareFinalPass(hdCamera, blueNoise, flipY);
                passData.source     = builder.ReadTexture(source);
                passData.afterPostProcessTexture = builder.ReadTexture(afterPostProcessTexture);
                passData.alphaTexture            = builder.ReadTexture(m_KeepAlpha ? alphaTexture : renderGraph.ImportTexture(TextureXR.GetWhiteTexture()));
                passData.destination             = builder.WriteTexture(finalRT);

                builder.SetRenderFunc(
                    (FinalPassData data, RenderGraphContext ctx) =>
                {
                    DoFinalPass(data.parameters,
                                ctx.resources.GetTexture(data.source),
                                ctx.resources.GetTexture(data.afterPostProcessTexture),
                                ctx.resources.GetTexture(data.destination),
                                ctx.resources.GetTexture(data.alphaTexture),
                                ctx.cmd);
                });
            }
        }
        public void RenderRaytracingDeferredLighting(CommandBuffer cmd, HDCamera hdCamera, HDRaytracingEnvironment rtEnvironment,
                                                     RTHandle directionBuffer, bool rayBinning, LayerMask layerMask, float maxRayLength, RTHandle outputBuffer, bool disableSpecularLighting = false, bool halfResolution = false)
        {
            ComputeShader    rayBinningCS         = m_Asset.renderPipelineRayTracingResources.rayBinningCS;
            RayTracingShader gBufferRaytracingRT  = m_Asset.renderPipelineRayTracingResources.gBufferRaytracingRT;
            ComputeShader    deferredRaytracingCS = m_Asset.renderPipelineRayTracingResources.deferredRaytracingCS;

            // Texture dimensions
            int texWidth  = hdCamera.actualWidth;
            int texHeight = hdCamera.actualHeight;

            if (halfResolution)
            {
                texWidth  /= 2;
                texHeight /= 2;
            }
            // Evaluate the dispatch parameters
            int rayTileSize     = 16;
            int numTilesRayBinX = (texWidth + (rayTileSize - 1)) / rayTileSize;
            int numTilesRayBinY = (texHeight + (rayTileSize - 1)) / rayTileSize;

            int bufferSizeX = numTilesRayBinX * rayTileSize;
            int bufferSizeY = numTilesRayBinY * rayTileSize;

            int currentKernel = 0;

            if (rayBinning)
            {
                // We need to go through the ray binning pass (if required)
                currentKernel = rayBinningCS.FindKernel(halfResolution? "RayBinningHalf" : "RayBinning");

                if (bufferSizeX * bufferSizeY > m_RayBinResult.count)
                {
                    if (m_RayBinResult != null)
                    {
                        CoreUtils.SafeRelease(m_RayBinResult);
                        CoreUtils.SafeRelease(m_RayBinSizeResult);
                        m_RayBinResult     = null;
                        m_RayBinSizeResult = null;
                    }

                    if (bufferSizeX * bufferSizeY > 0)
                    {
                        m_RayBinResult     = new ComputeBuffer(bufferSizeX * bufferSizeY, sizeof(uint));
                        m_RayBinSizeResult = new ComputeBuffer(numTilesRayBinX * numTilesRayBinY, sizeof(uint));
                    }
                }

                cmd.SetComputeTextureParam(rayBinningCS, currentKernel, HDShaderIDs._RaytracingDirectionBuffer, directionBuffer);
                cmd.SetComputeBufferParam(rayBinningCS, currentKernel, HDShaderIDs._RayBinResult, m_RayBinResult);
                cmd.SetComputeBufferParam(rayBinningCS, currentKernel, HDShaderIDs._RayBinSizeResult, m_RayBinSizeResult);
                cmd.SetComputeIntParam(rayBinningCS, HDShaderIDs._RayBinTileCountX, numTilesRayBinX);
                cmd.DispatchCompute(rayBinningCS, currentKernel, numTilesRayBinX, numTilesRayBinY, 1);
            }

            // Define the shader pass to use for the reflection pass
            cmd.SetRayTracingShaderPass(gBufferRaytracingRT, "GBufferDXR");

            if (rayBinning)
            {
                cmd.SetGlobalBuffer(HDShaderIDs._RayBinResult, m_RayBinResult);
                cmd.SetGlobalBuffer(HDShaderIDs._RayBinSizeResult, m_RayBinSizeResult);
                cmd.SetRayTracingIntParam(gBufferRaytracingRT, HDShaderIDs._RayBinTileCountX, numTilesRayBinX);
            }

            // Grab the acceleration structures and the light cluster to use
            RayTracingAccelerationStructure accelerationStructure = m_RayTracingManager.RequestAccelerationStructure(layerMask);
            HDRaytracingLightCluster        lightCluster          = m_RayTracingManager.RequestLightCluster(layerMask);

            // Set the acceleration structure for the pass
            cmd.SetRayTracingAccelerationStructure(gBufferRaytracingRT, HDShaderIDs._RaytracingAccelerationStructureName, accelerationStructure);

            // Bind the textures required for the ray launching
            cmd.SetRayTracingTextureParam(gBufferRaytracingRT, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
            cmd.SetRayTracingTextureParam(gBufferRaytracingRT, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer());
            cmd.SetRayTracingTextureParam(gBufferRaytracingRT, HDShaderIDs._RaytracingDirectionBuffer, directionBuffer);

            // Compute the pixel spread value
            float pixelSpreadAngle = hdCamera.camera.fieldOfView * (Mathf.PI / 180.0f) / Mathf.Min(hdCamera.actualWidth, hdCamera.actualHeight);

            cmd.SetGlobalFloat(HDShaderIDs._RaytracingPixelSpreadAngle, pixelSpreadAngle);

            // Additional ray launch values
            cmd.SetRayTracingFloatParams(gBufferRaytracingRT, HDShaderIDs._RaytracingRayBias, rtEnvironment.rayBias);
            cmd.SetRayTracingFloatParams(gBufferRaytracingRT, HDShaderIDs._RaytracingRayMaxLength, maxRayLength);

            // Bind the output textures
            cmd.SetRayTracingTextureParam(gBufferRaytracingRT, HDShaderIDs._GBufferTextureRW[0], m_RaytracingGBufferManager.GetBuffer(0));
            cmd.SetRayTracingTextureParam(gBufferRaytracingRT, HDShaderIDs._GBufferTextureRW[1], m_RaytracingGBufferManager.GetBuffer(1));
            cmd.SetRayTracingTextureParam(gBufferRaytracingRT, HDShaderIDs._GBufferTextureRW[2], m_RaytracingGBufferManager.GetBuffer(2));
            cmd.SetRayTracingTextureParam(gBufferRaytracingRT, HDShaderIDs._GBufferTextureRW[3], m_RaytracingGBufferManager.GetBuffer(3));
            // cmd.SetRaytracingTextureParam(gBufferRaytracingRT, rayGenGBuffer, HDShaderIDs._GBufferTextureRW[4], m_LocalGBufferManager.GetBuffer(4));
            // cmd.SetRaytracingTextureParam(gBufferRaytracingRT, rayGenGBuffer, HDShaderIDs._GBufferTextureRW[5], m_LocalGBufferManager.GetBuffer(5));
            cmd.SetRayTracingTextureParam(gBufferRaytracingRT, HDShaderIDs._RaytracingDistanceBuffer, m_RaytracingDistanceBuffer);

            // Compute the actual resolution that is needed base on the quality
            uint widthResolution  = (uint)hdCamera.actualWidth;
            uint heightResolution = (uint)hdCamera.actualHeight;

            if (disableSpecularLighting)
            {
                cmd.SetGlobalInt(HDShaderIDs._EnableSpecularLighting, 0);
            }

            if (rayBinning)
            {
                cmd.DispatchRays(gBufferRaytracingRT, m_RayGenGBufferBinned, (uint)bufferSizeX, (uint)bufferSizeY, 1);
            }
            else
            {
                cmd.SetRayTracingIntParams(gBufferRaytracingRT, "_RaytracingHalfResolution", halfResolution? 1 : 0);
                cmd.DispatchRays(gBufferRaytracingRT, m_RayGenGBuffer, widthResolution, heightResolution, 1);
            }

            // Now let's do the deferred shading pass on the samples
            currentKernel = deferredRaytracingCS.FindKernel(halfResolution ? "RaytracingDeferredHalf" : "RaytracingDeferred");

            LightCluster lightClusterSettings = VolumeManager.instance.stack.GetComponent <LightCluster>();

            cmd.SetComputeBufferParam(deferredRaytracingCS, currentKernel, HDShaderIDs._RaytracingLightCluster, lightCluster.GetCluster());
            cmd.SetComputeBufferParam(deferredRaytracingCS, currentKernel, HDShaderIDs._LightDatasRT, lightCluster.GetLightDatas());
            cmd.SetComputeVectorParam(deferredRaytracingCS, HDShaderIDs._MinClusterPos, lightCluster.GetMinClusterPos());
            cmd.SetComputeVectorParam(deferredRaytracingCS, HDShaderIDs._MaxClusterPos, lightCluster.GetMaxClusterPos());
            cmd.SetComputeIntParam(deferredRaytracingCS, HDShaderIDs._LightPerCellCount, lightClusterSettings.maxNumLightsPercell.value);
            cmd.SetComputeIntParam(deferredRaytracingCS, HDShaderIDs._PunctualLightCountRT, lightCluster.GetPunctualLightCount());
            cmd.SetComputeIntParam(deferredRaytracingCS, HDShaderIDs._AreaLightCountRT, lightCluster.GetAreaLightCount());

            cmd.SetComputeTextureParam(deferredRaytracingCS, currentKernel, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());

            cmd.SetComputeTextureParam(deferredRaytracingCS, currentKernel, HDShaderIDs._RaytracingDirectionBuffer, directionBuffer);
            cmd.SetComputeTextureParam(deferredRaytracingCS, currentKernel, HDShaderIDs._RaytracingDistanceBuffer, m_RaytracingDistanceBuffer);

            cmd.SetComputeTextureParam(deferredRaytracingCS, currentKernel, HDShaderIDs._GBufferTexture[0], m_RaytracingGBufferManager.GetBuffer(0));
            cmd.SetComputeTextureParam(deferredRaytracingCS, currentKernel, HDShaderIDs._GBufferTexture[1], m_RaytracingGBufferManager.GetBuffer(1));
            cmd.SetComputeTextureParam(deferredRaytracingCS, currentKernel, HDShaderIDs._GBufferTexture[2], m_RaytracingGBufferManager.GetBuffer(2));
            cmd.SetComputeTextureParam(deferredRaytracingCS, currentKernel, HDShaderIDs._GBufferTexture[3], m_RaytracingGBufferManager.GetBuffer(3));
            cmd.SetComputeTextureParam(deferredRaytracingCS, currentKernel, HDShaderIDs._LightLayersTexture, TextureXR.GetWhiteTexture());
            cmd.SetComputeTextureParam(deferredRaytracingCS, currentKernel, HDShaderIDs._RaytracingLitBufferRW, outputBuffer);

            // Evaluate the dispatch parameters
            int areaTileSize = 8;
            int numTilesXHR  = (texWidth + (areaTileSize - 1)) / areaTileSize;
            int numTilesYHR  = (texHeight + (areaTileSize - 1)) / areaTileSize;

            // Compute the texture
            cmd.DispatchCompute(deferredRaytracingCS, currentKernel, numTilesXHR, numTilesYHR, 1);

            if (disableSpecularLighting)
            {
                cmd.SetGlobalInt(HDShaderIDs._EnableSpecularLighting, hdCamera.frameSettings.IsEnabled(FrameSettingsField.SpecularLighting) ? 1 : 0);
            }
        }