void OnEnable()
    {
        Debug.Assert(Instance == null, "StaggeredCascade is expected to be a singleton");
        Instance = this;

        m_StaggerStage = StaggerStage.Updating;

        var go = new GameObject("ShadowCamera");

        go.hideFlags = HideFlags.DontSave;        // | HideFlags.NotEditable;
        go.transform.SetParent(transform);
        m_ShadowCamera = go.AddComponent <Camera>();
        m_ShadowCamera.orthographic = true;
        m_ShadowCamera.enabled      = false;

        m_ShaderPassName       = new ShaderPassName("ShadowCaster");
        m_DrawRendererSettings = new DrawRendererSettings {
            rendererConfiguration = RendererConfiguration.None,
            sorting = { flags = SortFlags.QuantizedFrontToBack }
        };
        m_DrawRendererSettings.SetShaderPassName(0, m_ShaderPassName);
        m_FilterRendererSettings = new FilterRenderersSettings(true)
        {
            renderQueueRange = new RenderQueueRange {
                min = (int)UnityEngine.Rendering.RenderQueue.Geometry,
                max = (int)UnityEngine.Rendering.RenderQueue.GeometryLast
            },
        };
    }
    void OnDisable()
    {
        Instance = null;

        if (Application.isPlaying)
        {
            Destroy(m_ShadowCamera.gameObject);
        }
        else
        {
            DestroyImmediate(m_ShadowCamera.gameObject);
        }

        m_StaggerStage = StaggerStage.Disabled;
    }
    bool DoRenderShadows(ScriptableRenderContext renderContext, CullResults cullResults, uint sliceIdx, uint sliceCount)
    {
        if (m_StaggerStage == StaggerStage.Enabled)
        {
            return(true);
        }

        var scales = transform.localScale;

        m_ShadowCamera.transform.position = transform.position - m_StaggeredLightDir[sliceIdx] * scales.y / 2f;
        m_ShadowCamera.transform.rotation = Quaternion.LookRotation(m_StaggeredLightDir[sliceIdx], Vector3.up);
        m_ShadowCamera.orthographicSize   = scales.z / 2f;
        m_ShadowCamera.aspect             = scales.x / scales.z;
        m_ShadowCamera.nearClipPlane      = 0f;
        m_ShadowCamera.farClipPlane       = scales.y;

        CullResults.GetCullingParameters(m_ShadowCamera, out m_ShadowCullParams);
        var lodParams = m_ShadowCullParams.lodParameters;

        lodParams.cameraPosition          = m_StaggeredPosition[sliceIdx];
        m_ShadowCullParams.lodParameters  = lodParams;
        m_ShadowCullParams.shadowDistance = 0f;

        var lodBias = QualitySettings.lodBias;

        QualitySettings.lodBias = 100f;
        CullResults.Cull(ref m_ShadowCullParams, renderContext, ref m_ShadowCullResults);
        QualitySettings.lodBias = lodBias;

        m_DrawRendererSettings.sorting.cameraPosition      = m_StaggeredPosition[sliceIdx];
        m_DrawRendererSettings.sorting.worldToCameraMatrix = m_StaggeredViewMatrix[sliceIdx];

        renderContext.DrawRenderers(m_ShadowCullResults.visibleRenderers, ref m_DrawRendererSettings, m_FilterRendererSettings);

        m_StaggerStage = StaggerStage.Enabled;

        return(true);
    }