//---------------------------------------------------------------------------------------------------------------------------------------------------
        // Render shadows
        //---------------------------------------------------------------------------------------------------------------------------------------------------
        void RenderPackedShadows(RenderLoop loop, CullResults cullResults, ref ShadowOutput packedShadows)
        {
            var setRenderTargetCommandBuffer = new CommandBuffer();

            setRenderTargetCommandBuffer.name = "Render packed shadows";
            setRenderTargetCommandBuffer.GetTemporaryRT(m_ShadowTexName, m_Settings.shadowAtlasWidth, m_Settings.shadowAtlasHeight, k_DepthBuffer, FilterMode.Bilinear, RenderTextureFormat.Shadowmap, RenderTextureReadWrite.Linear);
            setRenderTargetCommandBuffer.SetRenderTarget(new RenderTargetIdentifier(m_ShadowTexName));

            setRenderTargetCommandBuffer.ClearRenderTarget(true, true, Color.green);
            loop.ExecuteCommandBuffer(setRenderTargetCommandBuffer);
            setRenderTargetCommandBuffer.Dispose();

            VisibleLight[] visibleLights = cullResults.visibleLights;
            var            shadowSlices  = packedShadows.shadowSlices;

            // Render each light's shadow buffer into a subrect of the shared depth texture
            for (int lightIndex = 0; lightIndex < packedShadows.shadowLights.Length; lightIndex++)
            {
                int shadowSliceCount = packedShadows.shadowLights[lightIndex].shadowSliceCount;
                if (shadowSliceCount == 0)
                {
                    continue;
                }

                Profiler.BeginSample("Shadows.GetShadowCasterBounds");
                Bounds bounds;
                if (!cullResults.GetShadowCasterBounds(lightIndex, out bounds))
                {
                    Profiler.EndSample();
                    return;
                }
                Profiler.EndSample();

                Profiler.BeginSample("Shadows.DrawShadows");

                Matrix4x4 proj;
                Matrix4x4 view;

                var lightType      = visibleLights[lightIndex].lightType;
                var lightDirection = visibleLights[lightIndex].light.transform.forward;
                var shadowNearClip = visibleLights[lightIndex].light.shadowNearPlane;

                int shadowSliceIndex = packedShadows.GetShadowSliceIndex(lightIndex, 0);

                if (lightType == LightType.Spot)
                {
                    var  settings      = new DrawShadowsSettings(cullResults, lightIndex);
                    bool needRendering = cullResults.ComputeSpotShadowsMatricesAndCullingPrimitives(lightIndex, out view, out proj, out settings.splitData);
                    SetupShadowSplitMatrices(ref packedShadows.shadowSlices[shadowSliceIndex], proj, view);
                    if (needRendering)
                    {
                        RenderShadowSplit(ref shadowSlices[shadowSliceIndex], lightDirection, proj, view, ref loop, settings);
                    }
                }
                else if (lightType == LightType.Directional)
                {
                    Vector3 splitRatio = m_Settings.directionalLightCascades;

                    for (int s = 0; s < 4; ++s)
                    {
                        packedShadows.directionalShadowSplitSphereSqr[s] = new Vector4(0, 0, 0, float.NegativeInfinity);
                    }

                    for (int s = 0; s < shadowSliceCount; ++s, shadowSliceIndex++)
                    {
                        var  settings         = new DrawShadowsSettings(cullResults, lightIndex);
                        var  shadowResolution = shadowSlices[shadowSliceIndex].shadowResolution;
                        bool needRendering    = cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(lightIndex, s, shadowSliceCount, splitRatio, shadowResolution, shadowNearClip, out view, out proj, out settings.splitData);

                        packedShadows.directionalShadowSplitSphereSqr[s]    = settings.splitData.cullingSphere;
                        packedShadows.directionalShadowSplitSphereSqr[s].w *= packedShadows.directionalShadowSplitSphereSqr[s].w;

                        SetupShadowSplitMatrices(ref shadowSlices[shadowSliceIndex], proj, view);
                        if (needRendering)
                        {
                            RenderShadowSplit(ref shadowSlices[shadowSliceIndex], lightDirection, proj, view, ref loop, settings);
                        }
                    }
                }
                else if (lightType == LightType.Point)
                {
                    for (int s = 0; s < shadowSliceCount; ++s, shadowSliceIndex++)
                    {
                        var  settings      = new DrawShadowsSettings(cullResults, lightIndex);
                        bool needRendering = cullResults.ComputePointShadowsMatricesAndCullingPrimitives(lightIndex, (CubemapFace)s, 2.0f, out view, out proj, out settings.splitData);

                        SetupShadowSplitMatrices(ref shadowSlices[shadowSliceIndex], proj, view);
                        if (needRendering)
                        {
                            RenderShadowSplit(ref shadowSlices[shadowSliceIndex], lightDirection, proj, view, ref loop, settings);
                        }
                    }
                }
                Profiler.EndSample();
            }
        }