/// <summary>
        /// Function that returns the ray tracing and path tracing effects that are enabled for a given camera.
        /// </summary>
        /// <param name="hdCamera">The input camera</param>
        /// <param name="rayTracedShadows">Flag that defines if at least one light has ray traced shadows.</param>
        /// <param name="rayTracedContactShadows">Flag that defines if at least one light has ray traced contact shadows</param>
        /// <returns>HDEffectsParameters type.</returns>
        public static HDEffectsParameters EvaluateEffectsParameters(HDCamera hdCamera, bool rayTracedShadows, bool rayTracedContactShadows)
        {
            HDEffectsParameters parameters = new HDEffectsParameters();

            // Aggregate the shadow requirements
            parameters.shadows = hdCamera.frameSettings.IsEnabled(FrameSettingsField.ScreenSpaceShadows) && (rayTracedShadows || rayTracedContactShadows);

            // Aggregate the ambient occlusion parameters
            AmbientOcclusion aoSettings = hdCamera.volumeStack.GetComponent <AmbientOcclusion>();

            parameters.ambientOcclusion = aoSettings.rayTracing.value && hdCamera.frameSettings.IsEnabled(FrameSettingsField.SSAO);
            parameters.aoLayerMask      = aoSettings.layerMask.value;

            // Aggregate the reflections parameters
            ScreenSpaceReflection reflSettings = hdCamera.volumeStack.GetComponent <ScreenSpaceReflection>();

            parameters.reflections   = reflSettings.enabled.value && ScreenSpaceReflection.RayTracingActive(reflSettings) && hdCamera.frameSettings.IsEnabled(FrameSettingsField.SSR);
            parameters.reflLayerMask = reflSettings.layerMask.value;

            // Aggregate the global illumination parameters
            GlobalIllumination giSettings = hdCamera.volumeStack.GetComponent <GlobalIllumination>();

            parameters.globalIllumination = giSettings.enable.value && GlobalIllumination.RayTracingActive(giSettings) && hdCamera.frameSettings.IsEnabled(FrameSettingsField.SSGI);
            parameters.giLayerMask        = giSettings.layerMask.value;

            // Aggregate the global illumination parameters
            RecursiveRendering recursiveSettings = hdCamera.volumeStack.GetComponent <RecursiveRendering>();

            parameters.recursiveRendering = recursiveSettings.enable.value;
            parameters.recursiveLayerMask = recursiveSettings.layerMask.value;

            // Aggregate the sub surface parameters
            SubSurfaceScattering sssSettings = hdCamera.volumeStack.GetComponent <SubSurfaceScattering>();

            parameters.subSurface = sssSettings.rayTracing.value && hdCamera.frameSettings.IsEnabled(FrameSettingsField.SubsurfaceScattering);

            // Aggregate the path parameters
            PathTracing pathTracingSettings = hdCamera.volumeStack.GetComponent <PathTracing>();

            parameters.pathTracing = pathTracingSettings.enable.value;
            parameters.ptLayerMask = pathTracingSettings.layerMask.value;

            // We need to check if at least one effect will require the acceleration structure
            parameters.rayTracingRequired = parameters.ambientOcclusion || parameters.reflections ||
                                            parameters.globalIllumination || parameters.recursiveRendering || parameters.subSurface ||
                                            parameters.pathTracing || parameters.shadows;

            // Return the result
            return(parameters);
        }
        internal bool RayTracingLightClusterRequired(HDCamera hdCamera)
        {
            ScreenSpaceReflection reflSettings        = hdCamera.volumeStack.GetComponent <ScreenSpaceReflection>();
            GlobalIllumination    giSettings          = hdCamera.volumeStack.GetComponent <GlobalIllumination>();
            RecursiveRendering    recursiveSettings   = hdCamera.volumeStack.GetComponent <RecursiveRendering>();
            PathTracing           pathTracingSettings = hdCamera.volumeStack.GetComponent <PathTracing>();
            SubSurfaceScattering  subSurface          = hdCamera.volumeStack.GetComponent <SubSurfaceScattering>();

            return(m_ValidRayTracingState &&
                   (ScreenSpaceReflection.RayTracingActive(reflSettings) ||
                    GlobalIllumination.RayTracingActive(giSettings) ||
                    recursiveSettings.enable.value ||
                    pathTracingSettings.enable.value ||
                    subSurface.rayTracing.value));
        }
        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 && ScreenSpaceReflection.RayTracingActive(reflSettings) && hdCamera.frameSettings.IsEnabled(FrameSettingsField.SSR);
            GlobalIllumination    giSettings          = hdCamera.volumeStack.GetComponent <GlobalIllumination>();
            bool                  rtGIEnabled         = giSettings.enable.value && GlobalIllumination.RayTracingActive(giSettings) && 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,
                                             ScreenSpaceReflection.RayTracingActive(reflSettings), reflSettings.layerMask.value,
                                             GlobalIllumination.RayTracingActive(giSettings), 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];
                        if (currentRenderer == null)
                        {
                            continue;
                        }

                        // 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,
                                 ScreenSpaceReflection.RayTracingActive(reflSettings), reflSettings.layerMask.value,
                                 GlobalIllumination.RayTracingActive(giSettings), 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;
        }