// Must return the first executed shadow request
        public int UpdateShadowRequest(Camera camera, HDShadowInitParameters initParameters, HDShadowManager manager, VisibleLight visibleLight, CullResults cullResults, int lightIndex, out int shadowRequestCount)
        {
            int              firstShadowRequestIndex = -1;
            Vector3          cameraPos      = camera.transform.position;
            HDShadowSettings shadowSettings = VolumeManager.instance.stack.GetComponent <HDShadowSettings>();

            shadowRequestCount = 0;

            // When creating a new light, at the first frame, there is no AdditionalShadowData so we can't really render shadows
            if (m_ShadowData == null)
            {
                return(-1);
            }

            // Create shadow requests array using the light type
            if (shadowRequests == null || shadowRequests.Length != GetShadowRequestCount(shadowSettings))
            {
                int count = GetShadowRequestCount(shadowSettings);
                shadowRequests = new HDShadowRequest[count];

                for (int i = 0; i < count; i++)
                {
                    shadowRequests[i] = new HDShadowRequest();
                }
            }

            // If the shadow is too far away, we don't render it
            if (m_Light.type != LightType.Directional && Vector3.Distance(cameraPos, transform.position) >= m_ShadowData.shadowFadeDistance)
            {
                return(-1);
            }

            Vector2 viewportSize = new Vector2(m_ShadowData.shadowResolution, m_ShadowData.shadowResolution);

            if (initParameters.useDynamicViewportRescale && m_Light.type != LightType.Directional)
            {
                // resize viewport size by the normalized size of the light on screen
                // When we will have access to the non screen clamped bounding sphere light size, we could use it to scale the shadow map resolution
                // For the moment, this will be enough
                viewportSize *= Mathf.Lerp(64f / viewportSize.x, 1f, visibleLight.range / (cameraPos - transform.position).magnitude);
                viewportSize  = Vector2.Max(new Vector2(64f, 64f) / viewportSize, viewportSize);

                // Prevent flickering caused by the floating size of the viewport
                viewportSize.x = Mathf.Round(viewportSize.x);
                viewportSize.y = Mathf.Round(viewportSize.y);
            }

            viewportSize = Vector2.Max(viewportSize, new Vector2(16, 16));

            for (int requestIndex = 0; requestIndex < shadowRequests.Length; requestIndex++)
            {
                var       shadowRequest     = shadowRequests[requestIndex];
                Matrix4x4 invViewProjection = Matrix4x4.identity;

                // Write per light type matrices, splitDatas and culling parameters
                switch (m_Light.type)
                {
                case LightType.Point:
                    HDShadowUtils.ExtractPointLightData(m_Light.type, visibleLight, viewportSize, shadowNearPlane, m_ShadowData.normalBiasMax, (uint)requestIndex, out shadowRequest.view, out invViewProjection, out shadowRequest.projection, out shadowRequest.deviceProjection, out shadowRequest.splitData);
                    break;

                case LightType.Spot:
                    HDShadowUtils.ExtractSpotLightData(m_Light.type, spotLightShape, shadowNearPlane, aspectRatio, shapeWidth, shapeHeight, visibleLight, viewportSize, m_ShadowData.normalBiasMax, out shadowRequest.view, out invViewProjection, out shadowRequest.projection, out shadowRequest.deviceProjection, out shadowRequest.splitData);
                    break;

                case LightType.Directional:
                    Vector4 cullingSphere;
                    float   nearPlaneOffset = QualitySettings.shadowNearPlaneOffset;

                    HDShadowUtils.ExtractDirectionalLightData(visibleLight, viewportSize, (uint)requestIndex, shadowSettings.cascadeShadowSplitCount, shadowSettings.cascadeShadowSplits, nearPlaneOffset, cullResults, lightIndex, out shadowRequest.view, out invViewProjection, out shadowRequest.projection, out shadowRequest.deviceProjection, out shadowRequest.splitData);

                    cullingSphere = shadowRequest.splitData.cullingSphere;

                    // Camera relative for directional light culling sphere
                    if (ShaderConfig.s_CameraRelativeRendering != 0)
                    {
                        cullingSphere.x -= cameraPos.x;
                        cullingSphere.y -= cameraPos.y;
                        cullingSphere.z -= cameraPos.z;
                    }

                    manager.UpdateCascade(requestIndex, cullingSphere, shadowSettings.cascadeShadowBorders[requestIndex]);
                    break;

                case LightType.Area:
                    HDShadowUtils.ExtractAreaLightData(visibleLight, lightTypeExtent, out shadowRequest.view, out invViewProjection, out shadowRequest.projection, out shadowRequest.deviceProjection, out shadowRequest.splitData);
                    break;
                }

                // Assign all setting common to every lights
                SetCommonShadowRequestSettings(shadowRequest, cameraPos, invViewProjection, viewportSize, lightIndex);

                int shadowRequestIndex = manager.AddShadowRequest(shadowRequest);

                // Store the first shadow request id to return it
                if (firstShadowRequestIndex == -1)
                {
                    firstShadowRequestIndex = shadowRequestIndex;
                }

                shadowRequestCount++;
            }

            return(firstShadowRequestIndex);
        }
 int GetShadowRequestCount(HDShadowSettings shadowSettings)
 {
     return((m_Light.type == LightType.Point) ? 6 : (m_Light.type == LightType.Directional) ? shadowSettings.cascadeShadowSplitCount : 1);
 }