Пример #1
0
        public void RenderReflectionsT1(HDCamera hdCamera, CommandBuffer cmd, RTHandleSystem.RTHandle outputTexture, ScriptableRenderContext renderContext, int frameCount)
        {
            // First thing to check is: Do we have a valid ray-tracing environment?
            HDRaytracingEnvironment rtEnvironment  = m_RaytracingManager.CurrentEnvironment();
            HDRenderPipeline        renderPipeline = m_RaytracingManager.GetRenderPipeline();
            BlueNoise        blueNoise             = m_RaytracingManager.GetBlueNoiseManager();
            ComputeShader    reflectionFilter      = m_PipelineAsset.renderPipelineRayTracingResources.reflectionBilateralFilterCS;
            RayTracingShader reflectionShader      = m_PipelineAsset.renderPipelineRayTracingResources.reflectionRaytracing;

            bool invalidState = rtEnvironment == null || blueNoise == null ||
                                reflectionFilter == null || reflectionShader == null ||
                                m_PipelineResources.textures.owenScrambledTex == null || m_PipelineResources.textures.scramblingTex == null;

            // If no acceleration structure available, end it now
            if (invalidState)
            {
                return;
            }

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

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

            // Compute the actual resolution that is needed base on the quality
            string targetRayGen = m_RayGenHalfResName;

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

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

            // Inject the ray-tracing sampling data
            cmd.SetRayTracingTextureParam(reflectionShader, HDShaderIDs._OwenScrambledTexture, m_PipelineResources.textures.owenScrambledTex);
            cmd.SetRayTracingTextureParam(reflectionShader, HDShaderIDs._ScramblingTexture, m_PipelineResources.textures.scramblingTex);

            // Global reflection parameters
            cmd.SetRayTracingFloatParams(reflectionShader, HDShaderIDs._RaytracingIntensityClamp, settings.clampValue.value);
            cmd.SetRayTracingFloatParams(reflectionShader, HDShaderIDs._RaytracingReflectionMinSmoothness, settings.minSmoothness.value);
            cmd.SetRayTracingIntParams(reflectionShader, HDShaderIDs._RaytracingReflectSky, settings.reflectSky.value ? 1 : 0);

            // Inject the ray generation data
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayBias, rtEnvironment.rayBias);
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayMaxLength, settings.rayLength.value);
            cmd.SetRayTracingIntParams(reflectionShader, HDShaderIDs._RaytracingNumSamples, settings.numSamples.value);
            int frameIndex = hdCamera.IsTAAEnabled() ? hdCamera.taaFrameIndex : (int)frameCount % 8;

            cmd.SetGlobalInt(HDShaderIDs._RaytracingFrameIndex, frameIndex);

            // Set the data for the ray generation
            cmd.SetRayTracingTextureParam(reflectionShader, HDShaderIDs._SsrLightingTextureRW, m_LightingTexture);
            cmd.SetRayTracingTextureParam(reflectionShader, HDShaderIDs._SsrHitPointTexture, m_HitPdfTexture);
            cmd.SetRayTracingTextureParam(reflectionShader, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
            cmd.SetRayTracingTextureParam(reflectionShader, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer());

            // Set ray count tex
            cmd.SetRayTracingIntParam(reflectionShader, HDShaderIDs._RayCountEnabled, m_RaytracingManager.rayCountManager.RayCountIsEnabled());
            cmd.SetRayTracingTextureParam(reflectionShader, HDShaderIDs._RayCountTexture, m_RaytracingManager.rayCountManager.rayCountTexture);

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

            cmd.SetRayTracingFloatParam(reflectionShader, HDShaderIDs._RaytracingPixelSpreadAngle, pixelSpreadAngle);

            // LightLoop data
            cmd.SetGlobalBuffer(HDShaderIDs._RaytracingLightCluster, lightCluster.GetCluster());
            cmd.SetGlobalBuffer(HDShaderIDs._LightDatasRT, lightCluster.GetLightDatas());
            cmd.SetGlobalVector(HDShaderIDs._MinClusterPos, lightCluster.GetMinClusterPos());
            cmd.SetGlobalVector(HDShaderIDs._MaxClusterPos, lightCluster.GetMaxClusterPos());
            cmd.SetGlobalInt(HDShaderIDs._LightPerCellCount, lightClusterSettings.maxNumLightsPercell.value);
            cmd.SetGlobalInt(HDShaderIDs._PunctualLightCountRT, lightCluster.GetPunctualLightCount());
            cmd.SetGlobalInt(HDShaderIDs._AreaLightCountRT, lightCluster.GetAreaLightCount());

            // Note: Just in case, we rebind the directional light data (in case they were not)
            cmd.SetGlobalBuffer(HDShaderIDs._DirectionalLightDatas, renderPipeline.m_LightLoopLightData.directionalLightData);
            cmd.SetGlobalInt(HDShaderIDs._DirectionalLightCount, renderPipeline.m_lightList.directionalLights.Count);

            // Evaluate the clear coat mask texture based on the lit shader mode
            RenderTargetIdentifier clearCoatMaskTexture = hdCamera.frameSettings.litShaderMode == LitShaderMode.Deferred ? m_GbufferManager.GetBuffersRTI()[2] : TextureXR.GetBlackTexture();

            cmd.SetRayTracingTextureParam(reflectionShader, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMaskTexture);

            // Set the data for the ray miss
            cmd.SetRayTracingTextureParam(reflectionShader, HDShaderIDs._SkyTexture, m_SkyManager.skyReflection);

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

            // Force to disable specular lighting
            cmd.SetGlobalInt(HDShaderIDs._EnableSpecularLighting, 0);

            // Run the computation
            cmd.DispatchRays(reflectionShader, targetRayGen, widthResolution, heightResolution, 1);

            // Restore the previous state of specular lighting
            cmd.SetGlobalInt(HDShaderIDs._EnableSpecularLighting, hdCamera.frameSettings.IsEnabled(FrameSettingsField.SpecularLighting) ? 1 : 0);

            using (new ProfilingSample(cmd, "Filter Reflection", CustomSamplerId.RaytracingFilterReflection.GetSampler()))
            {
                // Fetch the right filter to use
                int currentKernel = reflectionFilter.FindKernel("RaytracingReflectionFilter");

                // Inject all the parameters for the compute
                cmd.SetComputeTextureParam(reflectionFilter, currentKernel, HDShaderIDs._SsrLightingTextureRW, m_LightingTexture);
                cmd.SetComputeTextureParam(reflectionFilter, currentKernel, HDShaderIDs._SsrHitPointTexture, m_HitPdfTexture);
                cmd.SetComputeTextureParam(reflectionFilter, currentKernel, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
                cmd.SetComputeTextureParam(reflectionFilter, currentKernel, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer());
                cmd.SetComputeTextureParam(reflectionFilter, currentKernel, "_NoiseTexture", blueNoise.textureArray16RGB);
                cmd.SetComputeTextureParam(reflectionFilter, currentKernel, "_VarianceTexture", m_VarianceBuffer);
                cmd.SetComputeTextureParam(reflectionFilter, currentKernel, "_MinColorRangeTexture", m_MinBoundBuffer);
                cmd.SetComputeTextureParam(reflectionFilter, currentKernel, "_MaxColorRangeTexture", m_MaxBoundBuffer);
                cmd.SetComputeTextureParam(reflectionFilter, currentKernel, "_RaytracingReflectionTexture", outputTexture);
                cmd.SetComputeTextureParam(reflectionFilter, currentKernel, HDShaderIDs._ScramblingTexture, m_PipelineResources.textures.scramblingTex);
                cmd.SetComputeIntParam(reflectionFilter, HDShaderIDs._SpatialFilterRadius, settings.spatialFilterRadius.value);
                cmd.SetComputeFloatParam(reflectionFilter, HDShaderIDs._RaytracingReflectionMinSmoothness, settings.minSmoothness.value);

                // Texture dimensions
                int texWidth  = outputTexture.rt.width;
                int texHeight = outputTexture.rt.height;

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

                // Bind the right texture for clear coat support
                cmd.SetComputeTextureParam(reflectionFilter, currentKernel, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMaskTexture);

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

                int numTilesXFR = (texWidth + (areaTileSize - 1)) / areaTileSize;
                int numTilesYFR = (texHeight + (areaTileSize - 1)) / areaTileSize;

                RTHandleSystem.RTHandle history = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedReflection)
                                                  ?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedReflection, ReflectionHistoryBufferAllocatorFunction, 1);

                // Fetch the right filter to use
                currentKernel = reflectionFilter.FindKernel("TemporalAccumulationFilter");
                cmd.SetComputeFloatParam(reflectionFilter, HDShaderIDs._TemporalAccumuationWeight, settings.temporalAccumulationWeight.value);
                cmd.SetComputeTextureParam(reflectionFilter, currentKernel, HDShaderIDs._AccumulatedFrameTexture, history);
                cmd.SetComputeTextureParam(reflectionFilter, currentKernel, HDShaderIDs._CurrentFrameTexture, outputTexture);
                cmd.SetComputeTextureParam(reflectionFilter, currentKernel, "_MinColorRangeTexture", m_MinBoundBuffer);
                cmd.SetComputeTextureParam(reflectionFilter, currentKernel, "_MaxColorRangeTexture", m_MaxBoundBuffer);
                cmd.DispatchCompute(reflectionFilter, currentKernel, numTilesXFR, numTilesYFR, 1);
            }
        }
Пример #2
0
        void RenderDirectionalLightScreenSpaceShadow(CommandBuffer cmd, HDCamera hdCamera)
        {
            // Render directional screen space shadow if required
            if (m_CurrentSunLightAdditionalLightData != null && m_CurrentSunLightAdditionalLightData.WillRenderScreenSpaceShadow())
            {
#if ENABLE_RAYTRACING
                // Grab the ray tracing environment
                HDRaytracingEnvironment rtEnvironment = m_RayTracingManager.CurrentEnvironment();

                // If the shadow is flagged as ray traced, we need to evaluate it completely
                if (rtEnvironment != null && hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) &&
                    m_CurrentSunLightAdditionalLightData.WillRenderRayTracedShadow())
                {
                    // Texture dimensions
                    int texWidth  = hdCamera.actualWidth;
                    int texHeight = hdCamera.actualHeight;

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

                    // Clear the integration texture
                    cmd.SetComputeTextureParam(m_ScreenSpaceShadowsCS, m_ClearShadowTexture, HDShaderIDs._RaytracedDirectionalShadowIntegration, m_ShadowIntermediateBufferRGBA0);
                    cmd.DispatchCompute(m_ScreenSpaceShadowsCS, m_ClearShadowTexture, numTilesX, numTilesY, 1);

                    // Grab and bind the acceleration structure for the target camera
                    RayTracingAccelerationStructure accelerationStructure = m_RayTracingManager.RequestAccelerationStructure(rtEnvironment.shadowLayerMask);
                    cmd.SetRayTracingAccelerationStructure(m_ScreenSpaceShadowsRT, HDShaderIDs._RaytracingAccelerationStructureName, accelerationStructure);

                    // Inject the ray-tracing sampling data
                    m_BlueNoise.BindDitheredRNGData8SPP(cmd);

                    // Compute the current frame index
                    int frameIndex = hdCamera.IsTAAEnabled() ? hdCamera.taaFrameIndex : (int)m_FrameCount % 8;
                    cmd.SetComputeIntParam(m_ScreenSpaceShadowsCS, HDShaderIDs._RaytracingFrameIndex, frameIndex);

                    // Inject the ray generation data
                    cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayBias, rtEnvironment.rayBias);

                    // Loop through the samples of this frame
                    for (int sampleIdx = 0; sampleIdx < m_CurrentSunLightAdditionalLightData.numRayTracingSamples; ++sampleIdx)
                    {
                        // Bind the light & sampling data
                        cmd.SetComputeBufferParam(m_ScreenSpaceShadowsCS, m_RaytracingDirectionalShadowSample, HDShaderIDs._DirectionalLightDatas, m_LightLoopLightData.directionalLightData);
                        cmd.SetComputeIntParam(m_ScreenSpaceShadowsCS, HDShaderIDs._DirectionalShadowIndex, m_CurrentShadowSortedSunLightIndex);
                        cmd.SetComputeFloatParam(m_ScreenSpaceShadowsCS, HDShaderIDs._DirectionalLightAngle, m_CurrentSunLightAdditionalLightData.sunLightConeAngle);
                        cmd.SetComputeIntParam(m_ScreenSpaceShadowsCS, HDShaderIDs._RaytracingSampleIndex, sampleIdx);
                        cmd.SetComputeIntParam(m_ScreenSpaceShadowsCS, HDShaderIDs._RaytracingNumSamples, m_CurrentSunLightAdditionalLightData.numRayTracingSamples);

                        // Input Buffer
                        cmd.SetComputeTextureParam(m_ScreenSpaceShadowsCS, m_RaytracingDirectionalShadowSample, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
                        cmd.SetComputeTextureParam(m_ScreenSpaceShadowsCS, m_RaytracingDirectionalShadowSample, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer());

                        // Output buffer
                        cmd.SetComputeTextureParam(m_ScreenSpaceShadowsCS, m_RaytracingDirectionalShadowSample, HDShaderIDs._RaytracingDirectionBuffer, m_RaytracingDirectionBuffer);

                        // Generate a new direction
                        cmd.DispatchCompute(m_ScreenSpaceShadowsCS, m_RaytracingDirectionalShadowSample, numTilesX, numTilesY, 1);

                        // Define the shader pass to use for the shadow pass
                        cmd.SetRayTracingShaderPass(m_ScreenSpaceShadowsRT, "VisibilityDXR");

                        // Set ray count texture
                        cmd.SetRayTracingIntParam(m_ScreenSpaceShadowsRT, HDShaderIDs._RayCountEnabled, m_RayTracingManager.rayCountManager.RayCountIsEnabled());
                        cmd.SetRayTracingTextureParam(m_ScreenSpaceShadowsRT, HDShaderIDs._RayCountTexture, m_RayTracingManager.rayCountManager.GetRayCountTexture());

                        // Input buffers
                        cmd.SetRayTracingTextureParam(m_ScreenSpaceShadowsRT, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
                        cmd.SetRayTracingTextureParam(m_ScreenSpaceShadowsRT, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer());
                        cmd.SetRayTracingTextureParam(m_ScreenSpaceShadowsRT, HDShaderIDs._RaytracingDirectionBuffer, m_RaytracingDirectionBuffer);
                        cmd.SetRayTracingIntParam(m_ScreenSpaceShadowsRT, HDShaderIDs._RaytracingNumSamples, m_CurrentSunLightAdditionalLightData.numRayTracingSamples);

                        // Output buffer
                        cmd.SetRayTracingTextureParam(m_ScreenSpaceShadowsRT, HDShaderIDs._RaytracedDirectionalShadowIntegration, m_ShadowIntermediateBufferRGBA0);

                        // Evaluate the visibility
                        cmd.DispatchRays(m_ScreenSpaceShadowsRT, m_RayGenDirectionalShadowSingleName, (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, 1);
                    }

                    // Grab the history buffer for shadows
                    RTHandle shadowHistoryArray = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedShadow)
                                                  ?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedShadow, ShadowHistoryBufferAllocatorFunction, 1);

                    // Apply the simple denoiser (if required)
                    if (m_CurrentSunLightAdditionalLightData.filterTracedShadow)
                    {
                        // Apply the temporal denoiser
                        HDTemporalFilter temporalFilter = m_RayTracingManager.GetTemporalFilter();
                        temporalFilter.DenoiseBuffer(cmd, hdCamera, m_ShadowIntermediateBufferRGBA0, shadowHistoryArray, m_ShadowIntermediateBufferRGBA1, singleChannel: true, slotIndex: m_CurrentSunLightDirectionalLightData.screenSpaceShadowIndex);

                        // Apply the spatial denoiser
                        HDSimpleDenoiser simpleDenoiser = m_RayTracingManager.GetSimpleDenoiser();
                        simpleDenoiser.DenoiseBufferNoHistory(cmd, hdCamera, m_ShadowIntermediateBufferRGBA1, m_ShadowIntermediateBufferRGBA0, m_CurrentSunLightAdditionalLightData.filterSizeTraced, singleChannel: true);
                    }

                    cmd.SetComputeTextureParam(m_ScreenSpaceShadowsCS, m_OutputShadowTextureKernel, HDShaderIDs._RaytracedDirectionalShadowIntegration, m_ShadowIntermediateBufferRGBA0);
                    cmd.SetComputeTextureParam(m_ScreenSpaceShadowsCS, m_OutputShadowTextureKernel, HDShaderIDs._ScreenSpaceShadowsTextureRW, m_ScreenSpaceShadowTextureArray);
                    cmd.SetComputeIntParam(m_ScreenSpaceShadowsCS, HDShaderIDs._RaytracingShadowSlot, m_CurrentSunLightDirectionalLightData.screenSpaceShadowIndex);
                    cmd.DispatchCompute(m_ScreenSpaceShadowsCS, m_OutputShadowTextureKernel, numTilesX, numTilesY, 1);
                }
                else
#endif
                {
                    // If it is screen space but not ray traced, then we can rely on the shadow map
                    CoreUtils.SetRenderTarget(cmd, m_ScreenSpaceShadowTextureArray, depthSlice: m_CurrentSunLightDirectionalLightData.screenSpaceShadowIndex);
                    HDUtils.DrawFullScreen(cmd, s_ScreenSpaceShadowsMat, m_ScreenSpaceShadowTextureArray);
                }
            }
        }
Пример #3
0
        bool RenderLightScreenSpaceShadows(HDCamera hdCamera, CommandBuffer cmd)
        {
            // Fetch the ray tracing environment
            HDRaytracingEnvironment rtEnvironment = m_RayTracingManager.CurrentEnvironment();

            // If invalid state, we stop right away
            if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) || rtEnvironment == null)
            {
                return(false);
            }

            // Grab the history buffer
            RTHandle shadowHistoryArray = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedShadow)
                                          ?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedShadow, ShadowHistoryBufferAllocatorFunction, 1);

            // Grab the acceleration structure for the target camera
            RayTracingAccelerationStructure accelerationStructure = m_RayTracingManager.RequestAccelerationStructure(rtEnvironment.shadowLayerMask);

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

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

            // Inject the ray-tracing sampling data
            m_BlueNoise.BindDitheredRNGData8SPP(cmd);

            // Compute and inject the frame data
            int frameIndex = hdCamera.IsTAAEnabled() ? hdCamera.taaFrameIndex : (int)m_FrameCount % 8;

            cmd.SetGlobalInt(HDShaderIDs._RaytracingFrameIndex, frameIndex);

            // Inject the ray generation data
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayBias, rtEnvironment.rayBias);

            using (new ProfilingSample(cmd, "Ray Traced Shadows", CustomSamplerId.RaytracingShadowIntegration.GetSampler()))
            {
                // Loop through all the potential screen space light shadows
                for (int lightIdx = 0; lightIdx < m_ScreenSpaceShadowIndex; ++lightIdx)
                {
                    // This matches the directional light
                    if (!m_CurrentScreenSpaceShadowData[lightIdx].valid)
                    {
                        continue;
                    }

                    // Fetch the light data and additional light data
                    LightData             currentLight = m_lightList.lights[m_CurrentScreenSpaceShadowData[lightIdx].lightDataIndex];
                    HDAdditionalLightData currentAdditionalLightData = m_CurrentScreenSpaceShadowData[lightIdx].additionalLightData;

                    // Trigger the right algorithm based on the light type
                    switch (currentLight.lightType)
                    {
                    case GPULightType.Rectangle:
                    {
                        RenderAreaScreenSpaceShadow(cmd, hdCamera, rtEnvironment, currentLight, currentAdditionalLightData, m_CurrentScreenSpaceShadowData[lightIdx].lightDataIndex, shadowHistoryArray);
                    }
                    break;

                    case GPULightType.Point:
                    {
                        RenderPunctualScreenSpaceShadow(cmd, hdCamera, rtEnvironment, currentLight, currentAdditionalLightData, m_CurrentScreenSpaceShadowData[lightIdx].lightDataIndex, shadowHistoryArray);
                    }
                    break;
                    }
                }
            }
            return(true);
        }
Пример #4
0
        void BindRayTracedReflectionData(CommandBuffer cmd, HDCamera hdCamera, RayTracingShader reflectionShader, ScreenSpaceReflection settings, LightCluster lightClusterSettings, RayTracingSettings rtSettings
                                         , RTHandle outputLightingBuffer, RTHandle outputHitPointBuffer)
        {
            // Grab the acceleration structures and the light cluster to use
            RayTracingAccelerationStructure accelerationStructure = RequestAccelerationStructure();
            HDRaytracingLightCluster        lightCluster          = RequestLightCluster();
            BlueNoise blueNoise = GetBlueNoiseManager();

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

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

            // Global reflection parameters
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingIntensityClamp, settings.clampValue.value);
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingReflectionMinSmoothness, settings.minSmoothness.value);
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingReflectionSmoothnessFadeStart, settings.smoothnessFadeStart.value);
            cmd.SetGlobalInt(HDShaderIDs._RaytracingIncludeSky, settings.reflectSky.value ? 1 : 0);

            // Inject the ray generation data
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayBias, rtSettings.rayBias.value);
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayMaxLength, settings.rayLength.value);
            cmd.SetGlobalInt(HDShaderIDs._RaytracingNumSamples, settings.sampleCount.value);

            // Inject the ray-tracing sampling data
            blueNoise.BindDitheredRNGData8SPP(cmd);

            // Set the data for the ray generation
            cmd.SetRayTracingTextureParam(reflectionShader, HDShaderIDs._SsrLightingTextureRW, outputLightingBuffer);
            cmd.SetRayTracingTextureParam(reflectionShader, HDShaderIDs._SsrHitPointTexture, outputHitPointBuffer);
            cmd.SetRayTracingTextureParam(reflectionShader, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
            cmd.SetRayTracingTextureParam(reflectionShader, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer());
            cmd.SetGlobalTexture(HDShaderIDs._StencilTexture, sharedRTManager.GetDepthStencilBuffer(), RenderTextureSubElement.Stencil);
            cmd.SetRayTracingIntParams(reflectionShader, HDShaderIDs._SsrStencilBit, (int)StencilUsage.TraceReflectionRay);

            // Set ray count tex
            RayCountManager rayCountManager = GetRayCountManager();

            cmd.SetGlobalInt(HDShaderIDs._RayCountEnabled, rayCountManager.RayCountIsEnabled());
            cmd.SetRayTracingTextureParam(reflectionShader, HDShaderIDs._RayCountTexture, rayCountManager.GetRayCountTexture());

            // Compute the pixel spread value
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingPixelSpreadAngle, GetPixelSpreadAngle(hdCamera.camera.fieldOfView, hdCamera.actualWidth, hdCamera.actualHeight));

            // Bind the lightLoop data
            lightCluster.BindLightClusterData(cmd);

            // Note: Just in case, we rebind the directional light data (in case they were not)
            cmd.SetGlobalBuffer(HDShaderIDs._DirectionalLightDatas, m_LightLoopLightData.directionalLightData);

            // Evaluate the clear coat mask texture based on the lit shader mode
            RenderTargetIdentifier clearCoatMaskTexture = hdCamera.frameSettings.litShaderMode == LitShaderMode.Deferred ? m_GbufferManager.GetBuffersRTI()[2] : TextureXR.GetBlackTexture();

            cmd.SetRayTracingTextureParam(reflectionShader, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMaskTexture);

            // Set the number of bounces for reflections
            cmd.SetGlobalInt(HDShaderIDs._RaytracingMaxRecursion, settings.bounceCount.value);

            // Set the data for the ray miss
            cmd.SetRayTracingTextureParam(reflectionShader, HDShaderIDs._SkyTexture, m_SkyManager.GetSkyReflection(hdCamera));
        }
        public void Render(HDCamera hdCamera, CommandBuffer cmd, RTHandleSystem.RTHandle outputTexture, ScriptableRenderContext renderContext, CullingResults cull)
        {
            // First thing to check is: Do we have a valid ray-tracing environment?
            HDRaytracingEnvironment rtEnvironment  = m_RaytracingManager.CurrentEnvironment();
            HDRenderPipeline        renderPipeline = m_RaytracingManager.GetRenderPipeline();
            RayTracingShader        forwardShader  = m_PipelineAsset.renderPipelineRayTracingResources.forwardRaytracing;
            Shader raytracingMask = m_PipelineAsset.renderPipelineRayTracingResources.raytracingFlagMask;

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

            // Check the validity of the state before computing the effect
            bool invalidState = rtEnvironment == null || !recursiveSettings.enable.value ||
                                forwardShader == null || raytracingMask == null ||
                                m_PipelineResources.textures.owenScrambledTex == null || m_PipelineResources.textures.scramblingTex == null;

            // If any resource or game-object is missing We stop right away
            if (invalidState)
            {
                return;
            }

            // Grab the acceleration structure and the list of HD lights for the target camera
            RayTracingAccelerationStructure accelerationStructure = m_RaytracingManager.RequestAccelerationStructure(rtEnvironment.raytracedLayerMask);
            HDRaytracingLightCluster        lightCluster          = m_RaytracingManager.RequestLightCluster(rtEnvironment.raytracedLayerMask);

            if (m_RaytracingFlagMaterial == null)
            {
                m_RaytracingFlagMaterial = CoreUtils.CreateEngineMaterial(raytracingMask);
            }

            // Before going into raytracing, we need to flag which pixels needs to be raytracing
            EvaluateRaytracingMask(cull, hdCamera, cmd, renderContext);

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

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

            // Inject the ray-tracing sampling data
            cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._OwenScrambledTexture, m_PipelineResources.textures.owenScrambledTex);
            cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._ScramblingTexture, m_PipelineResources.textures.scramblingTex);

            // Inject the ray generation data
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayBias, rtEnvironment.rayBias);
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayMaxLength, recursiveSettings.rayLength.value);
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingMaxRecursion, recursiveSettings.maxDepth.value);
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingCameraNearPlane, hdCamera.camera.nearClipPlane);

            // Set the data for the ray generation
            cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._RaytracingFlagMask, m_RaytracingFlagTarget);
            cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
            cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._CameraColorTextureRW, outputTexture);

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

            cmd.SetGlobalFloat(HDShaderIDs._RaytracingPixelSpreadAngle, pixelSpreadAngle);

            // LightLoop data
            cmd.SetGlobalBuffer(HDShaderIDs._RaytracingLightCluster, lightCluster.GetCluster());
            cmd.SetGlobalBuffer(HDShaderIDs._LightDatasRT, lightCluster.GetLightDatas());
            cmd.SetGlobalVector(HDShaderIDs._MinClusterPos, lightCluster.GetMinClusterPos());
            cmd.SetGlobalVector(HDShaderIDs._MaxClusterPos, lightCluster.GetMaxClusterPos());
            cmd.SetGlobalInt(HDShaderIDs._LightPerCellCount, lightClusterSettings.maxNumLightsPercell.value);
            cmd.SetGlobalInt(HDShaderIDs._PunctualLightCountRT, lightCluster.GetPunctualLightCount());
            cmd.SetGlobalInt(HDShaderIDs._AreaLightCountRT, lightCluster.GetAreaLightCount());

            // Note: Just in case, we rebind the directional light data (in case they were not)
            cmd.SetGlobalBuffer(HDShaderIDs._DirectionalLightDatas, renderPipeline.m_LightLoopLightData.directionalLightData);
            cmd.SetGlobalInt(HDShaderIDs._DirectionalLightCount, renderPipeline.m_lightList.directionalLights.Count);

            // Set the data for the ray miss
            cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._SkyTexture, m_SkyManager.skyReflection);

            // If this is the right debug mode and we have at least one light, write the first shadow to the denoise texture
            HDRenderPipeline hdrp = (RenderPipelineManager.currentPipeline as HDRenderPipeline);

            cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._RaytracingPrimaryDebug, m_DebugRaytracingTexture);
            hdrp.PushFullScreenDebugTexture(hdCamera, cmd, m_DebugRaytracingTexture, FullScreenDebugMode.PrimaryVisibility);

            // Run the computation
            cmd.DispatchRays(forwardShader, m_RayGenShaderName, (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, 1);
        }
Пример #6
0
        void RenderDirectionalLightScreenSpaceShadow(CommandBuffer cmd, HDCamera hdCamera, int frameCount)
        {
            // Render directional screen space shadow if required
            if (m_CurrentSunLightAdditionalLightData != null && m_CurrentSunLightAdditionalLightData.WillRenderScreenSpaceShadow())
            {
#if ENABLE_RAYTRACING
                // Grab the ray tracing environment
                HDRaytracingEnvironment rtEnvironment = m_RayTracingManager.CurrentEnvironment();

                // If the shadow is flagged as ray traced, we need to evaluate it completely
                if (rtEnvironment != null && hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && m_CurrentSunLightAdditionalLightData.WillRenderRayTracedShadow())
                {
                    BlueNoise        blueNoise      = m_RayTracingManager.GetBlueNoiseManager();
                    ComputeShader    shadowsCompute = m_Asset.renderPipelineRayTracingResources.shadowRaytracingCS;
                    RayTracingShader shadowRayTrace = m_Asset.renderPipelineRayTracingResources.shadowRaytracingRT;

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

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

                    int shadowComputeKernel = shadowsCompute.FindKernel("ClearShadowTexture");
                    cmd.SetComputeBufferParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._LightDatas, m_LightLoopLightData.lightData);
                    cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._RaytracedDirectionalShadowIntegration, m_DenoiseBuffer0);
                    cmd.DispatchCompute(shadowsCompute, shadowComputeKernel, numTilesX, numTilesY, 1);

                    // Inject the ray-tracing sampling data
                    blueNoise.BindDitheredRNGData8SPP(cmd);

                    for (int i = 0; i < m_CurrentSunLightAdditionalLightData.numRayTracingSamples; ++i)
                    {
                        shadowComputeKernel = shadowsCompute.FindKernel("RaytracingDirectionalShadowSample");

                        int frameIndex = hdCamera.IsTAAEnabled() ? hdCamera.taaFrameIndex : (int)frameCount % 8;

                        // This pass evaluates the analytic value and the generates and outputs the first sample
                        cmd.SetComputeBufferParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._LightDatas, m_LightLoopLightData.lightData);
                        cmd.SetComputeIntParam(shadowsCompute, HDShaderIDs._RaytracingFrameIndex, frameIndex);
                        cmd.SetComputeIntParam(shadowsCompute, HDShaderIDs._RaytracingNumSamples, m_CurrentSunLightAdditionalLightData.numRayTracingSamples);
                        cmd.SetComputeIntParam(shadowsCompute, HDShaderIDs._RaytracingSampleIndex, i);
                        cmd.SetComputeMatrixParam(shadowsCompute, HDShaderIDs._RaytracingAreaWorldToLocal, worldToLocalArea);
                        cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
                        cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer());
                        cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._RaytracedDirectionalShadowIntegration, m_DenoiseBuffer0);
                        cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._RaytracingDirectionBuffer, m_RaytracingDirectionBuffer);
                        cmd.SetComputeFloatParam(shadowsCompute, HDShaderIDs._DirectionalLightAngle, m_CurrentSunLightAdditionalLightData.sunLightConeAngle);

                        cmd.DispatchCompute(shadowsCompute, shadowComputeKernel, numTilesX, numTilesY, 1);

                        // Grab the acceleration structure for the target camera
                        RayTracingAccelerationStructure accelerationStructure = m_RayTracingManager.RequestAccelerationStructure(rtEnvironment.shadowLayerMask);

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

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

                        // Set ray count texture
                        // This pass will use the previously generated sample and add it to the integration buffer
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer());
                        cmd.SetRayTracingIntParam(shadowRayTrace, HDShaderIDs._RayCountEnabled, m_RayTracingManager.rayCountManager.RayCountIsEnabled());
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._RayCountTexture, m_RayTracingManager.rayCountManager.GetRayCountTexture());
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._RaytracedDirectionalShadowIntegration, m_DenoiseBuffer0);
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._RaytracingDirectionBuffer, m_RaytracingDirectionBuffer);
                        cmd.SetRayTracingFloatParam(shadowRayTrace, HDShaderIDs._DirectionalLightAngle, m_CurrentSunLightAdditionalLightData.sunLightConeAngle);
                        cmd.SetRayTracingIntParam(shadowRayTrace, HDShaderIDs._RaytracingNumSamples, 1);
                        cmd.DispatchRays(shadowRayTrace, m_RayGenDirectionalShadowSingleName, (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, 1);
                    }

                    RTHandle shadowHistoryArray = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedShadow)
                                                  ?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedShadow, ShadowHistoryBufferAllocatorFunction, 1);

                    // Apply the simple denoiser (if required)
                    if (m_CurrentSunLightAdditionalLightData.filterTracedShadow)
                    {
                        // Apply the temporal denoiser
                        HDTemporalFilter temporalFilter = m_RayTracingManager.GetTemporalFilter();
                        temporalFilter.DenoiseBuffer(cmd, hdCamera, m_DenoiseBuffer0, shadowHistoryArray, m_DenoiseBuffer1, singleChannel: true, slotIndex: m_CurrentSunLightDirectionalLightData.screenSpaceShadowIndex);

                        // Apply the spatial denoiser
                        HDSimpleDenoiser simpleDenoiser = m_RayTracingManager.GetSimpleDenoiser();
                        simpleDenoiser.DenoiseBufferNoHistory(cmd, hdCamera, m_DenoiseBuffer1, m_DenoiseBuffer0, m_CurrentSunLightAdditionalLightData.filterSizeTraced, singleChannel: true);
                    }

                    shadowComputeKernel = shadowsCompute.FindKernel("OutputShadowTexture");
                    cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._RaytracedDirectionalShadowIntegration, m_DenoiseBuffer0);
                    cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._ScreenSpaceShadowsTextureRW, m_ScreenSpaceShadowTextureArray);
                    cmd.SetComputeIntParam(shadowsCompute, HDShaderIDs._RaytracingShadowSlot, m_CurrentSunLightDirectionalLightData.screenSpaceShadowIndex);
                    cmd.DispatchCompute(shadowsCompute, shadowComputeKernel, numTilesX, numTilesY, 1);
                }
                else
#endif
                {
                    // If it is screen space but not ray traced, then we can rely on the shadow map
                    CoreUtils.SetRenderTarget(cmd, m_ScreenSpaceShadowTextureArray, depthSlice: m_CurrentSunLightDirectionalLightData.screenSpaceShadowIndex);
                    HDUtils.DrawFullScreen(cmd, s_ScreenSpaceShadowsMat, m_ScreenSpaceShadowTextureArray);
                }
            }
        }
Пример #7
0
        internal void BuildRayTracingAccelerationStructure(HDCamera hdCamera)
        {
            // Clear all the per frame-data
            m_RayTracingRendererReference.Clear();
            m_RayTracingLights.hdDirectionalLightArray.Clear();
            m_RayTracingLights.hdPointLightArray.Clear();
            m_RayTracingLights.hdLineLightArray.Clear();
            m_RayTracingLights.hdRectLightArray.Clear();
            m_RayTracingLights.hdLightArray.Clear();
            m_RayTracingLights.reflectionProbeArray.Clear();
            m_RayTracingLights.lightCount = 0;
            m_CurrentRAS.Dispose();
            m_CurrentRAS                    = new RayTracingAccelerationStructure();
            m_ValidRayTracingState          = false;
            m_ValidRayTracingCluster        = false;
            m_ValidRayTracingClusterCulling = false;
            bool rayTracedShadow = false;

            // fetch all the lights in the scene
            HDAdditionalLightData[] hdLightArray = UnityEngine.GameObject.FindObjectsOfType <HDAdditionalLightData>();

            for (int lightIdx = 0; lightIdx < hdLightArray.Length; ++lightIdx)
            {
                HDAdditionalLightData hdLight = hdLightArray[lightIdx];
                if (hdLight.enabled)
                {
                    // Check if there is a ray traced shadow in the scene
                    rayTracedShadow |= (hdLight.useRayTracedShadows || (hdLight.useContactShadow.@override && hdLight.rayTraceContactShadow));

                    switch (hdLight.type)
                    {
                    case HDLightType.Directional:
                        m_RayTracingLights.hdDirectionalLightArray.Add(hdLight);
                        break;

                    case HDLightType.Point:
                    case HDLightType.Spot:
                        m_RayTracingLights.hdPointLightArray.Add(hdLight);
                        break;

                    case HDLightType.Area:
                        switch (hdLight.areaLightShape)
                        {
                        case AreaLightShape.Rectangle:
                            m_RayTracingLights.hdRectLightArray.Add(hdLight);
                            break;

                        case AreaLightShape.Tube:
                            m_RayTracingLights.hdLineLightArray.Add(hdLight);
                            break;
                            //TODO: case AreaLightShape.Disc:
                        }
                        break;
                    }
                }
            }

            m_RayTracingLights.hdLightArray.AddRange(m_RayTracingLights.hdPointLightArray);
            m_RayTracingLights.hdLightArray.AddRange(m_RayTracingLights.hdLineLightArray);
            m_RayTracingLights.hdLightArray.AddRange(m_RayTracingLights.hdRectLightArray);

            HDAdditionalReflectionData[] reflectionProbeArray = UnityEngine.GameObject.FindObjectsOfType <HDAdditionalReflectionData>();
            for (int reflIdx = 0; reflIdx < reflectionProbeArray.Length; ++reflIdx)
            {
                HDAdditionalReflectionData reflectionProbe = reflectionProbeArray[reflIdx];
                // Add it to the list if enabled
                if (reflectionProbe.enabled)
                {
                    m_RayTracingLights.reflectionProbeArray.Add(reflectionProbe);
                }
            }

            m_RayTracingLights.lightCount = m_RayTracingLights.hdPointLightArray.Count
                                            + m_RayTracingLights.hdLineLightArray.Count
                                            + m_RayTracingLights.hdRectLightArray.Count
                                            + m_RayTracingLights.reflectionProbeArray.Count;

            AmbientOcclusion      aoSettings          = hdCamera.volumeStack.GetComponent <AmbientOcclusion>();
            ScreenSpaceReflection reflSettings        = hdCamera.volumeStack.GetComponent <ScreenSpaceReflection>();
            GlobalIllumination    giSettings          = hdCamera.volumeStack.GetComponent <GlobalIllumination>();
            RecursiveRendering    recursiveSettings   = hdCamera.volumeStack.GetComponent <RecursiveRendering>();
            PathTracing           pathTracingSettings = hdCamera.volumeStack.GetComponent <PathTracing>();

            // We need to process the emissive meshes of the rectangular area lights
            for (var i = 0; i < m_RayTracingLights.hdRectLightArray.Count; i++)
            {
                // Fetch the current renderer of the rectangular area light (if any)
                MeshRenderer currentRenderer = m_RayTracingLights.hdRectLightArray[i].emissiveMeshRenderer;

                // If there is none it means that there is no emissive mesh for this light
                if (currentRenderer == null)
                {
                    continue;
                }

                // This objects should be included into the RAS
                AddInstanceToRAS(currentRenderer,
                                 rayTracedShadow,
                                 aoSettings.rayTracing.value, aoSettings.layerMask.value,
                                 reflSettings.rayTracing.value, reflSettings.layerMask.value,
                                 giSettings.rayTracing.value, giSettings.layerMask.value,
                                 recursiveSettings.enable.value, recursiveSettings.layerMask.value,
                                 pathTracingSettings.enable.value, pathTracingSettings.layerMask.value);
            }

            int matCount = m_MaterialCRCs.Count;

            LODGroup[] lodGroupArray = UnityEngine.GameObject.FindObjectsOfType <LODGroup>();
            for (var i = 0; i < lodGroupArray.Length; i++)
            {
                // Grab the current LOD group
                LODGroup lodGroup = lodGroupArray[i];

                // Get the set of LODs
                LOD[] lodArray = lodGroup.GetLODs();
                for (int lodIdx = 0; lodIdx < lodArray.Length; ++lodIdx)
                {
                    LOD currentLOD = lodArray[lodIdx];
                    // We only want to push to the acceleration structure the lod0, we do not have defined way to select the right LOD at the moment
                    if (lodIdx == 0)
                    {
                        for (int rendererIdx = 0; rendererIdx < currentLOD.renderers.Length; ++rendererIdx)
                        {
                            // Fetch the renderer that we are interested in
                            Renderer currentRenderer = currentLOD.renderers[rendererIdx];

                            // This objects should but included into the RAS
                            AddInstanceToRAS(currentRenderer,
                                             rayTracedShadow,
                                             aoSettings.rayTracing.value, aoSettings.layerMask.value,
                                             reflSettings.rayTracing.value, reflSettings.layerMask.value,
                                             giSettings.rayTracing.value, giSettings.layerMask.value,
                                             recursiveSettings.enable.value, recursiveSettings.layerMask.value,
                                             pathTracingSettings.enable.value, pathTracingSettings.layerMask.value);
                        }
                    }

                    // Add them to the processed set so that they are not taken into account when processing all the renderers
                    for (int rendererIdx = 0; rendererIdx < currentLOD.renderers.Length; ++rendererIdx)
                    {
                        Renderer currentRenderer = currentLOD.renderers[rendererIdx];
                        // Add this fella to the renderer list
                        // Unfortunately, we need to check that this renderer was not already pushed into the list (happens if the user uses the same mesh renderer
                        // for two LODs)
                        if (!m_RayTracingRendererReference.ContainsKey(currentRenderer.GetInstanceID()))
                        {
                            m_RayTracingRendererReference.Add(currentRenderer.GetInstanceID(), 1);
                        }
                    }
                }
            }

            // Grab all the renderers from the scene
            var rendererArray = UnityEngine.GameObject.FindObjectsOfType <Renderer>();

            for (var i = 0; i < rendererArray.Length; i++)
            {
                // Fetch the current renderer
                Renderer currentRenderer = rendererArray[i];

                // If it is not active skip it
                if (currentRenderer.enabled == false)
                {
                    continue;
                }

                // Grab the current game object
                GameObject gameObject = currentRenderer.gameObject;

                // Has this object already been processed, just skip it
                if (m_RayTracingRendererReference.ContainsKey(currentRenderer.GetInstanceID()))
                {
                    continue;
                }

                // Does this object have a reflection probe component? if yes we do not want to have it in the acceleration structure
                if (gameObject.TryGetComponent <ReflectionProbe>(out reflectionProbe))
                {
                    continue;
                }

                // This objects should be included into the RAS
                AddInstanceToRAS(currentRenderer,
                                 rayTracedShadow,
                                 aoSettings.rayTracing.value, aoSettings.layerMask.value,
                                 reflSettings.rayTracing.value, reflSettings.layerMask.value,
                                 giSettings.rayTracing.value, giSettings.layerMask.value,
                                 recursiveSettings.enable.value, recursiveSettings.layerMask.value,
                                 pathTracingSettings.enable.value, pathTracingSettings.layerMask.value);
            }

            // Check if the amount of materials being tracked has changed
            m_MaterialsDirty |= (matCount != m_MaterialCRCs.Count);

            // build the acceleration structure
            m_CurrentRAS.Build();

            // tag the structures as valid
            m_ValidRayTracingState = true;
        }
Пример #8
0
 public void BuildRayTracingAccelerationStructure(RayTracingAccelerationStructure accelerationStructure)
 {
     Internal_BuildRayTracingAccelerationStructure(accelerationStructure);
 }
Пример #9
0
 public void SetRayTracingAccelerationStructure(RayTracingShader rayTracingShader, string name, RayTracingAccelerationStructure rayTracingAccelerationStructure)
 {
     Internal_SetRayTracingAccelerationStructure(rayTracingShader, Shader.PropertyToID(name), rayTracingAccelerationStructure);
 }
        public void RenderAO(HDCamera hdCamera, CommandBuffer cmd, RTHandle outputTexture, ShaderVariablesRaytracing globalCB, ScriptableRenderContext renderContext, int frameCount)
        {
            // If any of the previous requirements is missing, the effect is not requested or no acceleration structure, set the default one and leave right away
            if (!m_RenderPipeline.GetRayTracingState())
            {
                SetDefaultAmbientOcclusionTexture(cmd);
                return;
            }

            RayTracingShader aoShaderRT     = m_PipelineRayTracingResources.aoRaytracingRT;
            var             aoSettings      = hdCamera.volumeStack.GetComponent <AmbientOcclusion>();
            RayCountManager rayCountManager = m_RenderPipeline.GetRayCountManager();

            using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.RaytracingAmbientOcclusion)))
            {
                // Grab the acceleration structure for the target camera
                RayTracingAccelerationStructure accelerationStructure = m_RenderPipeline.RequestAccelerationStructure();

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

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

                // Inject the ray generation data (be careful of the global constant buffer limitation)
                globalCB._RaytracingRayMaxLength = aoSettings.rayLength;
                globalCB._RaytracingNumSamples   = aoSettings.sampleCount;
                ConstantBuffer.PushGlobal(cmd, globalCB, HDShaderIDs._ShaderVariablesRaytracing);

                // Set the data for the ray generation
                cmd.SetRayTracingTextureParam(aoShaderRT, HDShaderIDs._DepthTexture, m_RenderPipeline.sharedRTManager.GetDepthStencilBuffer());
                cmd.SetRayTracingTextureParam(aoShaderRT, HDShaderIDs._NormalBufferTexture, m_RenderPipeline.sharedRTManager.GetNormalBuffer());

                // Inject the ray-tracing sampling data
                BlueNoise blueNoise = m_RenderPipeline.GetBlueNoiseManager();
                blueNoise.BindDitheredRNGData8SPP(cmd);


                // Set the output textures
                cmd.SetRayTracingTextureParam(aoShaderRT, HDShaderIDs._RayCountTexture, rayCountManager.GetRayCountTexture());
                cmd.SetRayTracingTextureParam(aoShaderRT, HDShaderIDs._AmbientOcclusionTextureRW, m_AOIntermediateBuffer0);

                // Run the computation
                cmd.DispatchRays(aoShaderRT, m_RayGenShaderName, (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, (uint)hdCamera.viewCount);
            }

            using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.RaytracingFilterAmbientOcclusion)))
            {
                if (aoSettings.denoise)
                {
                    // Grab the history buffer
                    RTHandle ambientOcclusionHistory = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedAmbientOcclusion)
                                                       ?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedAmbientOcclusion, AmbientOcclusionHistoryBufferAllocatorFunction, 1);

                    float historyValidity = 1.0f;
                    #if UNITY_HDRP_DXR_TESTS_DEFINE
                    if (Application.isPlaying)
                    {
                        historyValidity = 0.0f;
                    }
                    else
                    #endif
                    // We need to check if something invalidated the history buffers
                    historyValidity = m_RenderPipeline.ValidRayTracingHistory(hdCamera) ? 1.0f : 0.0f;

                    // Apply the temporal denoiser
                    HDTemporalFilter temporalFilter = m_RenderPipeline.GetTemporalFilter();
                    temporalFilter.DenoiseBuffer(cmd, hdCamera, m_AOIntermediateBuffer0, ambientOcclusionHistory, m_AOIntermediateBuffer1, historyValidity: historyValidity);

                    // Apply the diffuse denoiser
                    HDDiffuseDenoiser diffuseDenoiser = m_RenderPipeline.GetDiffuseDenoiser();
                    diffuseDenoiser.DenoiseBuffer(cmd, hdCamera, m_AOIntermediateBuffer1, outputTexture, aoSettings.denoiserRadius);
                }
                else
                {
                    HDUtils.BlitCameraTexture(cmd, m_AOIntermediateBuffer0, outputTexture);
                }

                ComputeShader aoShaderCS = m_PipelineRayTracingResources.aoRaytracingCS;
                cmd.SetComputeFloatParam(aoShaderCS, HDShaderIDs._RaytracingAOIntensity, aoSettings.intensity.value);
                cmd.SetComputeTextureParam(aoShaderCS, m_RTAOApplyIntensityKernel, HDShaderIDs._AmbientOcclusionTextureRW, outputTexture);
                int texWidth     = hdCamera.actualWidth;
                int texHeight    = hdCamera.actualHeight;
                int areaTileSize = 8;
                int numTilesXHR  = (texWidth + (areaTileSize - 1)) / areaTileSize;
                int numTilesYHR  = (texHeight + (areaTileSize - 1)) / areaTileSize;
                cmd.DispatchCompute(aoShaderCS, m_RTAOApplyIntensityKernel, numTilesXHR, numTilesYHR, hdCamera.viewCount);
            }

            // Bind the textures and the params
            cmd.SetGlobalTexture(HDShaderIDs._AmbientOcclusionTexture, outputTexture);

            // TODO: All the push-debug stuff should be centralized somewhere
            (RenderPipelineManager.currentPipeline as HDRenderPipeline).PushFullScreenDebugTexture(hdCamera, cmd, outputTexture, FullScreenDebugMode.ScreenSpaceAmbientOcclusion);
        }
 public static void BindSceneStruct(CommandBuffer CmdBuffer, RayTracingAccelerationStructure RTSceneStruct)
 {
     CmdBuffer.SetRayTracingShaderPass(RTAO_Shader, RTAOPassID);
     CmdBuffer.SetRayTracingAccelerationStructure(RTAO_Shader, SceneStructID, RTSceneStruct);
 }
        void RaytracingRecursiveRender(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext renderContext, CullingResults cull)
        {
            // First thing to check is: Do we have a valid ray-tracing environment?
            RecursiveRendering recursiveSettings = VolumeManager.instance.stack.GetComponent <RecursiveRendering>();

            // Check the validity of the state before computing the effect
            bool invalidState = !hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) ||
                                !recursiveSettings.enable.value ||
                                m_Asset.currentPlatformRenderPipelineSettings.supportedRaytracingTier == RenderPipelineSettings.RaytracingTier.Tier1;

            // If any resource or game-object is missing We stop right away
            if (invalidState)
            {
                return;
            }

            RayTracingShader   forwardShader        = m_Asset.renderPipelineRayTracingResources.forwardRaytracing;
            Shader             raytracingMask       = m_Asset.renderPipelineRayTracingResources.raytracingFlagMask;
            LightCluster       lightClusterSettings = VolumeManager.instance.stack.GetComponent <LightCluster>();
            RayTracingSettings rtSettings           = VolumeManager.instance.stack.GetComponent <RayTracingSettings>();

            // Grab the acceleration structure and the list of HD lights for the target camera
            RayTracingAccelerationStructure accelerationStructure = RequestAccelerationStructure();
            HDRaytracingLightCluster        lightCluster          = RequestLightCluster();

            // Fecth the temporary buffers we shall be using
            RTHandle flagBuffer = GetRayTracingBuffer(InternalRayTracingBuffers.R0);

            if (m_RaytracingFlagMaterial == null)
            {
                m_RaytracingFlagMaterial = CoreUtils.CreateEngineMaterial(raytracingMask);
            }

            // Before going into ray tracing, we need to flag which pixels needs to be raytracing
            EvaluateRaytracingMask(cull, hdCamera, cmd, renderContext, flagBuffer);

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

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

            // Inject the ray-tracing sampling data
            cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._OwenScrambledTexture, m_Asset.renderPipelineResources.textures.owenScrambledRGBATex);
            cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._ScramblingTexture, m_Asset.renderPipelineResources.textures.scramblingTex);

            // Inject the ray generation data
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayBias, rtSettings.rayBias.value);
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayMaxLength, recursiveSettings.rayLength.value);
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingMaxRecursion, recursiveSettings.maxDepth.value);
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingCameraNearPlane, hdCamera.camera.nearClipPlane);

            // Set the data for the ray generation
            cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._RaytracingFlagMask, flagBuffer);
            cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
            cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._CameraColorTextureRW, m_CameraColorBuffer);

            // Set ray count texture
            RayCountManager rayCountManager = GetRayCountManager();

            cmd.SetRayTracingIntParam(forwardShader, HDShaderIDs._RayCountEnabled, rayCountManager.RayCountIsEnabled());
            cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._RayCountTexture, rayCountManager.GetRayCountTexture());

            // Compute an approximate pixel spread angle value (in radians)
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingPixelSpreadAngle, GetPixelSpreadAngle(hdCamera.camera.fieldOfView, hdCamera.actualWidth, hdCamera.actualHeight));

            // LightLoop data
            cmd.SetGlobalBuffer(HDShaderIDs._RaytracingLightCluster, lightCluster.GetCluster());
            cmd.SetGlobalBuffer(HDShaderIDs._LightDatasRT, lightCluster.GetLightDatas());
            cmd.SetGlobalVector(HDShaderIDs._MinClusterPos, lightCluster.GetMinClusterPos());
            cmd.SetGlobalVector(HDShaderIDs._MaxClusterPos, lightCluster.GetMaxClusterPos());
            cmd.SetGlobalInt(HDShaderIDs._LightPerCellCount, lightClusterSettings.maxNumLightsPercell.value);
            cmd.SetGlobalInt(HDShaderIDs._PunctualLightCountRT, lightCluster.GetPunctualLightCount());
            cmd.SetGlobalInt(HDShaderIDs._AreaLightCountRT, lightCluster.GetAreaLightCount());

            // Note: Just in case, we rebind the directional light data (in case they were not)
            cmd.SetGlobalBuffer(HDShaderIDs._DirectionalLightDatas, m_LightLoopLightData.directionalLightData);
            cmd.SetGlobalInt(HDShaderIDs._DirectionalLightCount, m_lightList.directionalLights.Count);

            // Set the data for the ray miss
            cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._SkyTexture, m_SkyManager.GetSkyReflection(hdCamera));

            // If this is the right debug mode and we have at least one light, write the first shadow to the de-noised texture
            RTHandle debugBuffer = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA0);

            cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._RaytracingPrimaryDebug, debugBuffer);

            // Run the computation
            cmd.DispatchRays(forwardShader, m_RayGenShaderName, (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, (uint)hdCamera.viewCount);

            HDRenderPipeline hdrp = (RenderPipelineManager.currentPipeline as HDRenderPipeline);

            hdrp.PushFullScreenDebugTexture(hdCamera, cmd, debugBuffer, FullScreenDebugMode.RecursiveRayTracing);
        }
Пример #13
0
        void RenderPathTracing(HDCamera hdCamera, CommandBuffer cmd, RTHandle outputTexture)
        {
            RayTracingShader pathTracingShader = m_Asset.renderPipelineRayTracingResources.pathTracing;

            m_PathTracingSettings = hdCamera.volumeStack.GetComponent <PathTracing>();

            // Check the validity of the state before moving on with the computation
            if (!pathTracingShader || !m_PathTracingSettings.enable.value)
            {
                return;
            }

            CheckDirtiness(hdCamera);

            // Inject the ray-tracing sampling data
            BlueNoise blueNoiseManager = GetBlueNoiseManager();

            blueNoiseManager.BindDitheredRNGData256SPP(cmd);

            // Grab the acceleration structure and the list of HD lights for the target camera
            RayTracingAccelerationStructure accelerationStructure = RequestAccelerationStructure();
            HDRaytracingLightCluster        lightCluster          = RequestLightCluster();
            LightCluster       lightClusterSettings = hdCamera.volumeStack.GetComponent <LightCluster>();
            RayTracingSettings rayTracingSettings   = hdCamera.volumeStack.GetComponent <RayTracingSettings>();

            if (!m_SubFrameManager.isRecording)
            {
                // If we are recording, the max iteration is set/overridden by the subframe manager, otherwise we read it from the path tracing volume
                m_SubFrameManager.subFrameCount = (uint)m_PathTracingSettings.maximumSamples.value;
            }

#if UNITY_HDRP_DXR_TESTS_DEFINE
            if (Application.isPlaying)
            {
                m_SubFrameManager.subFrameCount = 1;
            }
#endif

            uint currentIteration = m_SubFrameManager.iteration;
            if (currentIteration < m_SubFrameManager.subFrameCount)
            {
                // Define the shader pass to use for the path tracing pass
                cmd.SetRayTracingShaderPass(pathTracingShader, "PathTracingDXR");

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

                // Inject the ray-tracing sampling data
                cmd.SetGlobalTexture(HDShaderIDs._OwenScrambledTexture, m_Asset.renderPipelineResources.textures.owenScrambled256Tex);
                cmd.SetGlobalTexture(HDShaderIDs._ScramblingTexture, m_Asset.renderPipelineResources.textures.scramblingTex);

                // Inject the ray generation data

                cmd.SetGlobalFloat(HDShaderIDs._RaytracingNumSamples, m_SubFrameManager.subFrameCount);
                cmd.SetGlobalFloat(HDShaderIDs._RaytracingMinRecursion, m_PathTracingSettings.minimumDepth.value);
                cmd.SetGlobalFloat(HDShaderIDs._RaytracingMaxRecursion, m_PathTracingSettings.maximumDepth.value);
                cmd.SetGlobalFloat(HDShaderIDs._RaytracingIntensityClamp, m_PathTracingSettings.maximumIntensity.value);
                cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayBias, rayTracingSettings.rayBias.value);
                cmd.SetGlobalFloat(HDShaderIDs._RaytracingCameraNearPlane, hdCamera.camera.nearClipPlane);

                // Set the data for the ray generation
                cmd.SetGlobalInt(HDShaderIDs._RaytracingSampleIndex, (int)m_SubFrameManager.iteration);

                // Compute an approximate pixel spread angle value (in radians)
                cmd.SetRayTracingFloatParam(pathTracingShader, HDShaderIDs._RaytracingPixelSpreadAngle, GetPixelSpreadAngle(hdCamera.camera.fieldOfView, hdCamera.actualWidth, hdCamera.actualHeight));

                // LightLoop data
                cmd.SetGlobalBuffer(HDShaderIDs._RaytracingLightCluster, lightCluster.GetCluster());
                cmd.SetGlobalBuffer(HDShaderIDs._LightDatasRT, lightCluster.GetLightDatas());
                cmd.SetGlobalVector(HDShaderIDs._MinClusterPos, lightCluster.GetMinClusterPos());
                cmd.SetGlobalVector(HDShaderIDs._MaxClusterPos, lightCluster.GetMaxClusterPos());
                cmd.SetGlobalInt(HDShaderIDs._LightPerCellCount, lightClusterSettings.maxNumLightsPercell.value);
                cmd.SetGlobalInt(HDShaderIDs._PunctualLightCountRT, lightCluster.GetPunctualLightCount());
                cmd.SetGlobalInt(HDShaderIDs._AreaLightCountRT, lightCluster.GetAreaLightCount());

                // Set the data for the ray miss
                cmd.SetRayTracingIntParam(pathTracingShader, HDShaderIDs._RaytracingCameraSkyEnabled, m_CameraSkyEnabled ? 1 : 0);
                cmd.SetRayTracingVectorParam(pathTracingShader, HDShaderIDs._RaytracingCameraClearColor, hdCamera.backgroundColorHDR);
                cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._SkyTexture, m_SkyManager.GetSkyReflection(hdCamera));

                // Additional data for path tracing
                cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._RadianceTexture, m_RadianceTexture);
                cmd.SetRayTracingMatrixParam(pathTracingShader, HDShaderIDs._PixelCoordToViewDirWS, hdCamera.mainViewConstants.pixelCoordToViewDirWS);

                // Run the computation
                cmd.DispatchRays(pathTracingShader, "RayGen", (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, 1);
            }
            RenderAccumulation(hdCamera, cmd, m_RadianceTexture, outputTexture, true);
        }
Пример #14
0
        /// <summary>
        /// Function that adds a renderer to a ray tracing acceleration structure.
        /// </summary>
        /// <param name="targetRTAS">Ray Tracing Acceleration structure the renderer should be added to.</param>
        /// <param name="currentRenderer">The renderer that should be added to the RTAS.</param>
        /// <param name="effectsParameters">Structure defining the enabled ray tracing and path tracing effects for a camera.</param>
        /// <param name="transformDirty">Flag that indicates if the renderer's transform has changed.</param>
        /// <param name="materialsDirty">Flag that indicates if any of the renderer's materials have changed.</param>
        /// <returns></returns>
        public static AccelerationStructureStatus AddInstanceToRAS(RayTracingAccelerationStructure targetRTAS, Renderer currentRenderer, HDEffectsParameters effectsParameters, ref bool transformDirty, ref bool materialsDirty)
        {
            // Get all the materials of the mesh renderer
            currentRenderer.GetSharedMaterials(materialArray);
            // If the array is null, we are done
            if (materialArray == null)
            {
                return(AccelerationStructureStatus.NullMaterial);
            }

            // For every sub-mesh/sub-material let's build the right flags
            int numSubMeshes = 1;

            if (!(currentRenderer.GetType() == typeof(SkinnedMeshRenderer)))
            {
                currentRenderer.TryGetComponent(out MeshFilter meshFilter);
                if (meshFilter == null || meshFilter.sharedMesh == null)
                {
                    return(AccelerationStructureStatus.MissingMesh);
                }
                numSubMeshes = meshFilter.sharedMesh.subMeshCount;
            }
            else
            {
                SkinnedMeshRenderer skinnedMesh = (SkinnedMeshRenderer)currentRenderer;
                if (skinnedMesh.sharedMesh == null)
                {
                    return(AccelerationStructureStatus.MissingMesh);
                }
                numSubMeshes = skinnedMesh.sharedMesh.subMeshCount;
            }

            // Let's clamp the number of sub-meshes to avoid throwing an unwanted error
            numSubMeshes = Mathf.Min(numSubMeshes, maxNumSubMeshes);

            // Get the layer of this object
            int objectLayerValue = 1 << currentRenderer.gameObject.layer;

            // We need to build the instance flag for this renderer
            uint instanceFlag = 0x00;

            bool doubleSided = false;
            bool materialIsOnlyTransparent = true;
            bool hasTransparentSubMaterial = false;

            // We disregard the ray traced shadows option when in Path Tracing
            bool rayTracedShadow = effectsParameters.shadows && !effectsParameters.pathTracing;

            // Deactivate Path Tracing if the object does not belong to the path traced layer(s)
            bool pathTracing = effectsParameters.pathTracing && (bool)((effectsParameters.ptLayerMask & objectLayerValue) != 0);

            for (int meshIdx = 0; meshIdx < numSubMeshes; ++meshIdx)
            {
                // Initially we consider the potential mesh as invalid
                bool validMesh = false;
                if (materialArray.Count > meshIdx)
                {
                    // Grab the material for the current sub-mesh
                    Material currentMaterial = materialArray[meshIdx];

                    // Make sure that the material is HDRP's and non-decal
                    if (IsValidRayTracedMaterial(currentMaterial))
                    {
                        // Mesh is valid given that all requirements are ok
                        validMesh = true;

                        // First mark the thing as valid
                        subMeshFlagArray[meshIdx] = RayTracingSubMeshFlags.Enabled;

                        // Evaluate what kind of materials we are dealing with
                        bool alphaTested         = IsAlphaTestedMaterial(currentMaterial);
                        bool transparentMaterial = IsTransparentMaterial(currentMaterial);

                        // Aggregate the transparency info
                        materialIsOnlyTransparent &= transparentMaterial;
                        hasTransparentSubMaterial |= transparentMaterial;

                        // Append the additional flags depending on what kind of sub mesh this is
                        if (!transparentMaterial && !alphaTested)
                        {
                            subMeshFlagArray[meshIdx] |= RayTracingSubMeshFlags.ClosestHitOnly;
                        }
                        else if (transparentMaterial)
                        {
                            subMeshFlagArray[meshIdx] |= RayTracingSubMeshFlags.UniqueAnyHitCalls;
                        }

                        // Check if we want to enable double-sidedness for the mesh
                        // (note that a mix of single and double-sided materials will result in a double-sided mesh in the AS)
                        doubleSided |= currentMaterial.doubleSidedGI || currentMaterial.IsKeywordEnabled("_DOUBLESIDED_ON");

                        // Check if the material has changed since last time we were here
                        if (!materialsDirty)
                        {
                            materialsDirty |= UpdateMaterialCRC(currentMaterial.GetInstanceID(), currentMaterial.ComputeCRC());
                        }
                    }
                }

                // If the mesh was not valid, exclude it (without affecting sidedness)
                if (!validMesh)
                {
                    subMeshFlagArray[meshIdx] = RayTracingSubMeshFlags.Disabled;
                }
            }

            // If the material is considered opaque, every sub-mesh has to be enabled and with unique any hit calls
            if (!materialIsOnlyTransparent && hasTransparentSubMaterial)
            {
                for (int meshIdx = 0; meshIdx < numSubMeshes; ++meshIdx)
                {
                    subMeshFlagArray[meshIdx] = RayTracingSubMeshFlags.Enabled | RayTracingSubMeshFlags.UniqueAnyHitCalls;
                }
            }


            // Propagate the opacity mask only if all sub materials are opaque
            bool isOpaque = !hasTransparentSubMaterial;

            if (isOpaque)
            {
                instanceFlag |= (uint)(RayTracingRendererFlag.Opaque);
            }

            if (rayTracedShadow || pathTracing)
            {
                if (hasTransparentSubMaterial)
                {
                    // Raise the shadow casting flag if needed
                    instanceFlag |= ((currentRenderer.shadowCastingMode != ShadowCastingMode.Off) ? (uint)(RayTracingRendererFlag.CastShadowTransparent) : 0x00);
                }
                else
                {
                    // Raise the shadow casting flag if needed
                    instanceFlag |= ((currentRenderer.shadowCastingMode != ShadowCastingMode.Off) ? (uint)(RayTracingRendererFlag.CastShadowOpaque) : 0x00);
                }
            }

            // We consider a mesh visible by reflection, gi, etc if it is not in the shadow only mode.
            bool meshIsVisible = currentRenderer.shadowCastingMode != ShadowCastingMode.ShadowsOnly;

            if (effectsParameters.ambientOcclusion && !materialIsOnlyTransparent && meshIsVisible)
            {
                // Raise the Ambient Occlusion flag if needed
                instanceFlag |= ((effectsParameters.aoLayerMask & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.AmbientOcclusion) : 0x00;
            }

            if (effectsParameters.reflections && !materialIsOnlyTransparent && meshIsVisible)
            {
                // Raise the Screen Space Reflection flag if needed
                instanceFlag |= ((effectsParameters.reflLayerMask & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.Reflection) : 0x00;
            }

            if (effectsParameters.globalIllumination && !materialIsOnlyTransparent && meshIsVisible)
            {
                // Raise the Global Illumination flag if needed
                instanceFlag |= ((effectsParameters.giLayerMask & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.GlobalIllumination) : 0x00;
            }

            if (effectsParameters.recursiveRendering && meshIsVisible)
            {
                // Raise the Recursive Rendering flag if needed
                instanceFlag |= ((effectsParameters.recursiveLayerMask & objectLayerValue) != 0) ? (uint)(RayTracingRendererFlag.RecursiveRendering) : 0x00;
            }

            if (effectsParameters.pathTracing && meshIsVisible)
            {
                // Raise the Path Tracing flag if needed
                instanceFlag |= (uint)(RayTracingRendererFlag.PathTracing);
            }

            // If the object was not referenced
            if (instanceFlag == 0)
            {
                return(AccelerationStructureStatus.Added);
            }

            // Add it to the acceleration structure
            targetRTAS.AddInstance(currentRenderer, subMeshFlags: subMeshFlagArray, enableTriangleCulling: !doubleSided, mask: instanceFlag);

            // Indicates that a transform has changed in our scene (mesh or light)
            transformDirty |= currentRenderer.transform.hasChanged;
            currentRenderer.transform.hasChanged = false;

            // return the status
            return((!materialIsOnlyTransparent && hasTransparentSubMaterial) ? AccelerationStructureStatus.TransparencyIssue : AccelerationStructureStatus.Added);
        }
        public void BuildRayTracingAccelerationStructure()
        {
            // Clear all the per frame-data
            m_RayTracingRendererReference.Clear();
            m_RayTracingLights.hdDirectionalLightArray.Clear();
            m_RayTracingLights.hdPointLightArray.Clear();
            m_RayTracingLights.hdLineLightArray.Clear();
            m_RayTracingLights.hdRectLightArray.Clear();
            m_RayTracingLights.hdLightArray.Clear();
            m_RayTracingLights.reflectionProbeArray.Clear();
            m_RayTracingLights.lightCount = 0;
            m_CurrentRAS.Dispose();
            m_CurrentRAS             = new RayTracingAccelerationStructure();
            m_ValidRayTracingState   = false;
            m_ValidRayTracingCluster = false;

            bool rayTracedShadow = false;

            // fetch all the lights in the scene
            HDAdditionalLightData[] hdLightArray = UnityEngine.GameObject.FindObjectsOfType <HDAdditionalLightData>();

            for (int lightIdx = 0; lightIdx < hdLightArray.Length; ++lightIdx)
            {
                HDAdditionalLightData hdLight = hdLightArray[lightIdx];
                if (hdLight.enabled)
                {
                    // Check if there is a ray traced shadow in the scene
                    rayTracedShadow |= (hdLight.useRayTracedShadows || (hdLight.useContactShadow.@override && hdLight.rayTraceContactShadow));

                    switch (hdLight.type)
                    {
                    case HDLightType.Directional:
                        m_RayTracingLights.hdDirectionalLightArray.Add(hdLight);
                        break;

                    case HDLightType.Point:
                    case HDLightType.Spot:
                        m_RayTracingLights.hdPointLightArray.Add(hdLight);
                        break;

                    case HDLightType.Area:
                        switch (hdLight.areaLightShape)
                        {
                        case AreaLightShape.Rectangle:
                            m_RayTracingLights.hdRectLightArray.Add(hdLight);
                            break;

                        case AreaLightShape.Tube:
                            m_RayTracingLights.hdLineLightArray.Add(hdLight);
                            break;
                            //TODO: case AreaLightShape.Disc:
                        }
                        break;
                    }
                }
            }

            m_RayTracingLights.hdLightArray.AddRange(m_RayTracingLights.hdPointLightArray);
            m_RayTracingLights.hdLightArray.AddRange(m_RayTracingLights.hdLineLightArray);
            m_RayTracingLights.hdLightArray.AddRange(m_RayTracingLights.hdRectLightArray);

            HDAdditionalReflectionData[] reflectionProbeArray = UnityEngine.GameObject.FindObjectsOfType <HDAdditionalReflectionData>();
            for (int reflIdx = 0; reflIdx < reflectionProbeArray.Length; ++reflIdx)
            {
                HDAdditionalReflectionData reflectionProbe = reflectionProbeArray[reflIdx];
                // Add it to the list if enabled
                if (reflectionProbe.enabled)
                {
                    m_RayTracingLights.reflectionProbeArray.Add(reflectionProbe);
                }
            }

            m_RayTracingLights.lightCount = m_RayTracingLights.hdPointLightArray.Count
                                            + m_RayTracingLights.hdLineLightArray.Count
                                            + m_RayTracingLights.hdRectLightArray.Count
                                            + m_RayTracingLights.reflectionProbeArray.Count;

            AmbientOcclusion      aoSettings          = VolumeManager.instance.stack.GetComponent <AmbientOcclusion>();
            ScreenSpaceReflection reflSettings        = VolumeManager.instance.stack.GetComponent <ScreenSpaceReflection>();
            GlobalIllumination    giSettings          = VolumeManager.instance.stack.GetComponent <GlobalIllumination>();
            RecursiveRendering    recursiveSettings   = VolumeManager.instance.stack.GetComponent <RecursiveRendering>();
            PathTracing           pathTracingSettings = VolumeManager.instance.stack.GetComponent <PathTracing>();

            // Status used to track the errors
            AccelerationStructureStatus status = AccelerationStructureStatus.Clear;

            // First of all let's process all the LOD groups
            LODGroup[] lodGroupArray = UnityEngine.GameObject.FindObjectsOfType <LODGroup>();
            for (var i = 0; i < lodGroupArray.Length; i++)
            {
                // Grab the current LOD group
                LODGroup lodGroup = lodGroupArray[i];

                // Get the set of LODs
                LOD[] lodArray = lodGroup.GetLODs();
                for (int lodIdx = 0; lodIdx < lodArray.Length; ++lodIdx)
                {
                    LOD currentLOD = lodArray[lodIdx];
                    // We only want to push to the acceleration structure the lod0, we do not have defined way to select the right LOD at the moment
                    if (lodIdx == 0)
                    {
                        for (int rendererIdx = 0; rendererIdx < currentLOD.renderers.Length; ++rendererIdx)
                        {
                            // Fetch the renderer that we are interested in
                            Renderer currentRenderer = currentLOD.renderers[rendererIdx];

                            // This objects should but included into the RAS
                            status |= AddInstanceToRAS(currentRenderer,
                                                       rayTracedShadow,
                                                       aoSettings.rayTracing.value, aoSettings.layerMask.value,
                                                       reflSettings.rayTracing.value, reflSettings.layerMask.value,
                                                       giSettings.rayTracing.value, giSettings.layerMask.value,
                                                       recursiveSettings.enable.value, recursiveSettings.layerMask.value,
                                                       pathTracingSettings.enable.value, pathTracingSettings.layerMask.value);
                        }
                    }

                    // Add them to the processed set so that they are not taken into account when processing all the renderers
                    for (int rendererIdx = 0; rendererIdx < currentLOD.renderers.Length; ++rendererIdx)
                    {
                        Renderer currentRenderer = currentLOD.renderers[rendererIdx];
                        // Add this fella to the renderer list
                        m_RayTracingRendererReference.Add(currentRenderer.GetInstanceID(), 1);
                    }
                }
            }

            // Grab all the renderers from the scene
            var rendererArray = UnityEngine.GameObject.FindObjectsOfType <Renderer>();

            for (var i = 0; i < rendererArray.Length; i++)
            {
                // Fetch the current renderer
                Renderer currentRenderer = rendererArray[i];

                // If it is not active skip it
                if (currentRenderer.enabled == false)
                {
                    continue;
                }

                // Grab the current game object
                GameObject gameObject = currentRenderer.gameObject;

                // Has this object already been processed, just skip it
                if (m_RayTracingRendererReference.ContainsKey(currentRenderer.GetInstanceID()))
                {
                    continue;
                }

                // Does this object have a reflection probe component? if yes we do not want to have it in the acceleration structure
                if (gameObject.TryGetComponent <ReflectionProbe>(out reflectionProbe))
                {
                    continue;
                }

                // This objects should but included into the RAS
                status |= AddInstanceToRAS(currentRenderer,
                                           rayTracedShadow,
                                           aoSettings.rayTracing.value, aoSettings.layerMask.value,
                                           reflSettings.rayTracing.value, reflSettings.layerMask.value,
                                           giSettings.rayTracing.value, giSettings.layerMask.value,
                                           recursiveSettings.enable.value, recursiveSettings.layerMask.value,
                                           pathTracingSettings.enable.value, pathTracingSettings.layerMask.value);
            }

            // build the acceleration structure
            m_CurrentRAS.Build();

            // tag the structures as valid
            m_ValidRayTracingState = true;

            // Print a warning in case we hit a transparency issue
            if (((int)status & (int)AccelerationStructureStatus.TransparencyIssue) != 0)
            {
                Debug.LogWarning("An object has both transparent and opaque submeshes. This may cause performance issues");
            }
        }
Пример #16
0
 public void SetRayTracingAccelerationStructure(RayTracingShader rayTracingShader, int nameID, RayTracingAccelerationStructure rayTracingAccelerationStructure)
 {
     Internal_SetRayTracingAccelerationStructure(rayTracingShader, nameID, rayTracingAccelerationStructure);
 }
Пример #17
0
        void RenderPathTracing(HDCamera hdCamera, CommandBuffer cmd, RTHandle outputTexture)
        {
            RayTracingShader pathTracingShader = m_Asset.renderPipelineRayTracingResources.pathTracing;

            m_PathTracingSettings = hdCamera.volumeStack.GetComponent <PathTracing>();

            // Check the validity of the state before moving on with the computation
            if (!pathTracingShader || !m_PathTracingSettings.enable.value)
            {
                return;
            }

            if (hdCamera.viewCount > 1)
            {
                Debug.LogError("Path Tracing is not supported when using XR single-pass rendering.");
                return;
            }

            CheckDirtiness(hdCamera);

            // Inject the ray-tracing sampling data
            BlueNoise blueNoiseManager = GetBlueNoiseManager();

            blueNoiseManager.BindDitheredRNGData256SPP(cmd);

            // Grab the acceleration structure and the list of HD lights for the target camera
            RayTracingAccelerationStructure accelerationStructure = RequestAccelerationStructure();
            HDRaytracingLightCluster        lightCluster          = RequestLightCluster();
            LightCluster lightClusterSettings = hdCamera.volumeStack.GetComponent <LightCluster>();

            if (!m_SubFrameManager.isRecording)
            {
                // If we are recording, the max iteration is set/overridden by the subframe manager, otherwise we read it from the path tracing volume
                m_SubFrameManager.subFrameCount = (uint)m_PathTracingSettings.maximumSamples.value;
            }

#if UNITY_HDRP_DXR_TESTS_DEFINE
            if (Application.isPlaying)
            {
                m_SubFrameManager.subFrameCount = 1;
            }
#endif

            CameraData camData = m_SubFrameManager.GetCameraData(hdCamera.camera.GetInstanceID());
            if (camData.currentIteration < m_SubFrameManager.subFrameCount)
            {
                // Define the shader pass to use for the path tracing pass
                cmd.SetRayTracingShaderPass(pathTracingShader, "PathTracingDXR");

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

                // Inject the ray-tracing sampling data
                cmd.SetGlobalTexture(HDShaderIDs._OwenScrambledTexture, m_Asset.renderPipelineResources.textures.owenScrambled256Tex);
                cmd.SetGlobalTexture(HDShaderIDs._ScramblingTexture, m_Asset.renderPipelineResources.textures.scramblingTex);

                // Update the global constant buffer
                m_ShaderVariablesRayTracingCB._RaytracingNumSamples     = (int)m_SubFrameManager.subFrameCount;
                m_ShaderVariablesRayTracingCB._RaytracingMinRecursion   = m_PathTracingSettings.minimumDepth.value;
                m_ShaderVariablesRayTracingCB._RaytracingMaxRecursion   = m_PathTracingSettings.maximumDepth.value;
                m_ShaderVariablesRayTracingCB._RaytracingIntensityClamp = m_PathTracingSettings.maximumIntensity.value;
                m_ShaderVariablesRayTracingCB._RaytracingSampleIndex    = (int)camData.currentIteration;
                ConstantBuffer.PushGlobal(cmd, m_ShaderVariablesRayTracingCB, HDShaderIDs._ShaderVariablesRaytracing);

                // LightLoop data
                cmd.SetGlobalBuffer(HDShaderIDs._RaytracingLightCluster, lightCluster.GetCluster());
                cmd.SetGlobalBuffer(HDShaderIDs._LightDatasRT, lightCluster.GetLightDatas());

                // Set the data for the ray miss
                cmd.SetRayTracingIntParam(pathTracingShader, HDShaderIDs._RaytracingCameraSkyEnabled, camData.skyEnabled ? 1 : 0);
                cmd.SetRayTracingVectorParam(pathTracingShader, HDShaderIDs._RaytracingCameraClearColor, hdCamera.backgroundColorHDR);
                cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._SkyTexture, m_SkyManager.GetSkyReflection(hdCamera));

                // Additional data for path tracing
                cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._RadianceTexture, m_RadianceTexture);
                cmd.SetRayTracingMatrixParam(pathTracingShader, HDShaderIDs._PixelCoordToViewDirWS, hdCamera.mainViewConstants.pixelCoordToViewDirWS);
                cmd.SetRayTracingVectorParam(pathTracingShader, HDShaderIDs._PathTracedDoFConstants, ComputeDoFConstants(hdCamera, m_PathTracingSettings));

                // Run the computation
                cmd.DispatchRays(pathTracingShader, "RayGen", (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, 1);
            }
            RenderAccumulation(hdCamera, m_RadianceTexture, outputTexture, true, cmd);
        }
        public void RenderAO(HDCamera hdCamera, CommandBuffer cmd, RTHandleSystem.RTHandle outputTexture, ScriptableRenderContext renderContext, int frameCount)
        {
            // Let's check all the resources
            HDRaytracingEnvironment rtEnvironment = m_RaytracingManager.CurrentEnvironment();
            RayTracingShader        aoShader      = m_PipelineRayTracingResources.aoRaytracing;
            var aoSettings = VolumeManager.instance.stack.GetComponent <AmbientOcclusion>();

            // Check if the state is valid for evaluating ambient occlusion
            bool invalidState = rtEnvironment == null ||
                                aoShader == null ||
                                m_PipelineResources.textures.owenScrambledTex == null || m_PipelineResources.textures.scramblingTex == null;

            // If any of the previous requirements is missing, the effect is not requested or no acceleration structure, set the default one and leave right away
            if (invalidState)
            {
                SetDefaultAmbientOcclusionTexture(cmd);
                return;
            }

            // Grab the acceleration structure for the target camera
            RayTracingAccelerationStructure accelerationStructure = m_RaytracingManager.RequestAccelerationStructure(rtEnvironment.aoLayerMask);

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

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

            // Inject the ray-tracing sampling data
            cmd.SetRayTracingTextureParam(aoShader, HDShaderIDs._OwenScrambledTexture, m_PipelineResources.textures.owenScrambledTex);
            cmd.SetRayTracingTextureParam(aoShader, HDShaderIDs._ScramblingTexture, m_PipelineResources.textures.scramblingTex);

            // Inject the ray generation data
            cmd.SetRayTracingFloatParams(aoShader, HDShaderIDs._RaytracingRayBias, rtEnvironment.rayBias);
            cmd.SetRayTracingFloatParams(aoShader, HDShaderIDs._RaytracingRayMaxLength, aoSettings.rayLength.value);
            cmd.SetRayTracingIntParams(aoShader, HDShaderIDs._RaytracingNumSamples, aoSettings.numSamples.value);

            // Set the data for the ray generation
            cmd.SetRayTracingTextureParam(aoShader, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
            cmd.SetRayTracingTextureParam(aoShader, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer());
            int frameIndex = hdCamera.IsTAAEnabled() ? hdCamera.taaFrameIndex : (int)frameCount % 8;

            cmd.SetGlobalInt(HDShaderIDs._RaytracingFrameIndex, frameIndex);

            // Value used to scale the ao intensity
            cmd.SetRayTracingFloatParam(aoShader, HDShaderIDs._RaytracingAOIntensity, aoSettings.intensity.value);

            cmd.SetRayTracingIntParam(aoShader, HDShaderIDs._RayCountEnabled, m_RaytracingManager.rayCountManager.RayCountIsEnabled());
            cmd.SetRayTracingTextureParam(aoShader, HDShaderIDs._RayCountTexture, m_RaytracingManager.rayCountManager.rayCountTexture);

            // Set the output textures
            cmd.SetRayTracingTextureParam(aoShader, HDShaderIDs._AmbientOcclusionTextureRW, m_IntermediateBuffer);
            cmd.SetRayTracingTextureParam(aoShader, HDShaderIDs._RaytracingVSNormalTexture, m_ViewSpaceNormalBuffer);

            // Run the computation
            cmd.DispatchRays(aoShader, m_RayGenShaderName, (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, 1);

            using (new ProfilingSample(cmd, "Filter Reflection", CustomSamplerId.RaytracingAmbientOcclusion.GetSampler()))
            {
                if (aoSettings.enableFilter.value)
                {
                    // Grab the history buffer
                    RTHandleSystem.RTHandle ambientOcclusionHistory = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedAmbientOcclusion)
                                                                      ?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedAmbientOcclusion, AmbientOcclusionHistoryBufferAllocatorFunction, 1);

                    // Apply the simple denoiser
                    HDSimpleDenoiser simpleDenoiser = m_RaytracingManager.GetSimpleDenoiser();
                    simpleDenoiser.DenoiseBuffer(cmd, hdCamera, m_IntermediateBuffer, ambientOcclusionHistory, outputTexture, aoSettings.filterRadius.value, singleChannel: true);
                }
                else
                {
                    HDUtils.BlitCameraTexture(cmd, m_IntermediateBuffer, outputTexture);
                }
            }

            // Bind the textures and the params
            cmd.SetGlobalTexture(HDShaderIDs._AmbientOcclusionTexture, outputTexture);
            cmd.SetGlobalVector(HDShaderIDs._AmbientOcclusionParam, new Vector4(0f, 0f, 0f, VolumeManager.instance.stack.GetComponent <AmbientOcclusion>().directLightingStrength.value));

            // TODO: All the push-debug stuff should be centralized somewhere
            (RenderPipelineManager.currentPipeline as HDRenderPipeline).PushFullScreenDebugTexture(hdCamera, cmd, outputTexture, FullScreenDebugMode.SSAO);
        }
Пример #19
0
        bool RenderAreaShadows(HDCamera hdCamera, CommandBuffer cmd, int frameCount)
        {
            // Let's check all the resources and states to see if we should render the effect
            HDRaytracingEnvironment rtEnvironment = m_RayTracingManager.CurrentEnvironment();
            BlueNoise blueNoise = m_RayTracingManager.GetBlueNoiseManager();

            // Make sure everything is valid
            bool invalidState = !hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) ||
                                rtEnvironment == null ||
                                hdCamera.frameSettings.litShaderMode != LitShaderMode.Deferred;

            // If invalid state or ray-tracing acceleration structure, we stop right away
            if (invalidState)
            {
                return(false);
            }

            RayTracingShader shadowRayTrace = m_Asset.renderPipelineRayTracingResources.shadowRaytracingRT;
            ComputeShader    shadowsCompute = m_Asset.renderPipelineRayTracingResources.shadowRaytracingCS;
            ComputeShader    shadowFilter   = m_Asset.renderPipelineRayTracingResources.shadowFilterCS;

            // Grab the TAA history buffers (SN/UN and Analytic value)
            RTHandle shadowHistoryArray = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedShadow)
                                          ?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedShadow, ShadowHistoryBufferAllocatorFunction, 1);
            RTHandle areaAnalyticHistoryArray = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedAreaAnalytic)
                                                ?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedAreaAnalytic, AreaAnalyticHistoryBufferAllocatorFunction, 1);

            // Grab the acceleration structure for the target camera
            RayTracingAccelerationStructure accelerationStructure = m_RayTracingManager.RequestAccelerationStructure(rtEnvironment.shadowLayerMask);

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

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

            // Inject the ray-tracing sampling data
            blueNoise.BindDitheredRNGData8SPP(cmd);

            int frameIndex = hdCamera.IsTAAEnabled() ? hdCamera.taaFrameIndex : (int)frameCount % 8;

            cmd.SetGlobalInt(HDShaderIDs._RaytracingFrameIndex, frameIndex);

            // Temporal Filtering kernels
            int applyTAAKernel        = shadowFilter.FindKernel("AreaShadowApplyTAA");
            int updateAnalyticHistory = shadowFilter.FindKernel("AreaAnalyticHistoryCopy");
            int updateShadowHistory   = shadowFilter.FindKernel("AreaShadowHistoryCopy");

            // Spatial Filtering kernels
            int estimateNoiseKernel = shadowFilter.FindKernel("AreaShadowEstimateNoise");
            int firstDenoiseKernel  = shadowFilter.FindKernel("AreaShadowDenoiseFirstPass");
            int secondDenoiseKernel = shadowFilter.FindKernel("AreaShadowDenoiseSecondPass");

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

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

            // Inject the ray generation data
            cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayBias, rtEnvironment.rayBias);

            int numLights = m_lightList.lights.Count;

            for (int lightIdx = 0; lightIdx < numLights; ++lightIdx)
            {
                // If this is not a rectangular area light or it won't have shadows, skip it
                if (m_lightList.lights[lightIdx].lightType != GPULightType.Rectangle || m_lightList.lights[lightIdx].screenSpaceShadowIndex == -1)
                {
                    continue;
                }

                LightData             currentLight = m_lightList.lights[lightIdx];
                HDAdditionalLightData currentAdditionalLightData = GetCurrentRayTracedShadow(currentLight.screenSpaceShadowIndex);

                using (new ProfilingSample(cmd, "Ray Traced Area Shadow", CustomSamplerId.RaytracingShadowIntegration.GetSampler()))
                {
                    // We need to build the world to area light matrix
                    worldToLocalArea.SetColumn(0, currentLight.right);
                    worldToLocalArea.SetColumn(1, currentLight.up);
                    worldToLocalArea.SetColumn(2, currentLight.forward);

                    // Compensate the  relative rendering if active
                    Vector3 lightPositionWS = currentLight.positionRWS;
                    if (ShaderConfig.s_CameraRelativeRendering != 0)
                    {
                        lightPositionWS += hdCamera.camera.transform.position;
                    }
                    worldToLocalArea.SetColumn(3, lightPositionWS);
                    worldToLocalArea.m33 = 1.0f;
                    worldToLocalArea     = worldToLocalArea.inverse;

                    // We have noticed from extensive profiling that ray-trace shaders are not as effective for running per-pixel computation. In order to reduce that,
                    // we do a first prepass that compute the analytic term and probability and generates the first integration sample
                    if (true)
                    {
                        int shadowComputeKernel = shadowsCompute.FindKernel("RaytracingAreaShadowPrepass");

                        // This pass evaluates the analytic value and the generates and outputs the first sample
                        cmd.SetComputeBufferParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._LightDatas, m_LightLoopLightData.lightData);
                        cmd.SetComputeIntParam(shadowsCompute, HDShaderIDs._RaytracingTargetAreaLight, lightIdx);
                        cmd.SetComputeIntParam(shadowsCompute, HDShaderIDs._RaytracingNumSamples, currentAdditionalLightData.numRayTracingSamples);
                        cmd.SetComputeMatrixParam(shadowsCompute, HDShaderIDs._RaytracingAreaWorldToLocal, worldToLocalArea);
                        cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
                        cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer());
                        cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._GBufferTexture[0], m_GbufferManager.GetBuffer(0));
                        cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._GBufferTexture[1], m_GbufferManager.GetBuffer(1));
                        cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._GBufferTexture[2], m_GbufferManager.GetBuffer(2));
                        cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._GBufferTexture[3], m_GbufferManager.GetBuffer(3));
                        cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._AreaCookieTextures, m_TextureCaches.areaLightCookieManager.GetTexCache());
                        cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._RaytracedAreaShadowIntegration, m_DenoiseBuffer0);
                        cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._RaytracedAreaShadowSample, m_DenoiseBuffer1);
                        cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._RaytracingDirectionBuffer, m_RaytracingDirectionBuffer);
                        cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._RaytracingDistanceBuffer, m_RaytracingDistanceBuffer);
                        cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._AnalyticProbBuffer, m_AnalyticProbBuffer);
                        cmd.DispatchCompute(shadowsCompute, shadowComputeKernel, numTilesX, numTilesY, 1);

                        // This pass will use the previously generated sample and add it to the integration buffer
                        cmd.SetRayTracingBufferParam(shadowRayTrace, HDShaderIDs._LightDatas, m_LightLoopLightData.lightData);
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._RaytracedAreaShadowSample, m_DenoiseBuffer1);
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._RaytracedAreaShadowIntegration, m_DenoiseBuffer0);
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._RaytracingDirectionBuffer, m_RaytracingDirectionBuffer);
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._RaytracingDistanceBuffer, m_RaytracingDistanceBuffer);
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._AnalyticProbBuffer, m_AnalyticProbBuffer);
                        cmd.DispatchRays(shadowRayTrace, m_RayGenAreaShadowSingleName, (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, 1);

                        // Let's do the following samples (if any)
                        for (int sampleIndex = 1; sampleIndex < currentAdditionalLightData.numRayTracingSamples; ++sampleIndex)
                        {
                            shadowComputeKernel = shadowsCompute.FindKernel("RaytracingAreaShadowNewSample");

                            // This pass generates a new sample based on the initial pre-pass
                            cmd.SetComputeBufferParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._LightDatas, m_LightLoopLightData.lightData);
                            cmd.SetComputeIntParam(shadowsCompute, HDShaderIDs._RaytracingTargetAreaLight, lightIdx);
                            cmd.SetComputeIntParam(shadowsCompute, HDShaderIDs._RaytracingNumSamples, currentAdditionalLightData.numRayTracingSamples);
                            cmd.SetComputeIntParam(shadowsCompute, HDShaderIDs._RaytracingSampleIndex, sampleIndex);
                            cmd.SetComputeMatrixParam(shadowsCompute, HDShaderIDs._RaytracingAreaWorldToLocal, worldToLocalArea);
                            cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
                            cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer());
                            cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._GBufferTexture[0], m_GbufferManager.GetBuffer(0));
                            cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._GBufferTexture[1], m_GbufferManager.GetBuffer(1));
                            cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._GBufferTexture[2], m_GbufferManager.GetBuffer(2));
                            cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._GBufferTexture[3], m_GbufferManager.GetBuffer(3));
                            cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._AreaCookieTextures, m_TextureCaches.areaLightCookieManager.GetTexCache());
                            cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._RaytracedAreaShadowIntegration, m_DenoiseBuffer0);
                            cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._RaytracedAreaShadowSample, m_DenoiseBuffer1);
                            cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._RaytracingDirectionBuffer, m_RaytracingDirectionBuffer);
                            cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._RaytracingDistanceBuffer, m_RaytracingDistanceBuffer);
                            cmd.SetComputeTextureParam(shadowsCompute, shadowComputeKernel, HDShaderIDs._AnalyticProbBuffer, m_AnalyticProbBuffer);
                            cmd.DispatchCompute(shadowsCompute, shadowComputeKernel, numTilesX, numTilesY, 1);

                            // This pass will use the previously generated sample and add it to the integration buffer
                            cmd.SetRayTracingBufferParam(shadowRayTrace, HDShaderIDs._LightDatas, m_LightLoopLightData.lightData);
                            cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
                            cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._RaytracedAreaShadowSample, m_DenoiseBuffer1);
                            cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._RaytracedAreaShadowIntegration, m_DenoiseBuffer0);
                            cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._RaytracingDirectionBuffer, m_RaytracingDirectionBuffer);
                            cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._RaytracingDistanceBuffer, m_RaytracingDistanceBuffer);
                            cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._AnalyticProbBuffer, m_AnalyticProbBuffer);
                            cmd.DispatchRays(shadowRayTrace, m_RayGenAreaShadowSingleName, (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, 1);
                        }
                    }
                    else
                    {
                        // This pass generates the analytic value and will do the full integration
                        cmd.SetRayTracingBufferParam(shadowRayTrace, HDShaderIDs._LightDatas, m_LightLoopLightData.lightData);
                        cmd.SetRayTracingIntParam(shadowRayTrace, HDShaderIDs._RaytracingTargetAreaLight, lightIdx);
                        cmd.SetRayTracingIntParam(shadowRayTrace, HDShaderIDs._RaytracingNumSamples, currentAdditionalLightData.numRayTracingSamples);
                        cmd.SetRayTracingMatrixParam(shadowRayTrace, HDShaderIDs._RaytracingAreaWorldToLocal, worldToLocalArea);
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer());
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._GBufferTexture[0], m_GbufferManager.GetBuffer(0));
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._GBufferTexture[1], m_GbufferManager.GetBuffer(1));
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._GBufferTexture[2], m_GbufferManager.GetBuffer(2));
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._GBufferTexture[3], m_GbufferManager.GetBuffer(3));
                        cmd.SetRayTracingIntParam(shadowRayTrace, HDShaderIDs._RayCountEnabled, m_RayTracingManager.rayCountManager.RayCountIsEnabled());
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._RayCountTexture, m_RayTracingManager.rayCountManager.GetRayCountTexture());
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._AreaCookieTextures, m_TextureCaches.areaLightCookieManager.GetTexCache());
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._AnalyticProbBuffer, m_AnalyticProbBuffer);
                        cmd.SetRayTracingTextureParam(shadowRayTrace, HDShaderIDs._RaytracedAreaShadowIntegration, m_DenoiseBuffer0);
                        cmd.DispatchRays(shadowRayTrace, m_RayGenAreaShadowName, (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, 1);
                    }
                }

                using (new ProfilingSample(cmd, "Combine Area Shadow", CustomSamplerId.RaytracingShadowCombination.GetSampler()))
                {
                    // Global parameters
                    cmd.SetComputeIntParam(shadowFilter, HDShaderIDs._RaytracingDenoiseRadius, currentAdditionalLightData.filterSizeTraced);
                    cmd.SetComputeIntParam(shadowFilter, HDShaderIDs._RaytracingShadowSlot, m_lightList.lights[lightIdx].screenSpaceShadowIndex);

                    // Apply a vectorized temporal filtering pass and store it back in the denoisebuffer0 with the analytic value in the third channel
                    var historyScale = new Vector2(hdCamera.actualWidth / (float)shadowHistoryArray.rt.width, hdCamera.actualHeight / (float)shadowHistoryArray.rt.height);
                    cmd.SetComputeVectorParam(shadowFilter, HDShaderIDs._RTHandleScaleHistory, historyScale);

                    cmd.SetComputeTextureParam(shadowFilter, applyTAAKernel, HDShaderIDs._AnalyticProbBuffer, m_AnalyticProbBuffer);
                    cmd.SetComputeTextureParam(shadowFilter, applyTAAKernel, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
                    cmd.SetComputeTextureParam(shadowFilter, applyTAAKernel, HDShaderIDs._AreaShadowHistory, shadowHistoryArray);
                    cmd.SetComputeTextureParam(shadowFilter, applyTAAKernel, HDShaderIDs._AnalyticHistoryBuffer, areaAnalyticHistoryArray);
                    cmd.SetComputeTextureParam(shadowFilter, applyTAAKernel, HDShaderIDs._DenoiseInputTexture, m_DenoiseBuffer0);
                    cmd.SetComputeTextureParam(shadowFilter, applyTAAKernel, HDShaderIDs._DenoiseOutputTextureRW, m_DenoiseBuffer1);
                    cmd.DispatchCompute(shadowFilter, applyTAAKernel, numTilesX, numTilesY, 1);

                    // Update the shadow history buffer
                    cmd.SetComputeTextureParam(shadowFilter, updateAnalyticHistory, HDShaderIDs._AnalyticProbBuffer, m_AnalyticProbBuffer);
                    cmd.SetComputeTextureParam(shadowFilter, updateAnalyticHistory, HDShaderIDs._AnalyticHistoryBuffer, areaAnalyticHistoryArray);
                    cmd.DispatchCompute(shadowFilter, updateAnalyticHistory, numTilesX, numTilesY, 1);

                    // Update the analytic history buffer
                    cmd.SetComputeTextureParam(shadowFilter, updateShadowHistory, HDShaderIDs._DenoiseInputTexture, m_DenoiseBuffer1);
                    cmd.SetComputeTextureParam(shadowFilter, updateShadowHistory, HDShaderIDs._AreaShadowHistoryRW, shadowHistoryArray);
                    cmd.DispatchCompute(shadowFilter, updateShadowHistory, numTilesX, numTilesY, 1);

                    if (currentAdditionalLightData.filterSizeTraced > 0)
                    {
                        // Inject parameters for noise estimation
                        cmd.SetComputeTextureParam(shadowFilter, estimateNoiseKernel, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
                        cmd.SetComputeTextureParam(shadowFilter, estimateNoiseKernel, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer());
                        cmd.SetComputeTextureParam(shadowFilter, estimateNoiseKernel, HDShaderIDs._ScramblingTexture, m_Asset.renderPipelineResources.textures.scramblingTex);

                        // Noise estimation pre-pass
                        cmd.SetComputeTextureParam(shadowFilter, estimateNoiseKernel, HDShaderIDs._DenoiseInputTexture, m_DenoiseBuffer1);
                        cmd.SetComputeTextureParam(shadowFilter, estimateNoiseKernel, HDShaderIDs._DenoiseOutputTextureRW, m_DenoiseBuffer0);
                        cmd.DispatchCompute(shadowFilter, estimateNoiseKernel, numTilesX, numTilesY, 1);

                        // Reinject parameters for denoising
                        cmd.SetComputeTextureParam(shadowFilter, firstDenoiseKernel, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
                        cmd.SetComputeTextureParam(shadowFilter, firstDenoiseKernel, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer());
                        cmd.SetComputeTextureParam(shadowFilter, firstDenoiseKernel, HDShaderIDs._ScreenSpaceShadowsTextureRW, m_ScreenSpaceShadowTextureArray);

                        // First denoising pass
                        cmd.SetComputeTextureParam(shadowFilter, firstDenoiseKernel, HDShaderIDs._DenoiseInputTexture, m_DenoiseBuffer0);
                        cmd.SetComputeTextureParam(shadowFilter, firstDenoiseKernel, HDShaderIDs._DenoiseOutputTextureRW, m_DenoiseBuffer1);
                        cmd.DispatchCompute(shadowFilter, firstDenoiseKernel, numTilesX, numTilesY, 1);
                    }

                    // Re-inject parameters for denoising
                    cmd.SetComputeTextureParam(shadowFilter, secondDenoiseKernel, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer());
                    cmd.SetComputeTextureParam(shadowFilter, secondDenoiseKernel, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer());
                    cmd.SetComputeTextureParam(shadowFilter, secondDenoiseKernel, HDShaderIDs._ScreenSpaceShadowsTextureRW, m_ScreenSpaceShadowTextureArray);

                    // Second (and final) denoising pass
                    cmd.SetComputeTextureParam(shadowFilter, secondDenoiseKernel, HDShaderIDs._DenoiseInputTexture, m_DenoiseBuffer1);
                    cmd.DispatchCompute(shadowFilter, secondDenoiseKernel, numTilesX, numTilesY, 1);
                }
            }
            return(true);
        }
        void RenderSubsurfaceScattering(HDCamera hdCamera, CommandBuffer cmd, RTHandle colorBufferRT,
                                        RTHandle diffuseBufferRT, RTHandle depthStencilBufferRT, RTHandle depthTextureRT)
        {
            if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.SubsurfaceScattering))
            {
                return;
            }

            BuildCoarseStencilAndResolveIfNeeded(hdCamera, cmd);

            var settings = hdCamera.volumeStack.GetComponent <SubSurfaceScattering>();

            // If ray tracing is enabled for the camera, if the volume override is active and if the RAS is built, we want to do ray traced SSS
            if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && settings.rayTracing.value && GetRayTracingState())
            {
                using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.SubsurfaceScattering)))
                {
                    // Evaluate the dispatch parameters
                    int areaTileSize = 8;
                    int numTilesXHR  = (hdCamera.actualWidth + (areaTileSize - 1)) / areaTileSize;
                    int numTilesYHR  = (hdCamera.actualHeight + (areaTileSize - 1)) / areaTileSize;

                    // Clear the integration texture first
                    cmd.SetComputeTextureParam(m_ScreenSpaceShadowsCS, m_ClearShadowTexture, HDShaderIDs._RaytracedShadowIntegration, diffuseBufferRT);
                    cmd.DispatchCompute(m_ScreenSpaceShadowsCS, m_ClearShadowTexture, numTilesXHR, numTilesYHR, hdCamera.viewCount);

                    // Fetch the volume overrides that we shall be using
                    RayTracingShader   subSurfaceShader   = m_Asset.renderPipelineRayTracingResources.subSurfaceRayTracing;
                    RayTracingSettings rayTracingSettings = hdCamera.volumeStack.GetComponent <RayTracingSettings>();
                    ComputeShader      deferredRayTracing = m_Asset.renderPipelineRayTracingResources.deferredRaytracingCS;

                    // Fetch all the intermediate buffers that we need
                    RTHandle intermediateBuffer0 = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA0);
                    RTHandle intermediateBuffer1 = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA1);
                    RTHandle intermediateBuffer2 = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA2);
                    RTHandle intermediateBuffer3 = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA3);
                    RTHandle directionBuffer     = GetRayTracingBuffer(InternalRayTracingBuffers.Direction);

                    // Grab the acceleration structure for the target camera
                    RayTracingAccelerationStructure accelerationStructure = RequestAccelerationStructure();

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

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

                    // Inject the ray-tracing sampling data
                    BlueNoise blueNoise = GetBlueNoiseManager();
                    blueNoise.BindDitheredRNGData8SPP(cmd);

                    // For every sample that we need to process
                    for (int sampleIndex = 0; sampleIndex < settings.sampleCount.value; ++sampleIndex)
                    {
                        // Inject the ray generation data
                        cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayBias, rayTracingSettings.rayBias.value);
                        cmd.SetGlobalInt(HDShaderIDs._RaytracingNumSamples, settings.sampleCount.value);
                        cmd.SetGlobalInt(HDShaderIDs._RaytracingSampleIndex, sampleIndex);
                        int frameIndex = RayTracingFrameIndex(hdCamera);
                        cmd.SetGlobalInt(HDShaderIDs._RaytracingFrameIndex, frameIndex);

                        // Bind the textures for ray generation
                        cmd.SetRayTracingTextureParam(subSurfaceShader, HDShaderIDs._DepthTexture, sharedRTManager.GetDepthStencilBuffer());
                        cmd.SetRayTracingTextureParam(subSurfaceShader, HDShaderIDs._NormalBufferTexture, sharedRTManager.GetNormalBuffer());
                        cmd.SetRayTracingTextureParam(subSurfaceShader, HDShaderIDs._SSSBufferTexture, m_SSSColor);
                        cmd.SetGlobalTexture(HDShaderIDs._StencilTexture, sharedRTManager.GetDepthStencilBuffer(), RenderTextureSubElement.Stencil);

                        // Set the output textures
                        cmd.SetRayTracingTextureParam(subSurfaceShader, HDShaderIDs._ThroughputTextureRW, intermediateBuffer0);
                        cmd.SetRayTracingTextureParam(subSurfaceShader, HDShaderIDs._NormalTextureRW, intermediateBuffer1);
                        cmd.SetRayTracingTextureParam(subSurfaceShader, HDShaderIDs._PositionTextureRW, intermediateBuffer2);
                        cmd.SetRayTracingTextureParam(subSurfaceShader, HDShaderIDs._DiffuseLightingTextureRW, intermediateBuffer3);
                        cmd.SetRayTracingTextureParam(subSurfaceShader, HDShaderIDs._DirectionTextureRW, directionBuffer);

                        // Run the computation
                        cmd.DispatchRays(subSurfaceShader, m_RayGenSubSurfaceShaderName, (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, (uint)hdCamera.viewCount);

                        // Now let's do the deferred shading pass on the samples
                        // TODO: Do this only once in the init pass
                        int currentKernel = deferredRayTracing.FindKernel("RaytracingDiffuseDeferred");

                        // Bind the lightLoop data
                        HDRaytracingLightCluster lightCluster = RequestLightCluster();
                        lightCluster.BindLightClusterData(cmd);

                        // Bind the input textures
                        cmd.SetComputeTextureParam(deferredRayTracing, currentKernel, HDShaderIDs._DepthTexture, sharedRTManager.GetDepthStencilBuffer());
                        cmd.SetComputeTextureParam(deferredRayTracing, currentKernel, HDShaderIDs._ThroughputTextureRW, intermediateBuffer0);
                        cmd.SetComputeTextureParam(deferredRayTracing, currentKernel, HDShaderIDs._NormalTextureRW, intermediateBuffer1);
                        cmd.SetComputeTextureParam(deferredRayTracing, currentKernel, HDShaderIDs._PositionTextureRW, intermediateBuffer2);
                        cmd.SetComputeTextureParam(deferredRayTracing, currentKernel, HDShaderIDs._DirectionTextureRW, directionBuffer);
                        cmd.SetComputeTextureParam(deferredRayTracing, currentKernel, HDShaderIDs._DiffuseLightingTextureRW, intermediateBuffer3);

                        // Bind the output texture (it is used for accumulation read and write)
                        cmd.SetComputeTextureParam(deferredRayTracing, currentKernel, HDShaderIDs._RaytracingLitBufferRW, diffuseBufferRT);

                        // Compute the Lighting
                        cmd.DispatchCompute(deferredRayTracing, currentKernel, numTilesXHR, numTilesYHR, hdCamera.viewCount);
                    }

                    // 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 = 1.0f;
#if UNITY_HDRP_DXR_TESTS_DEFINE
                    if (Application.isPlaying)
                    {
                        historyValidity = 0.0f;
                    }
                    else
#endif
                    // We need to check if something invalidated the history buffers
                    historyValidity *= ValidRayTracingHistory(hdCamera) ? 1.0f : 0.0f;

                    // Apply temporal filtering to the buffer
                    HDTemporalFilter temporalFilter = GetTemporalFilter();
                    temporalFilter.DenoiseBuffer(cmd, hdCamera, diffuseBufferRT, subsurfaceHistory, intermediateBuffer0, singleChannel: false, historyValidity: historyValidity);

                    // Push this version of the texture for debug
                    PushFullScreenDebugTexture(hdCamera, cmd, intermediateBuffer0, FullScreenDebugMode.RayTracedSubSurface);

                    // Combine it with the rest of the lighting
                    m_CombineLightingPass.SetTexture(HDShaderIDs._IrradianceSource, intermediateBuffer0);
                    HDUtils.DrawFullScreen(cmd, m_CombineLightingPass, colorBufferRT, depthStencilBufferRT, shaderPassId: 1);
                }
            }
            else
            {
                using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.SubsurfaceScattering)))
                {
                    var parameters = PrepareSubsurfaceScatteringParameters(hdCamera);
                    var resources  = new SubsurfaceScatteringResources();
                    resources.colorBuffer           = colorBufferRT;
                    resources.diffuseBuffer         = diffuseBufferRT;
                    resources.depthStencilBuffer    = depthStencilBufferRT;
                    resources.depthTexture          = depthTextureRT;
                    resources.cameraFilteringBuffer = m_SSSCameraFilteringBuffer;
                    resources.coarseStencilBuffer   = parameters.coarseStencilBuffer;
                    resources.sssBuffer             = m_SSSColor;

                    // For Jimenez we always need an extra buffer, for Disney it depends on platform
                    if (parameters.needTemporaryBuffer)
                    {
                        // Clear the SSS filtering target
                        using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.ClearSSSFilteringTarget)))
                        {
                            CoreUtils.SetRenderTarget(cmd, m_SSSCameraFilteringBuffer, ClearFlag.Color, Color.clear);
                        }
                    }

                    RenderSubsurfaceScattering(parameters, resources, cmd);
                }
            }
        }
Пример #21
0
        internal void BuildRayTracingAccelerationStructure(HDCamera hdCamera)
        {
            // Clear all the per frame-data
            m_RayTracingRendererReference.Clear();
            m_RayTracingLights.hdDirectionalLightArray.Clear();
            m_RayTracingLights.hdPointLightArray.Clear();
            m_RayTracingLights.hdLineLightArray.Clear();
            m_RayTracingLights.hdRectLightArray.Clear();
            m_RayTracingLights.hdLightArray.Clear();
            m_RayTracingLights.reflectionProbeArray.Clear();
            m_RayTracingLights.lightCount = 0;
            m_CurrentRAS.Dispose();
            m_CurrentRAS                      = new RayTracingAccelerationStructure();
            m_ValidRayTracingState            = false;
            m_ValidRayTracingCluster          = false;
            m_ValidRayTracingClusterCulling   = false;
            m_RayTracedShadowsRequired        = false;
            m_RayTracedContactShadowsRequired = false;

            // If the camera does not have a ray tracing frame setting or it is a preview camera (due to the fact that the sphere does not exist as a game object we can't create the RTAS) we do not want to build a RTAS
            if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing))
            {
                return;
            }

            // We only support ray traced shadows if the camera supports ray traced shadows
            bool screenSpaceShadowsSupported = hdCamera.frameSettings.IsEnabled(FrameSettingsField.ScreenSpaceShadows);

            // fetch all the lights in the scene
            HDAdditionalLightData[] hdLightArray = UnityEngine.GameObject.FindObjectsOfType <HDAdditionalLightData>();

            for (int lightIdx = 0; lightIdx < hdLightArray.Length; ++lightIdx)
            {
                HDAdditionalLightData hdLight = hdLightArray[lightIdx];
                if (hdLight.enabled)
                {
                    // Check if there is a ray traced shadow in the scene
                    m_RayTracedShadowsRequired        |= (hdLight.useRayTracedShadows && screenSpaceShadowsSupported);
                    m_RayTracedContactShadowsRequired |= (hdLight.useContactShadow.@override && hdLight.rayTraceContactShadow);

                    // Indicates that a transform has changed in our scene (mesh or light)
                    m_TransformDirty            |= hdLight.transform.hasChanged;
                    hdLight.transform.hasChanged = false;

                    switch (hdLight.type)
                    {
                    case HDLightType.Directional:
                        m_RayTracingLights.hdDirectionalLightArray.Add(hdLight);
                        break;

                    case HDLightType.Point:
                    case HDLightType.Spot:
                        m_RayTracingLights.hdPointLightArray.Add(hdLight);
                        break;

                    case HDLightType.Area:
                        switch (hdLight.areaLightShape)
                        {
                        case AreaLightShape.Rectangle:
                            m_RayTracingLights.hdRectLightArray.Add(hdLight);
                            break;

                        case AreaLightShape.Tube:
                            m_RayTracingLights.hdLineLightArray.Add(hdLight);
                            break;
                            //TODO: case AreaLightShape.Disc:
                        }
                        break;
                    }
                }
            }

            // Aggregate the shadow requirement
            bool rayTracedShadows = m_RayTracedShadowsRequired || m_RayTracedContactShadowsRequired;

            m_RayTracingLights.hdLightArray.AddRange(m_RayTracingLights.hdPointLightArray);
            m_RayTracingLights.hdLightArray.AddRange(m_RayTracingLights.hdLineLightArray);
            m_RayTracingLights.hdLightArray.AddRange(m_RayTracingLights.hdRectLightArray);

            HDAdditionalReflectionData[] reflectionProbeArray = UnityEngine.GameObject.FindObjectsOfType <HDAdditionalReflectionData>();
            for (int reflIdx = 0; reflIdx < reflectionProbeArray.Length; ++reflIdx)
            {
                HDAdditionalReflectionData reflectionProbe = reflectionProbeArray[reflIdx];
                // Add it to the list if enabled
                if (reflectionProbe.enabled)
                {
                    m_RayTracingLights.reflectionProbeArray.Add(reflectionProbe);
                }
            }

            m_RayTracingLights.lightCount = m_RayTracingLights.hdPointLightArray.Count
                                            + m_RayTracingLights.hdLineLightArray.Count
                                            + m_RayTracingLights.hdRectLightArray.Count
                                            + m_RayTracingLights.reflectionProbeArray.Count;

            AmbientOcclusion      aoSettings          = hdCamera.volumeStack.GetComponent <AmbientOcclusion>();
            bool                  rtAOEnabled         = aoSettings.rayTracing.value && hdCamera.frameSettings.IsEnabled(FrameSettingsField.SSAO);
            ScreenSpaceReflection reflSettings        = hdCamera.volumeStack.GetComponent <ScreenSpaceReflection>();
            bool                  rtREnabled          = reflSettings.enabled.value && reflSettings.rayTracing.value && hdCamera.frameSettings.IsEnabled(FrameSettingsField.SSR);
            GlobalIllumination    giSettings          = hdCamera.volumeStack.GetComponent <GlobalIllumination>();
            bool                  rtGIEnabled         = giSettings.enable.value && giSettings.rayTracing.value && hdCamera.frameSettings.IsEnabled(FrameSettingsField.SSGI);
            RecursiveRendering    recursiveSettings   = hdCamera.volumeStack.GetComponent <RecursiveRendering>();
            bool                  rrEnabled           = recursiveSettings.enable.value;
            SubSurfaceScattering  sssSettings         = hdCamera.volumeStack.GetComponent <SubSurfaceScattering>();
            bool                  rtSSSEnabled        = sssSettings.rayTracing.value && hdCamera.frameSettings.IsEnabled(FrameSettingsField.SubsurfaceScattering);
            PathTracing           pathTracingSettings = hdCamera.volumeStack.GetComponent <PathTracing>();
            bool                  ptEnabled           = pathTracingSettings.enable.value;

            // We need to check if we should be building the ray tracing acceleration structure (if required by any effect)
            bool rayTracingRequired = rtAOEnabled || rtREnabled || rtGIEnabled || rrEnabled || rtSSSEnabled || ptEnabled || rayTracedShadows;

            if (!rayTracingRequired)
            {
                return;
            }

            // We need to process the emissive meshes of the rectangular area lights
            for (var i = 0; i < m_RayTracingLights.hdRectLightArray.Count; i++)
            {
                // Fetch the current renderer of the rectangular area light (if any)
                MeshRenderer currentRenderer = m_RayTracingLights.hdRectLightArray[i].emissiveMeshRenderer;

                // If there is none it means that there is no emissive mesh for this light
                if (currentRenderer == null)
                {
                    continue;
                }

                // This objects should be included into the RAS
                AddInstanceToRAS(currentRenderer,
                                 rayTracedShadows,
                                 rtAOEnabled, aoSettings.layerMask.value,
                                 rtREnabled, reflSettings.layerMask.value,
                                 rtGIEnabled, giSettings.layerMask.value,
                                 rrEnabled, recursiveSettings.layerMask.value,
                                 ptEnabled, pathTracingSettings.layerMask.value);
            }

            int matCount = m_MaterialCRCs.Count;

            LODGroup[] lodGroupArray = UnityEngine.GameObject.FindObjectsOfType <LODGroup>();
            for (var i = 0; i < lodGroupArray.Length; i++)
            {
                // Grab the current LOD group
                LODGroup lodGroup = lodGroupArray[i];

                // Get the set of LODs
                LOD[] lodArray = lodGroup.GetLODs();
                for (int lodIdx = 0; lodIdx < lodArray.Length; ++lodIdx)
                {
                    LOD currentLOD = lodArray[lodIdx];
                    // We only want to push to the acceleration structure the lod0, we do not have defined way to select the right LOD at the moment
                    if (lodIdx == 0)
                    {
                        for (int rendererIdx = 0; rendererIdx < currentLOD.renderers.Length; ++rendererIdx)
                        {
                            // Fetch the renderer that we are interested in
                            Renderer currentRenderer = currentLOD.renderers[rendererIdx];

                            // This objects should but included into the RAS
                            AddInstanceToRAS(currentRenderer,
                                             rayTracedShadows,
                                             aoSettings.rayTracing.value, aoSettings.layerMask.value,
                                             reflSettings.rayTracing.value, reflSettings.layerMask.value,
                                             giSettings.rayTracing.value, giSettings.layerMask.value,
                                             recursiveSettings.enable.value, recursiveSettings.layerMask.value,
                                             pathTracingSettings.enable.value, pathTracingSettings.layerMask.value);
                        }
                    }

                    // Add them to the processed set so that they are not taken into account when processing all the renderers
                    for (int rendererIdx = 0; rendererIdx < currentLOD.renderers.Length; ++rendererIdx)
                    {
                        Renderer currentRenderer = currentLOD.renderers[rendererIdx];
                        // Add this fella to the renderer list
                        // Unfortunately, we need to check that this renderer was not already pushed into the list (happens if the user uses the same mesh renderer
                        // for two LODs)
                        if (!m_RayTracingRendererReference.ContainsKey(currentRenderer.GetInstanceID()))
                        {
                            m_RayTracingRendererReference.Add(currentRenderer.GetInstanceID(), 1);
                        }
                    }
                }
            }

            // Grab all the renderers from the scene
            var rendererArray = UnityEngine.GameObject.FindObjectsOfType <Renderer>();

            for (var i = 0; i < rendererArray.Length; i++)
            {
                // Fetch the current renderer
                Renderer currentRenderer = rendererArray[i];

                // If it is not active skip it
                if (currentRenderer.enabled == false)
                {
                    continue;
                }

                // Grab the current game object
                GameObject gameObject = currentRenderer.gameObject;

                // Has this object already been processed, just skip it
                if (m_RayTracingRendererReference.ContainsKey(currentRenderer.GetInstanceID()))
                {
                    continue;
                }

                // Does this object have a reflection probe component? if yes we do not want to have it in the acceleration structure
                if (gameObject.TryGetComponent <ReflectionProbe>(out reflectionProbe))
                {
                    continue;
                }

                // This objects should be included into the RAS
                AddInstanceToRAS(currentRenderer,
                                 rayTracedShadows,
                                 aoSettings.rayTracing.value, aoSettings.layerMask.value,
                                 reflSettings.rayTracing.value, reflSettings.layerMask.value,
                                 giSettings.rayTracing.value, giSettings.layerMask.value,
                                 recursiveSettings.enable.value, recursiveSettings.layerMask.value,
                                 pathTracingSettings.enable.value, pathTracingSettings.layerMask.value);
            }

            // Check if the amount of materials being tracked has changed
            m_MaterialsDirty |= (matCount != m_MaterialCRCs.Count);

            if (ShaderConfig.s_CameraRelativeRendering != 0)
            {
                m_CurrentRAS.Build(hdCamera.camera.transform.position);
            }
            else
            {
                m_CurrentRAS.Build();
            }

            // tag the structures as valid
            m_ValidRayTracingState = true;
        }
        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);
            }
        }