static void LayerCullingSetup()
    {
#if UNITY_EDITOR
        var panel     = DebugManager.instance.GetPanel("Scene View", true);
        var container = panel.children.Where(c => c.displayName == "Forest Custom").FirstOrDefault() as DebugUI.Container;
        if (container == null)
        {
            container = new DebugUI.Container {
                displayName = "Forest Custom"
            }
        }
        ;
        container.children.Add(new DebugUI.BoolField {
            displayName = "Use Layer Culling",
            getter      = () => ms_SceneViewCulling,
            setter      = value => ms_SceneViewCulling = value
        });
        if (!panel.children.Contains(container))
        {
            panel.children.Add(container);
        }
#endif

        HDRenderPipeline.OnBeforeCameraCull += UpdateLayerCulling;
    }
    static void StaggeredCascadeSetup()
    {
#if UNITY_EDITOR
        var panel     = DebugManager.instance.GetPanel("Scene View", true);
        var container = panel.children.Where(c => c.displayName == "Forest Custom").FirstOrDefault() as DebugUI.Container;
        if (container == null)
        {
            container = new DebugUI.Container {
                displayName = "Forest Custom"
            }
        }
        ;
        container.children.Add(new DebugUI.BoolField {
            displayName = "Stagger Last Cascade",
            getter      = () => ms_SceneViewStagger,
            setter      = value => ms_SceneViewStagger = value
        });
        if (!panel.children.Contains(container))
        {
            panel.children.Add(container);
        }
#endif

        ShadowAtlas.OnIsStaggered         += OnIsStaggered;
        ShadowAtlas.OnShouldRenderShadows += OnShouldRenderShadows;
        ShadowAtlas.OnRenderShadows       += OnRenderShadows;
        HDRenderPipeline.OnBeginCamera    += OnBeginCamera;
    }
        internal override void SetWidget(DebugUI.Widget widget)
        {
            base.SetWidget(widget);
            m_Field     = CastWidget <DebugUI.Container>();
            m_Container = GetComponent <DebugUIHandlerContainer>();

            if (string.IsNullOrEmpty(m_Field.displayName))
            {
                header.gameObject.SetActive(false);
            }
            else
            {
                nameLabel.text = m_Field.displayName;
            }
        }
        public void RegisterLightingDebug()
        {
            var list = new List <DebugUI.Widget>();

            list.Add(new DebugUI.EnumField
            {
                displayName    = "Shadow Debug Mode",
                getter         = () => (int)lightingDebugSettings.shadowDebugMode,
                setter         = value => lightingDebugSettings.shadowDebugMode = (ShadowMapDebugMode)value,
                autoEnum       = typeof(ShadowMapDebugMode),
                onValueChanged = RefreshLightingDebug
            });

            if (lightingDebugSettings.shadowDebugMode == ShadowMapDebugMode.VisualizeShadowMap)
            {
                var container = new DebugUI.Container();
                container.children.Add(new DebugUI.BoolField {
                    displayName = "Use Selection", getter = () => lightingDebugSettings.shadowDebugUseSelection, setter = value => lightingDebugSettings.shadowDebugUseSelection = value, flags = DebugUI.Flags.EditorOnly, onValueChanged = RefreshLightingDebug
                });

                if (!lightingDebugSettings.shadowDebugUseSelection)
                {
                    container.children.Add(new DebugUI.UIntField {
                        displayName = "Shadow Map Index", getter = () => lightingDebugSettings.shadowMapIndex, setter = value => lightingDebugSettings.shadowMapIndex = value, min = () => 0u, max = () => (uint)(RenderPipelineManager.currentPipeline as HDRenderPipeline).GetCurrentShadowCount() - 1u
                    });
                }

                list.Add(container);
            }
            else if (lightingDebugSettings.shadowDebugMode == ShadowMapDebugMode.VisualizeAtlas)
            {
                list.Add(new DebugUI.Container
                {
                    children =
                    {
                        new DebugUI.UIntField {
                            displayName = "Shadow Atlas Index", getter = () => lightingDebugSettings.shadowAtlasIndex, setter = value => lightingDebugSettings.shadowAtlasIndex = value, min = () => 0u, max = () => (uint)(RenderPipelineManager.currentPipeline as HDRenderPipeline).GetShadowAtlasCount() - 1u
                        },
                        new DebugUI.UIntField {
                            displayName = "Shadow Slice Index", getter = () => lightingDebugSettings.shadowSliceIndex, setter = value => lightingDebugSettings.shadowSliceIndex = value, min = () => 0u, max = () => (uint)(RenderPipelineManager.currentPipeline as HDRenderPipeline).GetShadowSliceCount(lightingDebugSettings.shadowAtlasIndex) - 1u
                        }
                    }
                });
            }

            list.Add(new DebugUI.FloatField {
                displayName = "Shadow Range Min Value", getter = () => lightingDebugSettings.shadowMinValue, setter = value => lightingDebugSettings.shadowMinValue = value
            });
            list.Add(new DebugUI.FloatField {
                displayName = "Shadow Range Max Value", getter = () => lightingDebugSettings.shadowMaxValue, setter = value => lightingDebugSettings.shadowMaxValue = value
            });

            list.Add(new DebugUI.EnumField {
                displayName = "Lighting Debug Mode", getter = () => (int)lightingDebugSettings.debugLightingMode, setter = value => SetDebugLightingMode((DebugLightingMode)value), autoEnum = typeof(DebugLightingMode), onValueChanged = RefreshLightingDebug
            });
            list.Add(new DebugUI.EnumField {
                displayName = "Fullscreen Debug Mode", getter = () => (int)fullScreenDebugMode, setter = value => fullScreenDebugMode = (FullScreenDebugMode)value, enumNames = lightingFullScreenDebugStrings, enumValues = lightingFullScreenDebugValues, onValueChanged = RefreshLightingDebug
            });
            switch (fullScreenDebugMode)
            {
            case FullScreenDebugMode.PreRefractionColorPyramid:
            case FullScreenDebugMode.FinalColorPyramid:
            case FullScreenDebugMode.DepthPyramid:
            {
                list.Add(new DebugUI.Container
                    {
                        children =
                        {
                            new DebugUI.UIntField
                            {
                                displayName = "Fullscreen Debug Mip",
                                getter      = () =>
                                {
                                    int id;
                                    switch (fullScreenDebugMode)
                                    {
                                    case FullScreenDebugMode.FinalColorPyramid:
                                    case FullScreenDebugMode.PreRefractionColorPyramid:
                                        id = HDShaderIDs._ColorPyramidScale;
                                        break;

                                    default:
                                        id = HDShaderIDs._DepthPyramidScale;
                                        break;
                                    }
                                    var size       = Shader.GetGlobalVector(id);
                                    float lodCount = size.z;
                                    return((uint)(fullscreenDebugMip * lodCount));
                                },
                                setter = value =>
                                {
                                    int id;
                                    switch (fullScreenDebugMode)
                                    {
                                    case FullScreenDebugMode.FinalColorPyramid:
                                    case FullScreenDebugMode.PreRefractionColorPyramid:
                                        id = HDShaderIDs._ColorPyramidScale;
                                        break;

                                    default:
                                        id = HDShaderIDs._DepthPyramidScale;
                                        break;
                                    }
                                    var size           = Shader.GetGlobalVector(id);
                                    float lodCount     = size.z;
                                    fullscreenDebugMip = (float)Convert.ChangeType(value, typeof(float)) / lodCount;
                                },
                                min = () => 0u,
                                max = () =>
                                {
                                    int id;
                                    switch (fullScreenDebugMode)
                                    {
                                    case FullScreenDebugMode.FinalColorPyramid:
                                    case FullScreenDebugMode.PreRefractionColorPyramid:
                                        id = HDShaderIDs._ColorPyramidScale;
                                        break;

                                    default:
                                        id = HDShaderIDs._DepthPyramidScale;
                                        break;
                                    }
                                    var size       = Shader.GetGlobalVector(id);
                                    float lodCount = size.z;
                                    return((uint)lodCount);
                                }
                            }
                        }
                    });
                break;
            }

            default:
                fullscreenDebugMip = 0;
                break;
            }

            list.Add(new DebugUI.BoolField {
                displayName = "Override Smoothness", getter = () => lightingDebugSettings.overrideSmoothness, setter = value => lightingDebugSettings.overrideSmoothness = value, onValueChanged = RefreshLightingDebug
            });
            if (lightingDebugSettings.overrideSmoothness)
            {
                list.Add(new DebugUI.Container
                {
                    children =
                    {
                        new DebugUI.FloatField {
                            displayName = "Smoothness", getter = () => lightingDebugSettings.overrideSmoothnessValue, setter = value => lightingDebugSettings.overrideSmoothnessValue = value, min = () => 0f, max = () => 1f, incStep = 0.025f
                        }
                    }
                });
            }

            list.Add(new DebugUI.BoolField {
                displayName = "Override Albedo", getter = () => lightingDebugSettings.overrideAlbedo, setter = value => lightingDebugSettings.overrideAlbedo = value, onValueChanged = RefreshLightingDebug
            });
            if (lightingDebugSettings.overrideAlbedo)
            {
                list.Add(new DebugUI.Container
                {
                    children =
                    {
                        new DebugUI.ColorField {
                            displayName = "Albedo", getter = () => lightingDebugSettings.overrideAlbedoValue, setter = value => lightingDebugSettings.overrideAlbedoValue = value, showAlpha = false, hdr = false
                        }
                    }
                });
            }

            list.Add(new DebugUI.BoolField {
                displayName = "Override Normal", getter = () => lightingDebugSettings.overrideNormal, setter = value => lightingDebugSettings.overrideNormal = value
            });

            list.Add(new DebugUI.BoolField {
                displayName = "Override Specular Color", getter = () => lightingDebugSettings.overrideSpecularColor, setter = value => lightingDebugSettings.overrideSpecularColor = value, onValueChanged = RefreshLightingDebug
            });
            if (lightingDebugSettings.overrideSpecularColor)
            {
                list.Add(new DebugUI.Container
                {
                    children =
                    {
                        new DebugUI.ColorField {
                            displayName = "Specular Color", getter = () => lightingDebugSettings.overrideSpecularColorValue, setter = value => lightingDebugSettings.overrideSpecularColorValue = value, showAlpha = false, hdr = false
                        }
                    }
                });
            }

            list.Add(new DebugUI.EnumField {
                displayName = "Tile/Cluster Debug", getter = () => (int)lightingDebugSettings.tileClusterDebug, setter = value => lightingDebugSettings.tileClusterDebug = (LightLoop.TileClusterDebug)value, autoEnum = typeof(LightLoop.TileClusterDebug), onValueChanged = RefreshLightingDebug
            });
            if (lightingDebugSettings.tileClusterDebug != LightLoop.TileClusterDebug.None && lightingDebugSettings.tileClusterDebug != LightLoop.TileClusterDebug.MaterialFeatureVariants)
            {
                list.Add(new DebugUI.Container
                {
                    children =
                    {
                        new DebugUI.EnumField {
                            displayName = "Tile/Cluster Debug By Category", getter = () => (int)lightingDebugSettings.tileClusterDebugByCategory, setter = value => lightingDebugSettings.tileClusterDebugByCategory = (LightLoop.TileClusterCategoryDebug)value, autoEnum = typeof(LightLoop.TileClusterCategoryDebug)
                        }
                    }
                });
            }

            list.Add(new DebugUI.BoolField {
                displayName = "Display Sky Reflection", getter = () => lightingDebugSettings.displaySkyReflection, setter = value => lightingDebugSettings.displaySkyReflection = value, onValueChanged = RefreshLightingDebug
            });
            if (lightingDebugSettings.displaySkyReflection)
            {
                list.Add(new DebugUI.Container
                {
                    children =
                    {
                        new DebugUI.FloatField {
                            displayName = "Sky Reflection Mipmap", getter = () => lightingDebugSettings.skyReflectionMipmap, setter = value => lightingDebugSettings.skyReflectionMipmap = value, min = () => 0f, max = () => 1f, incStep = 0.05f
                        }
                    }
                });
            }

            if (DebugNeedsExposure())
            {
                list.Add(new DebugUI.FloatField {
                    displayName = "Debug Exposure", getter = () => lightingDebugSettings.debugExposure, setter = value => lightingDebugSettings.debugExposure = value
                });
            }

            m_DebugLightingItems = list.ToArray();
            var panel = DebugManager.instance.GetPanel(k_PanelLighting, true);

            panel.children.Add(m_DebugLightingItems);
        }
        void RegisterScreenSpaceTracingDebug()
        {
            var list = new List <DebugUI.Container>();

            var refractionContainer = new DebugUI.Container
            {
                displayName = "Refraction",
                children    =
                {
                    new DebugUI.BoolField {
                        displayName = "Debug Enabled", getter = IsScreenSpaceTracingRefractionDebugEnabled, setter = SetScreenSpaceTracingRefractionDebugEnabled, onValueChanged = RefreshScreenSpaceTracingDebug
                    },
                }
            };

            list.Add(refractionContainer);

            if (IsScreenSpaceTracingRefractionDebugEnabled())
            {
                var debugSettingsContainer = new DebugUI.Container
                {
                    displayName = "Debug Settings",
                    children    =
                    {
                        new DebugUI.Value {
                            displayName = string.Empty, getter = () => "Click in the scene view, or press 'End' key to select the pixel under the mouse in the scene view to debug."
                        },
                        new DebugUI.Value {
                            displayName = "SSRay Model", getter = () => screenSpaceTracingDebugData.tracingModel
                        }
                    }
                };
                refractionContainer.children.Add(debugSettingsContainer);

                switch (screenSpaceTracingDebugData.tracingModel)
                {
                case Lit.RefractionSSRayModel.Proxy:
                {
                    debugSettingsContainer.children.Add(
                        new DebugUI.EnumField {
                            displayName = "Debug Mode", getter = GetDebugLightingSubMode, setter = SetScreenSpaceTracingRefractionDebugMode, enumNames = debugScreenSpaceTracingProxyStrings, enumValues = debugScreenSpaceTracingProxyValues, onValueChanged = RefreshScreenSpaceTracingDebug
                        }
                        );
                    refractionContainer.children.Add(
                        new DebugUI.Container
                        {
                            displayName = "Debug Values",
                            children    =
                            {
                                new DebugUI.Value {
                                    displayName = "Hit Success", getter = () => screenSpaceTracingDebugData.endHitSuccess
                                },
                                new DebugUI.Value {
                                    displayName = "Proxy Shape", getter = () => screenSpaceTracingDebugData.proxyShapeType
                                },
                                new DebugUI.Value {
                                    displayName = "Projection Distance", getter = () => screenSpaceTracingDebugData.projectionDistance
                                },
                                new DebugUI.Value {
                                    displayName = "Start Position", getter = () => screenSpaceTracingDebugData.loopStartPositionSS
                                },
                                new DebugUI.Value {
                                    displayName = "Start Linear Depth", getter = () => screenSpaceTracingDebugData.loopStartLinearDepth
                                },
                                new DebugUI.Value {
                                    displayName = "End Linear Depth", getter = () => screenSpaceTracingDebugData.endLinearDepth
                                },
                                new DebugUI.Value {
                                    displayName = "End Position", getter = () => screenSpaceTracingDebugData.endPositionSS
                                },
                            }
                        }
                        );
                    break;
                }

                case Lit.RefractionSSRayModel.HiZ:
                {
                    debugSettingsContainer.children.Insert(1, new DebugUI.Value {
                            displayName = string.Empty, getter = () => "Press PageUp/PageDown to Increase/Decrease the HiZ step."
                        });
                    debugSettingsContainer.children.Add(
                        new DebugUI.EnumField {
                            displayName = "Debug Mode", getter = GetDebugLightingSubMode, setter = SetScreenSpaceTracingRefractionDebugMode, enumNames = debugScreenSpaceTracingHiZStrings, enumValues = debugScreenSpaceTracingHiZValues, onValueChanged = RefreshScreenSpaceTracingDebug
                        },
                        new DebugUI.BoolField {
                            displayName = "Display Grid", getter = () => showSSRayGrid, setter = v => showSSRayGrid = v
                        },
                        new DebugUI.BoolField {
                            displayName = "Display Depth", getter = () => showSSRayDepthPyramid, setter = v => showSSRayDepthPyramid = v
                        }
                        );
                    refractionContainer.children.Add(
                        new DebugUI.Container
                        {
                            displayName = "Debug Values (loop)",
                            children    =
                            {
                                new DebugUI.Value {
                                    displayName = "Hit Success", getter = () => screenSpaceTracingDebugData.endHitSuccess
                                },
                                new DebugUI.Value {
                                    displayName = "Start Position", getter = () => screenSpaceTracingDebugData.loopStartPositionSS
                                },
                                new DebugUI.Value {
                                    displayName = "Start Linear Depth", getter = () => screenSpaceTracingDebugData.loopStartLinearDepth
                                },
                                new DebugUI.Value {
                                    displayName = "Ray Direction SS", getter = () => new Vector2(screenSpaceTracingDebugData.loopRayDirectionSS.x, screenSpaceTracingDebugData.loopRayDirectionSS.y)
                                },
                                new DebugUI.Value {
                                    displayName = "Ray Depth", getter = () => 1f / screenSpaceTracingDebugData.loopRayDirectionSS.z
                                },
                                new DebugUI.Value {
                                    displayName = "End Position", getter = () => screenSpaceTracingDebugData.endPositionSS
                                },
                                new DebugUI.Value {
                                    displayName = "End Linear Depth", getter = () => screenSpaceTracingDebugData.endLinearDepth
                                },
                            }
                        },
                        new DebugUI.Container
                        {
                            displayName = "Debug Values (iteration)",
                            children    =
                            {
                                new DebugUI.Value {
                                    displayName = "Iteration", getter = () => string.Format("{0}/{1}", screenSpaceTracingDebugData.iteration, screenSpaceTracingDebugData.loopIterationMax)
                                },
                                new DebugUI.Value {
                                    displayName = "Position SS", getter = () => new Vector2(screenSpaceTracingDebugData.iterationPositionSS.x, screenSpaceTracingDebugData.iterationPositionSS.y)
                                },
                                new DebugUI.Value {
                                    displayName = "Depth", getter = () => 1f / screenSpaceTracingDebugData.iterationPositionSS.z
                                },
                                new DebugUI.Value {
                                    displayName = "Depth Buffer", getter = () => screenSpaceTracingDebugData.iterationLinearDepthBuffer
                                },
                                new DebugUI.Value {
                                    displayName = "Mip Level", getter = () => string.Format("{0}/{1}", screenSpaceTracingDebugData.iterationMipLevel, screenSpaceTracingDebugData.loopMipLevelMax)
                                },
                                new DebugUI.Value {
                                    displayName = "Intersection kind", getter = () => screenSpaceTracingDebugData.iterationIntersectionKind
                                },
                                new DebugUI.Value {
                                    displayName = "Cell Id", getter = () => screenSpaceTracingDebugData.iterationCellId
                                },
                                new DebugUI.Value {
                                    displayName = "Cell Size", getter = () => screenSpaceTracingDebugData.iterationCellSize
                                },
                            }
                        }
                        );
                    break;
                }
                }
            }

            m_DebugScreenSpaceTracingItems = list.ToArray();
            var panel = DebugManager.instance.GetPanel(k_PanelScreenSpaceTracing, true);

            panel.flags |= DebugUI.Flags.EditorForceUpdate;
            panel.children.Add(m_DebugScreenSpaceTracingItems);
        }