Esempio n. 1
0
        // Warning: must be called after ProcessShadowRequests and RenderShadows to have valid informations
        public void DisplayShadowMap(int shadowIndex, CommandBuffer cmd, Material debugMaterial, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue)
        {
            if (shadowIndex >= m_ShadowRequestCount)
            {
                return;
            }

            HDShadowRequest shadowRequest = m_ShadowRequests[shadowIndex];

            switch (shadowRequest.shadowMapType)
            {
            case ShadowMapType.PunctualAtlas:
            {
                m_Atlas.DisplayAtlas(cmd, debugMaterial, shadowRequest.atlasViewport, screenX, screenY, screenSizeX, screenSizeY, minValue, maxValue);
                break;
            }

            case ShadowMapType.CascadedDirectional:
            {
                m_CascadeAtlas.DisplayAtlas(cmd, debugMaterial, shadowRequest.atlasViewport, screenX, screenY, screenSizeX, screenSizeY, minValue, maxValue);
                break;
            }

            case ShadowMapType.AreaLightAtlas:
            {
                m_AreaLightShadowAtlas.DisplayAtlas(cmd, debugMaterial, shadowRequest.atlasViewport, screenX, screenY, screenSizeX, screenSizeY, minValue, maxValue);
                break;
            }
            }
            ;
        }
        HDShadowData CreateShadowData(HDShadowRequest shadowRequest, HDShadowAtlas atlas)
        {
            HDShadowData data = new HDShadowData();

            var devProj = shadowRequest.deviceProjection;
            var view    = shadowRequest.view;

            data.proj          = new Vector4(devProj.m00, devProj.m11, devProj.m22, devProj.m23);
            data.pos           = shadowRequest.position;
            data.rot0          = new Vector3(view.m00, view.m01, view.m02);
            data.rot1          = new Vector3(view.m10, view.m11, view.m12);
            data.rot2          = new Vector3(view.m20, view.m21, view.m22);
            data.shadowToWorld = shadowRequest.shadowToWorld;

            // Compute the scale and offset (between 0 and 1) for the atlas coordinates
            float rWidth  = 1.0f / atlas.width;
            float rHeight = 1.0f / atlas.height;

            data.atlasOffset = Vector2.Scale(new Vector2(rWidth, rHeight), new Vector2(shadowRequest.atlasViewport.x, shadowRequest.atlasViewport.y));

            data.shadowMapSize = new Vector4(shadowRequest.atlasViewport.width, shadowRequest.atlasViewport.height, 1.0f / shadowRequest.atlasViewport.width, 1.0f / shadowRequest.atlasViewport.height);

            data.viewBias      = shadowRequest.viewBias;
            data.normalBias    = shadowRequest.normalBias;
            data.flags         = shadowRequest.flags;
            data.edgeTolerance = shadowRequest.edgeTolerance;

            data.shadowFilterParams0.x = shadowRequest.shadowSoftness;
            data.shadowFilterParams0.y = HDShadowUtils.Asfloat(shadowRequest.blockerSampleCount);
            data.shadowFilterParams0.z = HDShadowUtils.Asfloat(shadowRequest.filterSampleCount);
            data.shadowFilterParams0.w = 0;

            return(data);
        }
Esempio n. 3
0
        public void UpdateShadowRequest(int index, HDShadowRequest shadowRequest)
        {
            if (index >= m_ShadowRequestCount)
            {
                return;
            }

            shadowRequest.atlasViewport = m_ShadowResolutionRequests[index].atlasViewport;
            m_ShadowRequests[index]     = shadowRequest;

            switch (shadowRequest.shadowMapType)
            {
            case ShadowMapType.PunctualAtlas:
            {
                m_Atlas.AddShadowRequest(shadowRequest);
                break;
            }

            case ShadowMapType.CascadedDirectional:
            {
                m_CascadeAtlas.AddShadowRequest(shadowRequest);
                break;
            }

            case ShadowMapType.AreaLightAtlas:
            {
                m_AreaLightShadowAtlas.AddShadowRequest(shadowRequest);
                break;
            }
            }
            ;
        }
Esempio n. 4
0
        public void ReserveShadows(Camera camera, HDShadowManager shadowManager, HDShadowInitParameters initParameters, CullResults cullResults, FrameSettings frameSettings, int lightIndex)
        {
            Bounds bounds;

            m_WillRenderShadows  = m_Light.shadows != LightShadows.None && frameSettings.enableShadow;
            m_WillRenderShadows &= cullResults.GetShadowCasterBounds(lightIndex, out bounds);
            // When creating a new light, at the first frame, there is no AdditionalShadowData so we can't really render shadows
            m_WillRenderShadows &= m_ShadowData != null && m_ShadowData.shadowDimmer > 0;

            if (!m_WillRenderShadows)
            {
                return;
            }

            // Create shadow requests array using the light type
            if (shadowRequests == null || m_ShadowRequestIndices == null)
            {
                const int maxLightShadowRequestsCount = 6;
                shadowRequests         = new HDShadowRequest[maxLightShadowRequestsCount];
                m_ShadowRequestIndices = new int[maxLightShadowRequestsCount];

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

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

            // Compute dynamic shadow resolution
            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, m_Light.range / (camera.transform.position - 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));

            // Update the directional shadow atlas size
            if (m_Light.type == LightType.Directional)
            {
                shadowManager.UpdateDirectionalShadowResolution((int)viewportSize.x, m_ShadowSettings.cascadeShadowSplitCount);
            }

            // Reserver wanted resolution in the shadow atlas
            bool allowResize = m_Light.type != LightType.Directional;
            int  count       = GetShadowRequestCount();

            for (int index = 0; index < count; index++)
            {
                m_ShadowRequestIndices[index] = shadowManager.ReserveShadowResolutions(viewportSize, allowResize);
            }
        }
        void SetCommonShadowRequestSettings(HDShadowRequest shadowRequest, Vector3 cameraPos, Matrix4x4 invViewProjection, Vector2 viewportSize, int lightIndex)
        {
            // zBuffer param to reconstruct depth position (for transmission)
            float f = m_Light.range;
            float n = shadowNearPlane;

            shadowRequest.zBufferParam  = new Vector4((f - n) / n, 1.0f, (f - n) / n * f, 1.0f / f);
            shadowRequest.viewBias      = new Vector4(m_ShadowData.viewBiasMin, m_ShadowData.viewBiasMax, m_ShadowData.viewBiasScale, 2.0f / shadowRequest.projection.m00 / viewportSize.x * 1.4142135623730950488016887242097f);
            shadowRequest.normalBias    = new Vector3(m_ShadowData.normalBiasMin, m_ShadowData.normalBiasMax, m_ShadowData.normalBiasScale);
            shadowRequest.flags         = 0;
            shadowRequest.flags        |= m_ShadowData.sampleBiasScale     ? (int)HDShadowFlag.SampleBiasScale : 0;
            shadowRequest.flags        |= m_ShadowData.edgeLeakFixup       ? (int)HDShadowFlag.EdgeLeakFixup : 0;
            shadowRequest.flags        |= m_ShadowData.edgeToleranceNormal ? (int)HDShadowFlag.EdgeToleranceNormal : 0;
            shadowRequest.edgeTolerance = m_ShadowData.edgeTolerance;

            // Make light position camera relative:
            // TODO: think about VR (use different camera position for each eye)
            if (ShaderConfig.s_CameraRelativeRendering != 0)
            {
                var translation = Matrix4x4.Translate(cameraPos);
                shadowRequest.view *= translation;
                translation.SetColumn(3, -cameraPos);
                translation[15]   = 1.0f;
                invViewProjection = translation * invViewProjection;
            }

            if (m_Light.type == LightType.Directional || (m_Light.type == LightType.Spot && spotLightShape == SpotLightShape.Box))
            {
                shadowRequest.position = new Vector3(shadowRequest.view.m03, shadowRequest.view.m13, shadowRequest.view.m23);
            }
            else
            {
                shadowRequest.position = (ShaderConfig.s_CameraRelativeRendering != 0) ? transform.position - cameraPos : transform.position;
            }

            shadowRequest.shadowToWorld = invViewProjection.transpose;
            shadowRequest.zClip         = (m_Light.type != LightType.Directional);
            shadowRequest.lightIndex    = lightIndex;
            // We don't allow shadow resize for directional cascade shadow
            shadowRequest.allowResize = m_Light.type != LightType.Directional;
            shadowRequest.lightType   = (int)m_Light.type;

            // Shadow algorithm parameters
            shadowRequest.shadowSoftness     = shadowSoftness / 100f;
            shadowRequest.blockerSampleCount = blockerSampleCount;
            shadowRequest.filterSampleCount  = filterSampleCount;
            shadowRequest.minFilterSize      = minFilterSize;

            shadowRequest.kernelSize   = (uint)kernelSize;
            shadowRequest.lightAngle   = (lightAngle * Mathf.PI / 180.0f);
            shadowRequest.maxDepthBias = maxDepthBias;
        }
Esempio n. 6
0
        HDShadowData CreateShadowData(HDShadowRequest shadowRequest, HDShadowAtlas atlas)
        {
            HDShadowData data = new HDShadowData();

            var devProj = shadowRequest.deviceProjection;
            var view    = shadowRequest.view;

            data.proj                  = new Vector4(devProj.m00, devProj.m11, devProj.m22, devProj.m23);
            data.pos                   = shadowRequest.position;
            data.rot0                  = new Vector3(view.m00, view.m01, view.m02);
            data.rot1                  = new Vector3(view.m10, view.m11, view.m12);
            data.rot2                  = new Vector3(view.m20, view.m21, view.m22);
            data.shadowToWorld         = shadowRequest.shadowToWorld;
            data.cacheTranslationDelta = new Vector3(0.0f, 0.0f, 0.0f);


            // Compute the scale and offset (between 0 and 1) for the atlas coordinates
            float rWidth  = 1.0f / atlas.width;
            float rHeight = 1.0f / atlas.height;

            data.atlasOffset = Vector2.Scale(new Vector2(rWidth, rHeight), new Vector2(shadowRequest.atlasViewport.x, shadowRequest.atlasViewport.y));

            data.shadowMapSize = new Vector4(shadowRequest.atlasViewport.width, shadowRequest.atlasViewport.height, 1.0f / shadowRequest.atlasViewport.width, 1.0f / shadowRequest.atlasViewport.height);

            data.viewBias      = shadowRequest.viewBias;
            data.normalBias    = shadowRequest.normalBias;
            data.flags         = shadowRequest.flags;
            data.edgeTolerance = shadowRequest.edgeTolerance;

            data.shadowFilterParams0.x = shadowRequest.shadowSoftness;
            data.shadowFilterParams0.y = HDShadowUtils.Asfloat(shadowRequest.blockerSampleCount);
            data.shadowFilterParams0.z = HDShadowUtils.Asfloat(shadowRequest.filterSampleCount);
            data.shadowFilterParams0.w = shadowRequest.minFilterSize;

            var hdAsset = (GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset);

            if (hdAsset.currentPlatformRenderPipelineSettings.hdShadowInitParams.shadowQuality == HDShadowQuality.VeryHigh && shadowRequest.lightType == (int)LightType.Directional)
            {
                data.shadowFilterParams0.x = shadowRequest.kernelSize;
                data.shadowFilterParams0.y = shadowRequest.lightAngle;
                data.shadowFilterParams0.z = shadowRequest.maxDepthBias;
            }

            if (atlas.HasBlurredEVSM())
            {
                data.shadowFilterParams0 = shadowRequest.evsmParams;
            }

            return(data);
        }
        // Warning: must be called after ProcessShadowRequests and RenderShadows to have valid informations
        public void DisplayShadowMap(int shadowIndex, CommandBuffer cmd, Material debugMaterial, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue, bool flipY)
        {
            if (shadowIndex >= m_ShadowRequestCount)
            {
                return;
            }

            HDShadowRequest shadowRequest = m_ShadowRequests[shadowIndex];

            if (shadowRequest.allowResize)
            {
                m_Atlas.DisplayAtlas(cmd, debugMaterial, shadowRequest.atlasViewport, screenX, screenY, screenSizeX, screenSizeY, minValue, maxValue, flipY);
            }
            else
            {
                m_CascadeAtlas.DisplayAtlas(cmd, debugMaterial, shadowRequest.atlasViewport, screenX, screenY, screenSizeX, screenSizeY, minValue, maxValue, flipY);
            }
        }
        public void UpdateShadowRequest(int index, HDShadowRequest shadowRequest)
        {
            if (index >= m_ShadowRequestCount)
            {
                return;
            }

            shadowRequest.atlasViewport = m_ShadowResolutionRequests[index].atlasViewport;
            m_ShadowRequests[index]     = shadowRequest;

            if (shadowRequest.allowResize)
            {
                m_Atlas.AddShadowRequest(shadowRequest);
            }
            else
            {
                m_CascadeAtlas.AddShadowRequest(shadowRequest);
            }
        }
Esempio n. 9
0
        public int AddShadowRequest(HDShadowRequest shadowRequest)
        {
            if (m_ShadowRequests.Count >= m_maxShadowRequests)
            {
                return(-1);
            }

            if (shadowRequest.allowResize)
            {
                m_Atlas.Reserve(shadowRequest);
            }
            else
            {
                m_CascadeAtlas.Reserve(shadowRequest);
            }

            // Keep track of all shadow request and the order they was requested
            m_ShadowRequests.Add(shadowRequest);

            return(m_ShadowRequests.Count - 1);
        }
Esempio n. 10
0
 public void AddShadowRequest(HDShadowRequest shadowRequest)
 {
     m_ShadowRequests.Add(shadowRequest);
 }
        void SetCommonShadowRequestSettings(HDShadowRequest shadowRequest, Vector3 cameraPos, Matrix4x4 invViewProjection, Matrix4x4 viewProjection, Vector2 viewportSize, int lightIndex)
        {
            // zBuffer param to reconstruct depth position (for transmission)
            float f = legacyLight.range;
            float n = shadowNearPlane;

            shadowRequest.zBufferParam  = new Vector4((f - n) / n, 1.0f, (f - n) / n * f, 1.0f / f);
            shadowRequest.viewBias      = new Vector4(m_ShadowData.viewBiasMin, m_ShadowData.viewBiasMax, m_ShadowData.viewBiasScale, 2.0f / shadowRequest.deviceProjectionYFlip.m00 / viewportSize.x * 1.4142135623730950488016887242097f);
            shadowRequest.normalBias    = new Vector3(m_ShadowData.normalBiasMin, m_ShadowData.normalBiasMax, m_ShadowData.normalBiasScale);
            shadowRequest.flags         = 0;
            shadowRequest.flags        |= m_ShadowData.sampleBiasScale     ? (int)HDShadowFlag.SampleBiasScale : 0;
            shadowRequest.flags        |= m_ShadowData.edgeLeakFixup       ? (int)HDShadowFlag.EdgeLeakFixup : 0;
            shadowRequest.flags        |= m_ShadowData.edgeToleranceNormal ? (int)HDShadowFlag.EdgeToleranceNormal : 0;
            shadowRequest.edgeTolerance = m_ShadowData.edgeTolerance;

            // Make light position camera relative:
            // TODO: think about VR (use different camera position for each eye)
            if (ShaderConfig.s_CameraRelativeRendering != 0)
            {
                var translation = Matrix4x4.Translate(cameraPos);
                shadowRequest.view *= translation;
                translation.SetColumn(3, -cameraPos);
                translation[15]   = 1.0f;
                invViewProjection = translation * invViewProjection;
            }

            if (legacyLight.type == LightType.Directional || (legacyLight.type == LightType.Spot && spotLightShape == SpotLightShape.Box))
            {
                shadowRequest.position = new Vector3(shadowRequest.view.m03, shadowRequest.view.m13, shadowRequest.view.m23);
            }
            else
            {
                shadowRequest.position = (ShaderConfig.s_CameraRelativeRendering != 0) ? transform.position - cameraPos : transform.position;
            }

            shadowRequest.shadowToWorld = invViewProjection.transpose;
            shadowRequest.zClip         = (legacyLight.type != LightType.Directional);
            shadowRequest.lightIndex    = lightIndex;
            // We don't allow shadow resize for directional cascade shadow
            if (legacyLight.type == LightType.Directional)
            {
                shadowRequest.shadowMapType = ShadowMapType.CascadedDirectional;
            }
            else if (lightTypeExtent == LightTypeExtent.Rectangle)
            {
                shadowRequest.shadowMapType = ShadowMapType.AreaLightAtlas;
            }
            else
            {
                shadowRequest.shadowMapType = ShadowMapType.PunctualAtlas;
            }

            shadowRequest.lightType = (int)legacyLight.type;

            // shadow clip planes (used for tessellation clipping)
            GeometryUtility.CalculateFrustumPlanes(viewProjection, m_ShadowFrustumPlanes);
            if (shadowRequest.frustumPlanes?.Length != 6)
            {
                shadowRequest.frustumPlanes = new Vector4[6];
            }
            // Left, right, top, bottom, near, far.
            for (int i = 0; i < 6; i++)
            {
                shadowRequest.frustumPlanes[i] = new Vector4(
                    m_ShadowFrustumPlanes[i].normal.x,
                    m_ShadowFrustumPlanes[i].normal.y,
                    m_ShadowFrustumPlanes[i].normal.z,
                    m_ShadowFrustumPlanes[i].distance
                    );
            }

            // Shadow algorithm parameters
            shadowRequest.shadowSoftness     = shadowSoftness / 100f;
            shadowRequest.blockerSampleCount = blockerSampleCount;
            shadowRequest.filterSampleCount  = filterSampleCount;
            shadowRequest.minFilterSize      = minFilterSize;

            shadowRequest.kernelSize   = (uint)kernelSize;
            shadowRequest.lightAngle   = (lightAngle * Mathf.PI / 180.0f);
            shadowRequest.maxDepthBias = maxDepthBias;
            // We transform it to base two for faster computation.
            // So e^x = 2^y where y = x * log2 (e)
            const float log2e = 1.44269504089f;

            shadowRequest.evsmParams.x = evsmExponent * log2e;
            shadowRequest.evsmParams.y = evsmLightLeakBias;
            shadowRequest.evsmParams.z = evsmVarianceBias;
            shadowRequest.evsmParams.w = evsmBlurPasses;
        }
        public void ReserveShadows(Camera camera, HDShadowManager shadowManager, HDShadowInitParameters initParameters, CullingResults cullResults, FrameSettings frameSettings, int lightIndex)
        {
            Bounds bounds;
            float  cameraDistance = Vector3.Distance(camera.transform.position, transform.position);

            m_WillRenderShadows = legacyLight.shadows != LightShadows.None && frameSettings.IsEnabled(FrameSettingsField.Shadow);

            m_WillRenderShadows &= cullResults.GetShadowCasterBounds(lightIndex, out bounds);
            // When creating a new light, at the first frame, there is no AdditionalShadowData so we can't really render shadows
            m_WillRenderShadows &= m_ShadowData != null && m_ShadowData.shadowDimmer > 0;
            // If the shadow is too far away, we don't render it
            if (m_ShadowData != null)
            {
                m_WillRenderShadows &= legacyLight.type == LightType.Directional || cameraDistance < (m_ShadowData.shadowFadeDistance);
            }

#if ENABLE_RAYTRACING
            m_WillRenderShadows &= !(lightTypeExtent == LightTypeExtent.Rectangle && useRayTracedShadows);
#endif

            if (!m_WillRenderShadows)
            {
                return;
            }

            // Create shadow requests array using the light type
            if (shadowRequests == null || m_ShadowRequestIndices == null)
            {
                const int maxLightShadowRequestsCount = 6;
                shadowRequests         = new HDShadowRequest[maxLightShadowRequestsCount];
                m_ShadowRequestIndices = new int[maxLightShadowRequestsCount];

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

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

            // Reserver wanted resolution in the shadow atlas
            ShadowMapType shadowMapType = (lightTypeExtent == LightTypeExtent.Rectangle) ? ShadowMapType.AreaLightAtlas :
                                          (legacyLight.type != LightType.Directional) ? ShadowMapType.PunctualAtlas : ShadowMapType.CascadedDirectional;

            bool viewPortRescaling = false;
            // Compute dynamic shadow resolution

            viewPortRescaling |= (shadowMapType == ShadowMapType.PunctualAtlas && initParameters.punctualLightShadowAtlas.useDynamicViewportRescale);
            viewPortRescaling |= (shadowMapType == ShadowMapType.AreaLightAtlas && initParameters.areaLightShadowAtlas.useDynamicViewportRescale);

            if (viewPortRescaling)
            {
                // 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, legacyLight.range / (camera.transform.position - 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));

            // Update the directional shadow atlas size
            if (legacyLight.type == LightType.Directional)
            {
                shadowManager.UpdateDirectionalShadowResolution((int)viewportSize.x, m_ShadowSettings.cascadeShadowSplitCount.value);
            }

            int count = GetShadowRequestCount();
            for (int index = 0; index < count; index++)
            {
                m_ShadowRequestIndices[index] = shadowManager.ReserveShadowResolutions(viewportSize, shadowMapType);
            }
        }
Esempio n. 13
0
 public void Reserve(HDShadowRequest shadowRequest)
 {
     shadowRequests.Add(shadowRequest);
 }
        // 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);
        }