1989 lines
110 KiB
C#
1989 lines
110 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using UnityEngine.Rendering.HighDefinition.Attributes;
|
|
|
|
namespace UnityEngine.Rendering.HighDefinition
|
|
{
|
|
[GenerateHLSL(needAccessors = false, generateCBuffer = true)]
|
|
unsafe struct ShaderVariablesDebugDisplay
|
|
{
|
|
[HLSLArray(32, typeof(Vector4))]
|
|
public fixed float _DebugRenderingLayersColors[32 * 4];
|
|
[HLSLArray(11, typeof(ShaderGenUInt4))]
|
|
public fixed uint _DebugViewMaterialArray[11 * 4]; // Contain the id (define in various materialXXX.cs.hlsl) of the property to display
|
|
|
|
public int _DebugLightingMode; // Match enum DebugLightingMode
|
|
public int _DebugLightLayersMask;
|
|
public int _DebugShadowMapMode;
|
|
public int _DebugMipMapMode; // Match enum DebugMipMapMode
|
|
|
|
public int _DebugFullScreenMode;
|
|
public float _DebugTransparencyOverdrawWeight;
|
|
public int _DebugMipMapModeTerrainTexture; // Match enum DebugMipMapModeTerrainTexture
|
|
public int _ColorPickerMode; // Match enum ColorPickerDebugMode
|
|
|
|
public Vector4 _DebugLightingAlbedo; // x == bool override, yzw = albedo for diffuse
|
|
public Vector4 _DebugLightingSmoothness; // x == bool override, y == override value
|
|
public Vector4 _DebugLightingNormal; // x == bool override
|
|
public Vector4 _DebugLightingAmbientOcclusion; // x == bool override, y == override value
|
|
public Vector4 _DebugLightingSpecularColor; // x == bool override, yzw = specular color
|
|
public Vector4 _DebugLightingEmissiveColor; // x == bool override, yzw = emissive color
|
|
public Vector4 _DebugLightingMaterialValidateHighColor; // user can specific the colors for the validator error conditions
|
|
public Vector4 _DebugLightingMaterialValidateLowColor;
|
|
public Vector4 _DebugLightingMaterialValidatePureMetalColor;
|
|
public Vector4 _MousePixelCoord; // xy unorm, zw norm
|
|
public Vector4 _MouseClickPixelCoord; // xy unorm, zw norm
|
|
|
|
public int _MatcapMixAlbedo;
|
|
public float _MatcapViewScale;
|
|
public int _DebugSingleShadowIndex;
|
|
|
|
public int _DebugProbeVolumeMode;
|
|
public int _DebugAOVOutput;
|
|
public int _DebugDisplayPad0;
|
|
public int _DebugDisplayPad1;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Full Screen Debug Mode.
|
|
/// </summary>
|
|
[GenerateHLSL]
|
|
public enum FullScreenDebugMode
|
|
{
|
|
/// <summary>No Full Screen debug mode.</summary>
|
|
None,
|
|
|
|
// Lighting
|
|
/// <summary>Minimum Full Screen Lighting debug mode value (used internally).</summary>
|
|
MinLightingFullScreenDebug,
|
|
/// <summary>Display Screen Space Ambient Occlusion buffer.</summary>
|
|
ScreenSpaceAmbientOcclusion,
|
|
/// <summary>Display Screen Space Reflections buffer used for lighting.</summary>
|
|
ScreenSpaceReflections,
|
|
/// <summary>Display the Transparent Screen Space Reflections buffer.</summary>
|
|
TransparentScreenSpaceReflections,
|
|
/// <summary>Display Contact Shadows buffer.</summary>
|
|
ContactShadows,
|
|
/// <summary>Display Contact Shadows fade.</summary>
|
|
ContactShadowsFade,
|
|
/// <summary>Display Screen Space Shadows.</summary>
|
|
ScreenSpaceShadows,
|
|
/// <summary>Displays the color pyramid before the refraction pass.</summary>
|
|
PreRefractionColorPyramid,
|
|
/// <summary>Display the Depth Pyramid.</summary>
|
|
DepthPyramid,
|
|
/// <summary>Display the final color pyramid for the frame.</summary>
|
|
FinalColorPyramid,
|
|
|
|
// Raytracing Only
|
|
/// <summary>Display ray tracing light cluster.</summary>
|
|
LightCluster,
|
|
/// <summary>Display screen space global illumination.</summary>
|
|
ScreenSpaceGlobalIllumination,
|
|
/// <summary>Display recursive ray tracing.</summary>
|
|
RecursiveRayTracing,
|
|
/// <summary>Display ray-traced sub-surface scattering.</summary>
|
|
RayTracedSubSurface,
|
|
/// <summary>Maximum Full Screen Lighting debug mode value (used internally).</summary>
|
|
MaxLightingFullScreenDebug,
|
|
|
|
// Rendering
|
|
/// <summary>Minimum Full Screen Rendering debug mode value (used internally).</summary>
|
|
MinRenderingFullScreenDebug,
|
|
/// <summary>Display Motion Vectors.</summary>
|
|
MotionVectors,
|
|
/// <summary>Display NaNs.</summary>
|
|
NanTracker,
|
|
/// <summary>Display Log of the color buffer.</summary>
|
|
ColorLog,
|
|
/// <summary>Display Depth of Field circle of confusion.</summary>
|
|
DepthOfFieldCoc,
|
|
/// <summary>Display Transparency Overdraw.</summary>
|
|
TransparencyOverdraw,
|
|
/// <summary>Display Quad Overdraw.</summary>
|
|
QuadOverdraw,
|
|
/// <summary>Display Vertex Density.</summary>
|
|
VertexDensity,
|
|
/// <summary>Display Requested Virtual Texturing tiles, colored by the mip</summary>
|
|
RequestedVirtualTextureTiles,
|
|
/// <summary>Maximum Full Screen Rendering debug mode value (used internally).</summary>
|
|
MaxRenderingFullScreenDebug,
|
|
|
|
//Material
|
|
/// <summary>Minimum Full Screen Material debug mode value (used internally).</summary>
|
|
MinMaterialFullScreenDebug,
|
|
/// <summary>Display Diffuse Color validation mode.</summary>
|
|
ValidateDiffuseColor,
|
|
/// <summary>Display specular Color validation mode.</summary>
|
|
ValidateSpecularColor,
|
|
/// <summary>Maximum Full Screen Material debug mode value (used internally).</summary>
|
|
MaxMaterialFullScreenDebug,
|
|
// TODO: Move before count for 11.0
|
|
/// <summary>Display Screen Space Reflections buffer of the previous frame accumulated.</summary>
|
|
ScreenSpaceReflectionsPrev,
|
|
/// <summary>Display Screen Space Reflections buffer of the current frame hit.</summary>
|
|
ScreenSpaceReflectionsAccum
|
|
}
|
|
|
|
/// <summary>
|
|
/// Class managing debug display in HDRP.
|
|
/// </summary>
|
|
public class DebugDisplaySettings : IDebugData
|
|
{
|
|
static string k_PanelDisplayStats = "Display Stats";
|
|
static string k_PanelMaterials = "Material";
|
|
static string k_PanelLighting = "Lighting";
|
|
static string k_PanelVolume = "Volume";
|
|
static string k_PanelRendering = "Rendering";
|
|
static string k_PanelDecals = "Decals";
|
|
|
|
DebugUI.Widget[] m_DebugDisplayStatsItems;
|
|
DebugUI.Widget[] m_DebugMaterialItems;
|
|
DebugUI.Widget[] m_DebugLightingItems;
|
|
DebugUI.Widget[] m_DebugVolumeItems;
|
|
DebugUI.Widget[] m_DebugRenderingItems;
|
|
DebugUI.Widget[] m_DebugDecalsAffectingTransparentItems;
|
|
|
|
static GUIContent[] s_LightingFullScreenDebugStrings = null;
|
|
static int[] s_LightingFullScreenDebugValues = null;
|
|
static GUIContent[] s_RenderingFullScreenDebugStrings = null;
|
|
static int[] s_RenderingFullScreenDebugValues = null;
|
|
static GUIContent[] s_MaterialFullScreenDebugStrings = null;
|
|
static int[] s_MaterialFullScreenDebugValues = null;
|
|
static GUIContent[] s_MsaaSamplesDebugStrings = null;
|
|
static int[] s_MsaaSamplesDebugValues = null;
|
|
static GUIContent[] s_TileAndClusterDebugStrings = null;
|
|
static int[] s_TileAndClusterDebugValues = null;
|
|
|
|
static List<GUIContent> s_CameraNames = new List<GUIContent>();
|
|
static GUIContent[] s_CameraNamesStrings = null;
|
|
static int[] s_CameraNamesValues = null;
|
|
|
|
static bool needsRefreshingCameraFreezeList = true;
|
|
|
|
List<ProfilingSampler> m_RecordedSamplers = new List<ProfilingSampler>();
|
|
|
|
// Accumulate values to avg over one second.
|
|
class AccumulatedTiming
|
|
{
|
|
public float accumulatedValue = 0;
|
|
public float lastAverage = 0;
|
|
|
|
internal void UpdateLastAverage(int frameCount)
|
|
{
|
|
lastAverage = accumulatedValue / frameCount;
|
|
accumulatedValue = 0.0f;
|
|
}
|
|
}
|
|
Dictionary<string, AccumulatedTiming> m_AccumulatedGPUTiming = new Dictionary<string, AccumulatedTiming>();
|
|
Dictionary<string, AccumulatedTiming> m_AccumulatedCPUTiming = new Dictionary<string, AccumulatedTiming>();
|
|
Dictionary<string, AccumulatedTiming> m_AccumulatedInlineCPUTiming = new Dictionary<string, AccumulatedTiming>();
|
|
float m_TimeSinceLastAvgValue = 0.0f;
|
|
int m_AccumulatedFrames = 0;
|
|
const float k_AccumulationTimeInSeconds = 1.0f;
|
|
|
|
List<ProfilingSampler> m_RecordedSamplersRT = new List<ProfilingSampler>();
|
|
enum DebugProfilingType
|
|
{
|
|
CPU,
|
|
GPU,
|
|
InlineCPU
|
|
}
|
|
|
|
/// <summary>
|
|
/// Debug data.
|
|
/// </summary>
|
|
public class DebugData
|
|
{
|
|
/// <summary>Ratio of the screen size in which overlays are rendered.</summary>
|
|
public float debugOverlayRatio = 0.33f;
|
|
/// <summary>Current full screen debug mode.</summary>
|
|
public FullScreenDebugMode fullScreenDebugMode = FullScreenDebugMode.None;
|
|
/// <summary>Enable range remapping.</summary>
|
|
public bool enableDebugDepthRemap = false; // False per default to be compliant with AOV depth output (AOV depth must export unmodified linear depth)
|
|
/// <summary>Depth Range remapping values for some of the fullscreen mode. Only x and y are used.</summary>
|
|
public Vector4 fullScreenDebugDepthRemap = new Vector4(0.0f, 1.0f, 0.0f, 0.0f);
|
|
/// <summary>Current full screen debug mode mip level (when applicable).</summary>
|
|
public float fullscreenDebugMip = 0.0f;
|
|
/// <summary>Index of the light used for contact shadows display.</summary>
|
|
public int fullScreenContactShadowLightIndex = 0;
|
|
/// <summary>XR single pass test mode.</summary>
|
|
public bool xrSinglePassTestMode = false;
|
|
/// <summary>Whether to display the average timings every second.</summary>
|
|
public bool averageProfilerTimingsOverASecond = false;
|
|
|
|
/// <summary>Current material debug settings.</summary>
|
|
public MaterialDebugSettings materialDebugSettings = new MaterialDebugSettings();
|
|
/// <summary>Current lighting debug settings.</summary>
|
|
public LightingDebugSettings lightingDebugSettings = new LightingDebugSettings();
|
|
/// <summary>Current mip map debug settings.</summary>
|
|
public MipMapDebugSettings mipMapDebugSettings = new MipMapDebugSettings();
|
|
/// <summary>Current color picker debug settings.</summary>
|
|
public ColorPickerDebugSettings colorPickerDebugSettings = new ColorPickerDebugSettings();
|
|
/// <summary>Current false color debug settings.</summary>
|
|
public FalseColorDebugSettings falseColorDebugSettings = new FalseColorDebugSettings();
|
|
/// <summary>Current decals debug settings.</summary>
|
|
public DecalsDebugSettings decalsDebugSettings = new DecalsDebugSettings();
|
|
/// <summary>Current transparency debug settings.</summary>
|
|
public TransparencyDebugSettings transparencyDebugSettings = new TransparencyDebugSettings();
|
|
/// <summary>Current volume debug settings.</summary>
|
|
public VolumeDebugSettings volumeDebugSettings = new VolumeDebugSettings();
|
|
/// <summary>Current number of samples for MSAA textures.</summary>
|
|
public MSAASamples msaaSamples = MSAASamples.None;
|
|
/// <summary>Index of screen space shadow to display.</summary>
|
|
public uint screenSpaceShadowIndex = 0;
|
|
/// <summary>Max quad cost for quad overdraw display.</summary>
|
|
public uint maxQuadCost = 5;
|
|
/// <summary>Max vertex density for vertex density display.</summary>
|
|
public uint maxVertexDensity = 10;
|
|
/// <summary>Display ray tracing ray count per frame.</summary>
|
|
public bool countRays = false;
|
|
|
|
/// <summary>Index of the camera to freeze for visibility.</summary>
|
|
public int debugCameraToFreeze = 0;
|
|
|
|
// TODO: The only reason this exist is because of Material/Engine debug enums
|
|
// They have repeating values, which caused issues when iterating through the enum, thus the need for explicit indices
|
|
// Once we refactor material/engine debug to avoid repeating values, we should be able to remove that.
|
|
//saved enum fields for when repainting
|
|
internal int lightingDebugModeEnumIndex;
|
|
internal int lightingFulscreenDebugModeEnumIndex;
|
|
internal int materialValidatorDebugModeEnumIndex;
|
|
internal int tileClusterDebugEnumIndex;
|
|
internal int mipMapsEnumIndex;
|
|
internal int engineEnumIndex;
|
|
internal int attributesEnumIndex;
|
|
internal int propertiesEnumIndex;
|
|
internal int gBufferEnumIndex;
|
|
internal int shadowDebugModeEnumIndex;
|
|
internal int tileClusterDebugByCategoryEnumIndex;
|
|
internal int clusterDebugModeEnumIndex;
|
|
internal int lightVolumeDebugTypeEnumIndex;
|
|
internal int renderingFulscreenDebugModeEnumIndex;
|
|
internal int terrainTextureEnumIndex;
|
|
internal int colorPickerDebugModeEnumIndex;
|
|
internal int exposureDebugModeEnumIndex;
|
|
internal int msaaSampleDebugModeEnumIndex;
|
|
internal int debugCameraToFreezeEnumIndex;
|
|
internal int volumeComponentEnumIndex;
|
|
internal int volumeCameraEnumIndex;
|
|
internal int probeVolumeDebugModeEnumIndex;
|
|
internal int probeVolumeAtlasSliceModeEnumIndex;
|
|
|
|
// When settings mutually exclusives enum values, we need to reset the other ones.
|
|
internal void ResetExclusiveEnumIndices()
|
|
{
|
|
materialDebugSettings.materialEnumIndex = 0;
|
|
lightingDebugModeEnumIndex = 0;
|
|
mipMapsEnumIndex = 0;
|
|
engineEnumIndex = 0;
|
|
attributesEnumIndex = 0;
|
|
propertiesEnumIndex = 0;
|
|
gBufferEnumIndex = 0;
|
|
lightingFulscreenDebugModeEnumIndex = 0;
|
|
renderingFulscreenDebugModeEnumIndex = 0;
|
|
}
|
|
}
|
|
DebugData m_Data;
|
|
|
|
/// <summary>
|
|
/// Debug data.
|
|
/// </summary>
|
|
public DebugData data { get => m_Data; }
|
|
|
|
// Had to keep those public because HDRP tests using it (as a workaround to access proper enum values for this debug)
|
|
/// <summary>List of Full Screen Rendering Debug mode names.</summary>
|
|
public static GUIContent[] renderingFullScreenDebugStrings => s_RenderingFullScreenDebugStrings;
|
|
/// <summary>List of Full Screen Rendering Debug mode values.</summary>
|
|
public static int[] renderingFullScreenDebugValues => s_RenderingFullScreenDebugValues;
|
|
|
|
/// <summary>List of Full Screen Lighting Debug mode names.</summary>
|
|
public static GUIContent[] lightingFullScreenDebugStrings => s_LightingFullScreenDebugStrings;
|
|
/// <summary>List of Full Screen Lighting Debug mode values.</summary>
|
|
public static int[] lightingFullScreenDebugValues => s_LightingFullScreenDebugValues;
|
|
|
|
internal DebugDisplaySettings()
|
|
{
|
|
FillFullScreenDebugEnum(ref s_LightingFullScreenDebugStrings, ref s_LightingFullScreenDebugValues, FullScreenDebugMode.MinLightingFullScreenDebug, FullScreenDebugMode.MaxLightingFullScreenDebug);
|
|
FillFullScreenDebugEnum(ref s_RenderingFullScreenDebugStrings, ref s_RenderingFullScreenDebugValues, FullScreenDebugMode.MinRenderingFullScreenDebug, FullScreenDebugMode.MaxRenderingFullScreenDebug);
|
|
FillFullScreenDebugEnum(ref s_MaterialFullScreenDebugStrings, ref s_MaterialFullScreenDebugValues, FullScreenDebugMode.MinMaterialFullScreenDebug, FullScreenDebugMode.MaxMaterialFullScreenDebug);
|
|
|
|
var device = SystemInfo.graphicsDeviceType;
|
|
if (device == GraphicsDeviceType.Metal)
|
|
{
|
|
s_RenderingFullScreenDebugStrings = s_RenderingFullScreenDebugStrings.Where((val, idx) => (idx + FullScreenDebugMode.MinRenderingFullScreenDebug) != FullScreenDebugMode.VertexDensity).ToArray();
|
|
s_RenderingFullScreenDebugValues = s_RenderingFullScreenDebugValues.Where((val, idx) => (idx + FullScreenDebugMode.MinRenderingFullScreenDebug) != FullScreenDebugMode.VertexDensity).ToArray();
|
|
}
|
|
if (device == GraphicsDeviceType.Metal || device == GraphicsDeviceType.PlayStation4 || device == GraphicsDeviceType.PlayStation5)
|
|
{
|
|
s_RenderingFullScreenDebugStrings = s_RenderingFullScreenDebugStrings.Where((val, idx) => (idx + FullScreenDebugMode.MinRenderingFullScreenDebug) != FullScreenDebugMode.QuadOverdraw).ToArray();
|
|
s_RenderingFullScreenDebugValues = s_RenderingFullScreenDebugValues.Where((val, idx) => (idx + FullScreenDebugMode.MinRenderingFullScreenDebug) != FullScreenDebugMode.QuadOverdraw).ToArray();
|
|
}
|
|
|
|
FillTileClusterDebugEnum();
|
|
|
|
s_MaterialFullScreenDebugStrings[(int)FullScreenDebugMode.ValidateDiffuseColor - ((int)FullScreenDebugMode.MinMaterialFullScreenDebug)] = new GUIContent("Diffuse Color");
|
|
s_MaterialFullScreenDebugStrings[(int)FullScreenDebugMode.ValidateSpecularColor - ((int)FullScreenDebugMode.MinMaterialFullScreenDebug)] = new GUIContent("Metal or SpecularColor");
|
|
|
|
s_MsaaSamplesDebugStrings = Enum.GetNames(typeof(MSAASamples))
|
|
.Select(t => new GUIContent(t))
|
|
.ToArray();
|
|
s_MsaaSamplesDebugValues = (int[])Enum.GetValues(typeof(MSAASamples));
|
|
|
|
m_Data = new DebugData();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Reset action.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
Action IDebugData.GetReset() => () => m_Data = new DebugData();
|
|
|
|
internal float[] GetDebugMaterialIndexes()
|
|
{
|
|
return data.materialDebugSettings.GetDebugMaterialIndexes();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the current Light filtering mode.
|
|
/// </summary>
|
|
/// <returns>Current Light filtering mode.</returns>
|
|
public DebugLightFilterMode GetDebugLightFilterMode()
|
|
{
|
|
return data.lightingDebugSettings.debugLightFilterMode;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the current Lighting Debug Mode.
|
|
/// </summary>
|
|
/// <returns>Current Lighting Debug Mode.</returns>
|
|
public DebugLightingMode GetDebugLightingMode()
|
|
{
|
|
return data.lightingDebugSettings.debugLightingMode;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the current Light Layers Debug Mask.
|
|
/// </summary>
|
|
/// <returns>Current Light Layers Debug Mask.</returns>
|
|
public DebugLightLayersMask GetDebugLightLayersMask()
|
|
{
|
|
var settings = data.lightingDebugSettings;
|
|
if (!settings.debugLightLayers)
|
|
return 0;
|
|
|
|
#if UNITY_EDITOR
|
|
if (settings.debugSelectionLightLayers)
|
|
{
|
|
if (UnityEditor.Selection.activeGameObject == null)
|
|
return 0;
|
|
var light = UnityEditor.Selection.activeGameObject.GetComponent<HDAdditionalLightData>();
|
|
if (light == null)
|
|
return 0;
|
|
|
|
if (settings.debugSelectionShadowLayers)
|
|
return (DebugLightLayersMask)light.GetShadowLayers();
|
|
return (DebugLightLayersMask)light.GetLightLayers();
|
|
}
|
|
#endif
|
|
|
|
return settings.debugLightLayersFilterMask;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the current Shadow Map Debug Mode.
|
|
/// </summary>
|
|
/// <returns>Current Shadow Map Debug Mode.</returns>
|
|
public ShadowMapDebugMode GetDebugShadowMapMode()
|
|
{
|
|
return data.lightingDebugSettings.shadowDebugMode;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the current Mip Map Debug Mode.
|
|
/// </summary>
|
|
/// <returns>Current Mip Map Debug Mode.</returns>
|
|
public DebugMipMapMode GetDebugMipMapMode()
|
|
{
|
|
return data.mipMapDebugSettings.debugMipMapMode;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the current Terrain Texture Mip Map Debug Mode.
|
|
/// </summary>
|
|
/// <returns>Current Terrain Texture Mip Map Debug Mode.</returns>
|
|
public DebugMipMapModeTerrainTexture GetDebugMipMapModeTerrainTexture()
|
|
{
|
|
return data.mipMapDebugSettings.terrainTexture;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the current Color Picker Mode.
|
|
/// </summary>
|
|
/// <returns>Current Color Picker Mode.</returns>
|
|
public ColorPickerDebugMode GetDebugColorPickerMode()
|
|
{
|
|
return data.colorPickerDebugSettings.colorPickerMode;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the current Probe Volume Debug Mode.
|
|
/// </summary>
|
|
/// <returns>Current Probe Volume Debug Mode.</returns>
|
|
internal ProbeVolumeDebugMode GetProbeVolumeDebugMode()
|
|
{
|
|
return data.lightingDebugSettings.probeVolumeDebugMode;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if camera visibility is frozen.
|
|
/// </summary>
|
|
/// <returns>True if camera visibility is frozen</returns>
|
|
public bool IsCameraFreezeEnabled()
|
|
{
|
|
return data.debugCameraToFreeze != 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if a specific camera is frozen for visibility.
|
|
/// </summary>
|
|
/// <param name="camera">Camera to be tested.</param>
|
|
/// <returns>True if a specific camera is frozen for visibility.</returns>
|
|
public bool IsCameraFrozen(Camera camera)
|
|
{
|
|
return IsCameraFreezeEnabled() && camera.name.Equals(s_CameraNamesStrings[data.debugCameraToFreeze].text);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if any debug display is enabled.
|
|
/// </summary>
|
|
/// <returns>True if any debug display is enabled.</returns>
|
|
public bool IsDebugDisplayEnabled()
|
|
{
|
|
return data.materialDebugSettings.IsDebugDisplayEnabled() || data.lightingDebugSettings.IsDebugDisplayEnabled() || data.mipMapDebugSettings.IsDebugDisplayEnabled() || IsDebugFullScreenEnabled();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if any material debug display is enabled.
|
|
/// </summary>
|
|
/// <returns>True if any material debug display is enabled.</returns>
|
|
public bool IsDebugMaterialDisplayEnabled()
|
|
{
|
|
return data.materialDebugSettings.IsDebugDisplayEnabled();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if any full screen debug display is enabled.
|
|
/// </summary>
|
|
/// <returns>True if any full screen debug display is enabled.</returns>
|
|
public bool IsDebugFullScreenEnabled()
|
|
{
|
|
return data.fullScreenDebugMode != FullScreenDebugMode.None;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if a full screen debug display supporting the FullScreenDebug pass is enabled.
|
|
/// </summary>
|
|
/// <returns>True if a full screen debug display supporting the FullScreenDebug pass is enabled.</returns>
|
|
internal bool IsFullScreenDebugPassEnabled()
|
|
{
|
|
return data.fullScreenDebugMode == FullScreenDebugMode.QuadOverdraw ||
|
|
data.fullScreenDebugMode == FullScreenDebugMode.VertexDensity;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if any full screen exposure debug display is enabled.
|
|
/// </summary>
|
|
/// <returns>True if any full screen exposure debug display is enabled.</returns>
|
|
public bool IsDebugExposureModeEnabled()
|
|
{
|
|
return data.lightingDebugSettings.exposureDebugMode != ExposureDebugMode.None;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if material validation is enabled.
|
|
/// </summary>
|
|
/// <returns>True if any material validation is enabled.</returns>
|
|
public bool IsMaterialValidationEnabled()
|
|
{
|
|
return (data.fullScreenDebugMode == FullScreenDebugMode.ValidateDiffuseColor) || (data.fullScreenDebugMode == FullScreenDebugMode.ValidateSpecularColor);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if mip map debug display is enabled.
|
|
/// </summary>
|
|
/// <returns>True if any mip mapdebug display is enabled.</returns>
|
|
public bool IsDebugMipMapDisplayEnabled()
|
|
{
|
|
return data.mipMapDebugSettings.IsDebugDisplayEnabled();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if matcap view is enabled for a particular camera.
|
|
/// </summary>
|
|
/// <param name="camera">Input camera.</param>
|
|
/// <returns>True if matcap view is enabled for a particular camera.</returns>
|
|
public bool IsMatcapViewEnabled(HDCamera camera)
|
|
{
|
|
bool sceneViewLightingDisabled = CoreUtils.IsSceneLightingDisabled(camera.camera);
|
|
return sceneViewLightingDisabled || GetDebugLightingMode() == DebugLightingMode.MatcapView;
|
|
}
|
|
|
|
private void DisableNonMaterialDebugSettings()
|
|
{
|
|
data.fullScreenDebugMode = FullScreenDebugMode.None;
|
|
data.lightingDebugSettings.debugLightingMode = DebugLightingMode.None;
|
|
data.mipMapDebugSettings.debugMipMapMode = DebugMipMapMode.None;
|
|
data.lightingDebugSettings.debugLightLayers = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the current shared material properties debug view.
|
|
/// </summary>
|
|
/// <param name="value">Desired shared material property to display.</param>
|
|
public void SetDebugViewCommonMaterialProperty(MaterialSharedProperty value)
|
|
{
|
|
if (value != MaterialSharedProperty.None)
|
|
DisableNonMaterialDebugSettings();
|
|
data.materialDebugSettings.SetDebugViewCommonMaterialProperty(value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the current material debug view.
|
|
/// </summary>
|
|
/// <param name="value">Desired material debug view.</param>
|
|
public void SetDebugViewMaterial(int value)
|
|
{
|
|
if (value != 0)
|
|
DisableNonMaterialDebugSettings();
|
|
data.materialDebugSettings.SetDebugViewMaterial(value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the current engine debug view.
|
|
/// </summary>
|
|
/// <param name="value">Desired engine debug view.</param>
|
|
public void SetDebugViewEngine(int value)
|
|
{
|
|
if (value != 0)
|
|
DisableNonMaterialDebugSettings();
|
|
data.materialDebugSettings.SetDebugViewEngine(value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set current varying debug view.
|
|
/// </summary>
|
|
/// <param name="value">Desired varying debug view.</param>
|
|
public void SetDebugViewVarying(DebugViewVarying value)
|
|
{
|
|
if (value != 0)
|
|
DisableNonMaterialDebugSettings();
|
|
data.materialDebugSettings.SetDebugViewVarying(value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the current Material Property debug view.
|
|
/// </summary>
|
|
/// <param name="value">Desired property debug view.</param>
|
|
public void SetDebugViewProperties(DebugViewProperties value)
|
|
{
|
|
if (value != 0)
|
|
DisableNonMaterialDebugSettings();
|
|
data.materialDebugSettings.SetDebugViewProperties(value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the current GBuffer debug view.
|
|
/// </summary>
|
|
/// <param name="value">Desired GBuffer debug view.</param>
|
|
public void SetDebugViewGBuffer(int value)
|
|
{
|
|
if (value != 0)
|
|
DisableNonMaterialDebugSettings();
|
|
data.materialDebugSettings.SetDebugViewGBuffer(value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the current Full Screen Debug Mode.
|
|
/// </summary>
|
|
/// <param name="value">Desired Full Screen Debug mode.</param>
|
|
public void SetFullScreenDebugMode(FullScreenDebugMode value)
|
|
{
|
|
if (data.lightingDebugSettings.shadowDebugMode == ShadowMapDebugMode.SingleShadow)
|
|
value = 0;
|
|
|
|
if (value != FullScreenDebugMode.None)
|
|
{
|
|
data.lightingDebugSettings.debugLightingMode = DebugLightingMode.None;
|
|
data.lightingDebugSettings.debugLightLayers = false;
|
|
data.materialDebugSettings.DisableMaterialDebug();
|
|
data.mipMapDebugSettings.debugMipMapMode = DebugMipMapMode.None;
|
|
}
|
|
|
|
data.fullScreenDebugMode = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the current Shadow Map Debug Mode.
|
|
/// </summary>
|
|
/// <param name="value">Desired Shadow Map debug mode.</param>
|
|
public void SetShadowDebugMode(ShadowMapDebugMode value)
|
|
{
|
|
// When SingleShadow is enabled, we don't render full screen debug modes
|
|
if (value == ShadowMapDebugMode.SingleShadow)
|
|
data.fullScreenDebugMode = 0;
|
|
data.lightingDebugSettings.shadowDebugMode = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the current Light Filtering.
|
|
/// </summary>
|
|
/// <param name="value">Desired Light Filtering.</param>
|
|
public void SetDebugLightFilterMode(DebugLightFilterMode value)
|
|
{
|
|
if (value != 0)
|
|
{
|
|
data.materialDebugSettings.DisableMaterialDebug();
|
|
data.mipMapDebugSettings.debugMipMapMode = DebugMipMapMode.None;
|
|
data.lightingDebugSettings.debugLightLayers = false;
|
|
}
|
|
data.lightingDebugSettings.debugLightFilterMode = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the current Light layers Debug Mode
|
|
/// </summary>
|
|
/// <param name="value">Desired Light Layers Debug Mode.</param>
|
|
public void SetDebugLightLayersMode(bool value)
|
|
{
|
|
if (value)
|
|
{
|
|
data.ResetExclusiveEnumIndices();
|
|
data.lightingDebugSettings.debugLightFilterMode = DebugLightFilterMode.None;
|
|
|
|
var builtins = typeof(Builtin.BuiltinData);
|
|
var attr = builtins.GetCustomAttributes(true)[0] as GenerateHLSL;
|
|
var renderingLayers = Array.IndexOf(builtins.GetFields(), builtins.GetField("renderingLayers"));
|
|
|
|
SetDebugViewMaterial(attr.paramDefinesStart + renderingLayers);
|
|
}
|
|
else
|
|
{
|
|
SetDebugViewMaterial(0);
|
|
}
|
|
data.lightingDebugSettings.debugLightLayers = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the current Lighting Debug Mode.
|
|
/// </summary>
|
|
/// <param name="value">Desired Lighting Debug Mode.</param>
|
|
public void SetDebugLightingMode(DebugLightingMode value)
|
|
{
|
|
if (value != 0)
|
|
{
|
|
data.fullScreenDebugMode = FullScreenDebugMode.None;
|
|
data.materialDebugSettings.DisableMaterialDebug();
|
|
data.mipMapDebugSettings.debugMipMapMode = DebugMipMapMode.None;
|
|
data.lightingDebugSettings.debugLightLayers = false;
|
|
}
|
|
data.lightingDebugSettings.debugLightingMode = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the current Probe Volume Debug Mode.
|
|
/// </summary>
|
|
/// <param name="value">Desired Probe Volume Debug Mode.</param>
|
|
internal void SetProbeVolumeDebugMode(ProbeVolumeDebugMode value)
|
|
{
|
|
data.lightingDebugSettings.probeVolumeDebugMode = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the current Probe Volume Atlas Mode.
|
|
/// </summary>
|
|
/// <param name="value">Desired Probe Volume Atlas Mode.</param>
|
|
internal void SetProbeVolumeAtlasSliceMode(ProbeVolumeAtlasSliceMode value)
|
|
{
|
|
data.lightingDebugSettings.probeVolumeAtlasSliceMode = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the current Exposure Debug Mode.
|
|
/// </summary>
|
|
/// <param name="value">Desired Probe Volume Debug Mode.</param>
|
|
internal void SetExposureDebugMode(ExposureDebugMode value)
|
|
{
|
|
data.lightingDebugSettings.exposureDebugMode = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the current Mip Map Debug Mode.
|
|
/// </summary>
|
|
/// <param name="value">Desired Mip Map debug mode.</param>
|
|
public void SetMipMapMode(DebugMipMapMode value)
|
|
{
|
|
if (value != 0)
|
|
{
|
|
data.materialDebugSettings.DisableMaterialDebug();
|
|
data.lightingDebugSettings.debugLightingMode = DebugLightingMode.None;
|
|
data.lightingDebugSettings.debugLightLayers = false;
|
|
data.fullScreenDebugMode = FullScreenDebugMode.None;
|
|
}
|
|
data.mipMapDebugSettings.debugMipMapMode = value;
|
|
}
|
|
|
|
void EnableProfilingRecorders()
|
|
{
|
|
Debug.Assert(m_RecordedSamplers.Count == 0);
|
|
|
|
m_RecordedSamplers.Add(ProfilingSampler.Get(HDProfileId.HDRenderPipelineAllRenderRequest));
|
|
m_RecordedSamplers.Add(ProfilingSampler.Get(HDProfileId.VolumeUpdate));
|
|
m_RecordedSamplers.Add(ProfilingSampler.Get(HDProfileId.RenderShadowMaps));
|
|
m_RecordedSamplers.Add(ProfilingSampler.Get(HDProfileId.GBuffer));
|
|
m_RecordedSamplers.Add(ProfilingSampler.Get(HDProfileId.PrepareLightsForGPU));
|
|
m_RecordedSamplers.Add(ProfilingSampler.Get(HDProfileId.VolumeVoxelization));
|
|
m_RecordedSamplers.Add(ProfilingSampler.Get(HDProfileId.VolumetricLighting));
|
|
m_RecordedSamplers.Add(ProfilingSampler.Get(HDProfileId.RenderDeferredLightingCompute));
|
|
m_RecordedSamplers.Add(ProfilingSampler.Get(HDProfileId.ForwardOpaque));
|
|
m_RecordedSamplers.Add(ProfilingSampler.Get(HDProfileId.ForwardTransparent));
|
|
m_RecordedSamplers.Add(ProfilingSampler.Get(HDProfileId.ForwardPreRefraction));
|
|
m_RecordedSamplers.Add(ProfilingSampler.Get(HDProfileId.ColorPyramid));
|
|
m_RecordedSamplers.Add(ProfilingSampler.Get(HDProfileId.DepthPyramid));
|
|
m_RecordedSamplers.Add(ProfilingSampler.Get(HDProfileId.PostProcessing));
|
|
}
|
|
|
|
void DisableProfilingRecorders()
|
|
{
|
|
foreach (var sampler in m_RecordedSamplers)
|
|
{
|
|
sampler.enableRecording = false;
|
|
}
|
|
|
|
m_RecordedSamplers.Clear();
|
|
}
|
|
|
|
void EnableProfilingRecordersRT()
|
|
{
|
|
Debug.Assert(m_RecordedSamplersRT.Count == 0);
|
|
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingBuildCluster));
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingCullLights));
|
|
|
|
// Ray Traced Reflections
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingReflectionDirectionGeneration));
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingReflectionEvaluation));
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingReflectionAdjustWeight));
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingReflectionUpscale));
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingReflectionFilter));
|
|
|
|
// Ray Traced Ambient Occlusion
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingAmbientOcclusion));
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingFilterAmbientOcclusion));
|
|
|
|
// Ray Traced Shadows
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingDirectionalLightShadow));
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingLightShadow));
|
|
|
|
// Ray Traced Indirect Diffuse
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingIndirectDiffuseDirectionGeneration));
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingIndirectDiffuseEvaluation));
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingIndirectDiffuseUpscale));
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingFilterIndirectDiffuse));
|
|
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingDebugOverlay));
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.ForwardPreRefraction));
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RayTracingRecursiveRendering));
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RayTracingPrepass));
|
|
m_RecordedSamplersRT.Add(ProfilingSampler.Get(HDProfileId.RaytracingDeferredLighting));
|
|
}
|
|
|
|
void DisableProfilingRecordersRT()
|
|
{
|
|
foreach (var sampler in m_RecordedSamplersRT)
|
|
{
|
|
sampler.enableRecording = false;
|
|
}
|
|
|
|
m_RecordedSamplersRT.Clear();
|
|
}
|
|
|
|
float GetSamplerTiming(DebugProfilingType type, ProfilingSampler sampler)
|
|
{
|
|
if (data.averageProfilerTimingsOverASecond)
|
|
{
|
|
// Find the right accumulated dictionary
|
|
var accumulatedDictionary = type == DebugProfilingType.CPU ? m_AccumulatedCPUTiming :
|
|
type == DebugProfilingType.InlineCPU ? m_AccumulatedInlineCPUTiming :
|
|
m_AccumulatedGPUTiming;
|
|
|
|
AccumulatedTiming accTiming = null;
|
|
if (accumulatedDictionary.TryGetValue(sampler.name, out accTiming))
|
|
return accTiming.lastAverage;
|
|
}
|
|
else
|
|
{
|
|
return (type == DebugProfilingType.CPU) ? sampler.cpuElapsedTime : ((type == DebugProfilingType.GPU) ? sampler.gpuElapsedTime : sampler.inlineCpuElapsedTime);
|
|
}
|
|
|
|
return 0.0f;
|
|
}
|
|
|
|
ObservableList<DebugUI.Widget> BuildProfilingSamplerList(DebugProfilingType type)
|
|
{
|
|
var result = new ObservableList<DebugUI.Widget>();
|
|
|
|
// Find the right accumulated dictionary and add it there if not existing yet.
|
|
var accumulatedDictionary = type == DebugProfilingType.CPU ? m_AccumulatedCPUTiming :
|
|
type == DebugProfilingType.InlineCPU ? m_AccumulatedInlineCPUTiming :
|
|
m_AccumulatedGPUTiming;
|
|
|
|
|
|
foreach (var sampler in m_RecordedSamplers)
|
|
{
|
|
sampler.enableRecording = true;
|
|
if (!accumulatedDictionary.ContainsKey(sampler.name))
|
|
{
|
|
accumulatedDictionary.Add(sampler.name, new AccumulatedTiming());
|
|
}
|
|
|
|
result.Add(new DebugUI.Value
|
|
{
|
|
displayName = sampler.name,
|
|
getter = () => string.Format("{0:F2}", GetSamplerTiming(type, sampler)),
|
|
refreshRate = 1.0f / 5.0f
|
|
});
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
ObservableList<DebugUI.Widget> BuildProfilingSamplerListRT(DebugProfilingType type)
|
|
{
|
|
var result = new ObservableList<DebugUI.Widget>();
|
|
|
|
// Find the right accumulated dictionary and add it there if not existing yet.
|
|
var accumulatedDictionary = type == DebugProfilingType.CPU ? m_AccumulatedCPUTiming :
|
|
type == DebugProfilingType.InlineCPU ? m_AccumulatedInlineCPUTiming :
|
|
m_AccumulatedGPUTiming;
|
|
|
|
|
|
foreach (var sampler in m_RecordedSamplersRT)
|
|
{
|
|
sampler.enableRecording = true;
|
|
if (!accumulatedDictionary.ContainsKey(sampler.name))
|
|
{
|
|
accumulatedDictionary.Add(sampler.name, new AccumulatedTiming());
|
|
}
|
|
|
|
result.Add(new DebugUI.Value
|
|
{
|
|
displayName = sampler.name,
|
|
getter = () => string.Format("{0:F2}", GetSamplerTiming(type, sampler)),
|
|
refreshRate = 1.0f / 5.0f
|
|
});
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void UpdateListOfAveragedProfilerTimings(List<ProfilingSampler> samplers, bool needUpdatingAverages)
|
|
{
|
|
foreach (var sampler in samplers)
|
|
{
|
|
// Accumulate.
|
|
AccumulatedTiming accCPUTiming = null;
|
|
if (m_AccumulatedCPUTiming.TryGetValue(sampler.name, out accCPUTiming))
|
|
accCPUTiming.accumulatedValue += sampler.cpuElapsedTime;
|
|
|
|
AccumulatedTiming accInlineCPUTiming = null;
|
|
if (m_AccumulatedInlineCPUTiming.TryGetValue(sampler.name, out accInlineCPUTiming))
|
|
accInlineCPUTiming.accumulatedValue += sampler.inlineCpuElapsedTime;
|
|
|
|
AccumulatedTiming accGPUTiming = null;
|
|
if (m_AccumulatedGPUTiming.TryGetValue(sampler.name, out accGPUTiming))
|
|
accGPUTiming.accumulatedValue += sampler.gpuElapsedTime;
|
|
|
|
if (needUpdatingAverages)
|
|
{
|
|
if (accCPUTiming != null)
|
|
accCPUTiming.UpdateLastAverage(m_AccumulatedFrames);
|
|
if (accInlineCPUTiming != null)
|
|
accInlineCPUTiming.UpdateLastAverage(m_AccumulatedFrames);
|
|
if (accGPUTiming != null)
|
|
accGPUTiming.UpdateLastAverage(m_AccumulatedFrames);
|
|
}
|
|
}
|
|
}
|
|
|
|
internal void UpdateAveragedProfilerTimings()
|
|
{
|
|
m_TimeSinceLastAvgValue += Time.unscaledDeltaTime;
|
|
m_AccumulatedFrames++;
|
|
bool needUpdatingAverages = m_TimeSinceLastAvgValue >= k_AccumulationTimeInSeconds;
|
|
|
|
UpdateListOfAveragedProfilerTimings(m_RecordedSamplers, needUpdatingAverages);
|
|
UpdateListOfAveragedProfilerTimings(m_RecordedSamplersRT, needUpdatingAverages);
|
|
|
|
if (needUpdatingAverages)
|
|
{
|
|
m_TimeSinceLastAvgValue = 0.0f;
|
|
m_AccumulatedFrames = 0;
|
|
}
|
|
}
|
|
|
|
void RegisterDisplayStatsDebug()
|
|
{
|
|
var list = new List<DebugUI.Widget>();
|
|
list.Add(new DebugUI.Value { displayName = "Frame Rate (fps)", getter = () => 1f / Time.smoothDeltaTime, refreshRate = 1f / 5f });
|
|
list.Add(new DebugUI.Value { displayName = "Frame Time (ms)", getter = () => Time.smoothDeltaTime * 1000f, refreshRate = 1f / 5f });
|
|
|
|
|
|
EnableProfilingRecorders();
|
|
list.Add(new DebugUI.BoolField { displayName = "Update every second with average", getter = () => data.averageProfilerTimingsOverASecond, setter = value => data.averageProfilerTimingsOverASecond = value });
|
|
list.Add(new DebugUI.Foldout("CPU timings (Command Buffers)", BuildProfilingSamplerList(DebugProfilingType.CPU)));
|
|
list.Add(new DebugUI.Foldout("GPU timings", BuildProfilingSamplerList(DebugProfilingType.GPU)));
|
|
if (HDRenderPipeline.currentAsset?.currentPlatformRenderPipelineSettings.supportRayTracing ?? true)
|
|
{
|
|
EnableProfilingRecordersRT();
|
|
list.Add(new DebugUI.Foldout("CPU timings RT (Command Buffers)", BuildProfilingSamplerListRT(DebugProfilingType.CPU)));
|
|
list.Add(new DebugUI.Foldout("GPU timings RT", BuildProfilingSamplerListRT(DebugProfilingType.GPU)));
|
|
}
|
|
list.Add(new DebugUI.Foldout("Inline CPU timings", BuildProfilingSamplerList(DebugProfilingType.InlineCPU)));
|
|
list.Add(new DebugUI.BoolField { displayName = "Count Rays (MRays/Frame)", getter = () => data.countRays, setter = value => data.countRays = value, onValueChanged = RefreshDisplayStatsDebug });
|
|
if (data.countRays)
|
|
{
|
|
list.Add(new DebugUI.Container
|
|
{
|
|
children =
|
|
{
|
|
new DebugUI.Value { displayName = "Ambient Occlusion", getter = () => ((float)(RenderPipelineManager.currentPipeline as HDRenderPipeline).GetRaysPerFrame(RayCountValues.AmbientOcclusion)) / 1e6f, refreshRate = 1f / 30f },
|
|
new DebugUI.Value { displayName = "Shadows Directional", getter = () => ((float)(RenderPipelineManager.currentPipeline as HDRenderPipeline).GetRaysPerFrame(RayCountValues.ShadowDirectional)) / 1e6f, refreshRate = 1f / 30f },
|
|
new DebugUI.Value { displayName = "Shadows Area", getter = () => ((float)(RenderPipelineManager.currentPipeline as HDRenderPipeline).GetRaysPerFrame(RayCountValues.ShadowAreaLight)) / 1e6f, refreshRate = 1f / 30f },
|
|
new DebugUI.Value { displayName = "Shadows Point/Spot", getter = () => ((float)(RenderPipelineManager.currentPipeline as HDRenderPipeline).GetRaysPerFrame(RayCountValues.ShadowPointSpot)) / 1e6f, refreshRate = 1f / 30f },
|
|
new DebugUI.Value { displayName = "Reflections Forward ", getter = () => ((float)(RenderPipelineManager.currentPipeline as HDRenderPipeline).GetRaysPerFrame(RayCountValues.ReflectionForward)) / 1e6f, refreshRate = 1f / 30f },
|
|
new DebugUI.Value { displayName = "Reflections Deferred", getter = () => ((float)(RenderPipelineManager.currentPipeline as HDRenderPipeline).GetRaysPerFrame(RayCountValues.ReflectionDeferred)) / 1e6f, refreshRate = 1f / 30f },
|
|
new DebugUI.Value { displayName = "Diffuse GI Forward", getter = () => ((float)(RenderPipelineManager.currentPipeline as HDRenderPipeline).GetRaysPerFrame(RayCountValues.DiffuseGI_Forward)) / 1e6f, refreshRate = 1f / 30f },
|
|
new DebugUI.Value { displayName = "Diffuse GI Deferred", getter = () => ((float)(RenderPipelineManager.currentPipeline as HDRenderPipeline).GetRaysPerFrame(RayCountValues.DiffuseGI_Deferred)) / 1e6f, refreshRate = 1f / 30f },
|
|
new DebugUI.Value { displayName = "Recursive Rendering", getter = () => ((float)(RenderPipelineManager.currentPipeline as HDRenderPipeline).GetRaysPerFrame(RayCountValues.Recursive)) / 1e6f, refreshRate = 1f / 30f },
|
|
new DebugUI.Value { displayName = "Total", getter = () => ((float)(RenderPipelineManager.currentPipeline as HDRenderPipeline).GetRaysPerFrame(RayCountValues.Total)) / 1e6f, refreshRate = 1f / 30f },
|
|
}
|
|
});
|
|
}
|
|
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
list.Add(new DebugUI.BoolField { displayName = "Debug XR Layout", getter = () => XRSystem.dumpDebugInfo, setter = value => XRSystem.dumpDebugInfo = value, onValueChanged = RefreshDisplayStatsDebug });
|
|
if (XRSystem.dumpDebugInfo)
|
|
{
|
|
Func<object> Bind<T>(Func<T, object> func, T arg) => () => func(arg);
|
|
|
|
for (int i = 0; i < XRSystem.passDebugInfos.Count; i++)
|
|
list.Add(new DebugUI.Value { displayName = "", getter = Bind(XRSystem.ReadPassDebugInfo, i) });
|
|
}
|
|
#endif
|
|
|
|
m_DebugDisplayStatsItems = list.ToArray();
|
|
var panel = DebugManager.instance.GetPanel(k_PanelDisplayStats, true);
|
|
panel.flags = DebugUI.Flags.RuntimeOnly;
|
|
panel.children.Add(m_DebugDisplayStatsItems);
|
|
}
|
|
|
|
void RegisterMaterialDebug()
|
|
{
|
|
var list = new List<DebugUI.Widget>();
|
|
|
|
list.Add(new DebugUI.EnumField { displayName = "Common Material Properties", getter = () => (int)data.materialDebugSettings.debugViewMaterialCommonValue, setter = value => SetDebugViewCommonMaterialProperty((MaterialSharedProperty)value), autoEnum = typeof(MaterialSharedProperty), getIndex = () => (int)data.materialDebugSettings.debugViewMaterialCommonValue, setIndex = value => { data.ResetExclusiveEnumIndices(); data.materialDebugSettings.debugViewMaterialCommonValue = (MaterialSharedProperty)value; } });
|
|
list.Add(new DebugUI.EnumField { displayName = "Material", getter = () => (data.materialDebugSettings.debugViewMaterial[0]) == 0 ? 0 : data.materialDebugSettings.debugViewMaterial[1], setter = value => SetDebugViewMaterial(value), enumNames = MaterialDebugSettings.debugViewMaterialStrings, enumValues = MaterialDebugSettings.debugViewMaterialValues, getIndex = () => data.materialDebugSettings.materialEnumIndex, setIndex = value => { data.ResetExclusiveEnumIndices(); data.materialDebugSettings.materialEnumIndex = value; } });
|
|
list.Add(new DebugUI.EnumField { displayName = "Engine", getter = () => data.materialDebugSettings.debugViewEngine, setter = value => SetDebugViewEngine(value), enumNames = MaterialDebugSettings.debugViewEngineStrings, enumValues = MaterialDebugSettings.debugViewEngineValues, getIndex = () => data.engineEnumIndex, setIndex = value => { data.ResetExclusiveEnumIndices(); data.engineEnumIndex = value; } });
|
|
list.Add(new DebugUI.EnumField { displayName = "Attributes", getter = () => (int)data.materialDebugSettings.debugViewVarying, setter = value => SetDebugViewVarying((DebugViewVarying)value), autoEnum = typeof(DebugViewVarying), getIndex = () => data.attributesEnumIndex, setIndex = value => { data.ResetExclusiveEnumIndices(); data.attributesEnumIndex = value; } });
|
|
list.Add(new DebugUI.EnumField { displayName = "Properties", getter = () => (int)data.materialDebugSettings.debugViewProperties, setter = value => SetDebugViewProperties((DebugViewProperties)value), autoEnum = typeof(DebugViewProperties), getIndex = () => data.propertiesEnumIndex, setIndex = value => { data.ResetExclusiveEnumIndices(); data.propertiesEnumIndex = value; } });
|
|
list.Add(new DebugUI.EnumField { displayName = "GBuffer", getter = () => data.materialDebugSettings.debugViewGBuffer, setter = value => SetDebugViewGBuffer(value), enumNames = MaterialDebugSettings.debugViewMaterialGBufferStrings, enumValues = MaterialDebugSettings.debugViewMaterialGBufferValues, getIndex = () => data.gBufferEnumIndex, setIndex = value => { data.ResetExclusiveEnumIndices(); data.gBufferEnumIndex = value; } });
|
|
list.Add(new DebugUI.EnumField { displayName = "Material Validator", getter = () => (int)data.fullScreenDebugMode, setter = value => SetFullScreenDebugMode((FullScreenDebugMode)value), enumNames = s_MaterialFullScreenDebugStrings, enumValues = s_MaterialFullScreenDebugValues, onValueChanged = RefreshMaterialDebug, getIndex = () => data.materialValidatorDebugModeEnumIndex, setIndex = value => { data.ResetExclusiveEnumIndices(); data.materialValidatorDebugModeEnumIndex = value; } });
|
|
|
|
if (data.fullScreenDebugMode == FullScreenDebugMode.ValidateDiffuseColor || data.fullScreenDebugMode == FullScreenDebugMode.ValidateSpecularColor)
|
|
{
|
|
list.Add(new DebugUI.Container
|
|
{
|
|
children =
|
|
{
|
|
new DebugUI.ColorField { displayName = "Too High Color", getter = () => data.materialDebugSettings.materialValidateHighColor, setter = value => data.materialDebugSettings.materialValidateHighColor = value, showAlpha = false, hdr = true },
|
|
new DebugUI.ColorField { displayName = "Too Low Color", getter = () => data.materialDebugSettings.materialValidateLowColor, setter = value => data.materialDebugSettings.materialValidateLowColor = value, showAlpha = false, hdr = true },
|
|
new DebugUI.ColorField { displayName = "Not A Pure Metal Color", getter = () => data.materialDebugSettings.materialValidateTrueMetalColor, setter = value => data.materialDebugSettings.materialValidateTrueMetalColor = value, showAlpha = false, hdr = true },
|
|
new DebugUI.BoolField { displayName = "Pure Metals", getter = () => data.materialDebugSettings.materialValidateTrueMetal, setter = (v) => data.materialDebugSettings.materialValidateTrueMetal = v },
|
|
}
|
|
});
|
|
}
|
|
|
|
m_DebugMaterialItems = list.ToArray();
|
|
var panel = DebugManager.instance.GetPanel(k_PanelMaterials, true);
|
|
panel.children.Add(m_DebugMaterialItems);
|
|
}
|
|
|
|
void RefreshDisplayStatsDebug<T>(DebugUI.Field<T> field, T value)
|
|
{
|
|
UnregisterDebugItems(k_PanelDisplayStats, m_DebugDisplayStatsItems);
|
|
RegisterDisplayStatsDebug();
|
|
}
|
|
|
|
// For now we just rebuild the lighting panel if needed, but ultimately it could be done in a better way
|
|
void RefreshLightingDebug<T>(DebugUI.Field<T> field, T value)
|
|
{
|
|
UnregisterDebugItems(k_PanelLighting, m_DebugLightingItems);
|
|
RegisterLightingDebug();
|
|
}
|
|
|
|
void RefreshDecalsDebug<T>(DebugUI.Field<T> field, T value)
|
|
{
|
|
UnregisterDebugItems(k_PanelDecals, m_DebugDecalsAffectingTransparentItems);
|
|
RegisterDecalsDebug();
|
|
}
|
|
|
|
void RefreshRenderingDebug<T>(DebugUI.Field<T> field, T value)
|
|
{
|
|
// Explicitly invoke the render debug unregister to handle render graph items.
|
|
UnregisterDebugItems(k_PanelRendering, m_DebugRenderingItems);
|
|
RegisterRenderingDebug();
|
|
}
|
|
|
|
void RefreshMaterialDebug<T>(DebugUI.Field<T> field, T value)
|
|
{
|
|
UnregisterDebugItems(k_PanelMaterials, m_DebugMaterialItems);
|
|
RegisterMaterialDebug();
|
|
}
|
|
|
|
void RefreshVolumeDebug<T>(DebugUI.Field<T> field, T value)
|
|
{
|
|
UnregisterDebugItems(k_PanelVolume, m_DebugVolumeItems);
|
|
RegisterVolumeDebug();
|
|
}
|
|
|
|
void RegisterLightingDebug()
|
|
{
|
|
var list = new List<DebugUI.Widget>();
|
|
|
|
{
|
|
var shadows = new DebugUI.Container() { displayName = "Shadows" };
|
|
|
|
shadows.children.Add(new DebugUI.EnumField { displayName = "Debug Mode", getter = () => (int)data.lightingDebugSettings.shadowDebugMode, setter = value => SetShadowDebugMode((ShadowMapDebugMode)value), autoEnum = typeof(ShadowMapDebugMode), onValueChanged = RefreshLightingDebug, getIndex = () => data.shadowDebugModeEnumIndex, setIndex = value => data.shadowDebugModeEnumIndex = value });
|
|
|
|
if (data.lightingDebugSettings.shadowDebugMode == ShadowMapDebugMode.VisualizeShadowMap || data.lightingDebugSettings.shadowDebugMode == ShadowMapDebugMode.SingleShadow)
|
|
{
|
|
var container = new DebugUI.Container();
|
|
container.children.Add(new DebugUI.BoolField { displayName = "Use Selection", getter = () => data.lightingDebugSettings.shadowDebugUseSelection, setter = value => data.lightingDebugSettings.shadowDebugUseSelection = value, flags = DebugUI.Flags.EditorOnly, onValueChanged = RefreshLightingDebug });
|
|
|
|
if (!data.lightingDebugSettings.shadowDebugUseSelection)
|
|
container.children.Add(new DebugUI.UIntField { displayName = "Shadow Map Index", getter = () => data.lightingDebugSettings.shadowMapIndex, setter = value => data.lightingDebugSettings.shadowMapIndex = value, min = () => 0u, max = () => (uint)(Math.Max(0, (RenderPipelineManager.currentPipeline as HDRenderPipeline).GetCurrentShadowCount() - 1u)) });
|
|
|
|
shadows.children.Add(container);
|
|
}
|
|
|
|
shadows.children.Add(new DebugUI.FloatField
|
|
{
|
|
displayName = "Global Scale Factor",
|
|
getter = () => data.lightingDebugSettings.shadowResolutionScaleFactor,
|
|
setter = (v) => data.lightingDebugSettings.shadowResolutionScaleFactor = v,
|
|
min = () => 0.01f,
|
|
max = () => 4.0f,
|
|
});
|
|
|
|
shadows.children.Add(new DebugUI.BoolField
|
|
{
|
|
displayName = "Clear Shadow Atlas",
|
|
getter = () => data.lightingDebugSettings.clearShadowAtlas,
|
|
setter = (v) => data.lightingDebugSettings.clearShadowAtlas = v
|
|
});
|
|
|
|
shadows.children.Add(new DebugUI.FloatField { displayName = "Range Minimum Value", getter = () => data.lightingDebugSettings.shadowMinValue, setter = value => data.lightingDebugSettings.shadowMinValue = value });
|
|
shadows.children.Add(new DebugUI.FloatField { displayName = "Range Maximum Value", getter = () => data.lightingDebugSettings.shadowMaxValue, setter = value => data.lightingDebugSettings.shadowMaxValue = value });
|
|
#if UNITY_EDITOR
|
|
shadows.children.Add(new DebugUI.Button { displayName = "Log Cached Shadow Atlas Status", action = () => HDCachedShadowManager.instance.PrintLightStatusInCachedAtlas() });
|
|
#endif
|
|
list.Add(shadows);
|
|
}
|
|
|
|
{
|
|
var lighting = new DebugUI.Container() { displayName = "Lighting" };
|
|
|
|
lighting.children.Add(new DebugUI.Foldout
|
|
{
|
|
displayName = "Show Lights By Type",
|
|
children =
|
|
{
|
|
new DebugUI.BoolField { displayName = "Directional Lights", getter = () => data.lightingDebugSettings.showDirectionalLight, setter = value => data.lightingDebugSettings.showDirectionalLight = value },
|
|
new DebugUI.BoolField { displayName = "Punctual Lights", getter = () => data.lightingDebugSettings.showPunctualLight, setter = value => data.lightingDebugSettings.showPunctualLight = value },
|
|
new DebugUI.BoolField { displayName = "Area Lights", getter = () => data.lightingDebugSettings.showAreaLight, setter = value => data.lightingDebugSettings.showAreaLight = value },
|
|
new DebugUI.BoolField { displayName = "Reflection Probes", getter = () => data.lightingDebugSettings.showReflectionProbe, setter = value => data.lightingDebugSettings.showReflectionProbe = value },
|
|
}
|
|
});
|
|
|
|
lighting.children.Add(new DebugUI.Foldout
|
|
{
|
|
displayName = "Probe Volumes",
|
|
children =
|
|
{
|
|
new DebugUI.EnumField { displayName = "Probe Volume Debug Mode", getter = () => (int)data.lightingDebugSettings.probeVolumeDebugMode, setter = value => SetProbeVolumeDebugMode((ProbeVolumeDebugMode)value), autoEnum = typeof(ProbeVolumeDebugMode), onValueChanged = RefreshLightingDebug, getIndex = () => data.probeVolumeDebugModeEnumIndex, setIndex = value => data.probeVolumeDebugModeEnumIndex = value },
|
|
new DebugUI.EnumField { displayName = "Probe Volume Atlas Slice Mode", getter = () => (int)data.lightingDebugSettings.probeVolumeAtlasSliceMode, setter = value => SetProbeVolumeAtlasSliceMode((ProbeVolumeAtlasSliceMode)value), autoEnum = typeof(ProbeVolumeAtlasSliceMode), onValueChanged = RefreshLightingDebug, getIndex = () => data.probeVolumeAtlasSliceModeEnumIndex, setIndex = value => data.probeVolumeAtlasSliceModeEnumIndex = value },
|
|
new DebugUI.FloatField { displayName = "Probe Volume Range Min Value", getter = () => data.lightingDebugSettings.probeVolumeMinValue, setter = value => data.lightingDebugSettings.probeVolumeMinValue = value },
|
|
new DebugUI.FloatField { displayName = "Probe Volume Range Max Value", getter = () => data.lightingDebugSettings.probeVolumeMaxValue, setter = value => data.lightingDebugSettings.probeVolumeMaxValue = value },
|
|
}
|
|
});
|
|
|
|
var exposureFoldout = new DebugUI.Foldout
|
|
{
|
|
displayName = "Exposure ",
|
|
children =
|
|
{
|
|
new DebugUI.EnumField
|
|
{
|
|
displayName = "Debug Mode",
|
|
getter = () => (int)data.lightingDebugSettings.exposureDebugMode,
|
|
setter = value => SetExposureDebugMode((ExposureDebugMode)value),
|
|
autoEnum = typeof(ExposureDebugMode), onValueChanged = RefreshLightingDebug,
|
|
getIndex = () => data.exposureDebugModeEnumIndex,
|
|
setIndex = value => data.exposureDebugModeEnumIndex = value
|
|
}
|
|
}
|
|
};
|
|
|
|
if (data.lightingDebugSettings.exposureDebugMode == ExposureDebugMode.MeteringWeighted)
|
|
{
|
|
exposureFoldout.children.Add(
|
|
new DebugUI.BoolField()
|
|
{
|
|
displayName = "Display Mask Only",
|
|
getter = () => data.lightingDebugSettings.displayMaskOnly,
|
|
setter = value => data.lightingDebugSettings.displayMaskOnly = value
|
|
});
|
|
}
|
|
if (data.lightingDebugSettings.exposureDebugMode == ExposureDebugMode.HistogramView)
|
|
{
|
|
exposureFoldout.children.Add(
|
|
new DebugUI.BoolField()
|
|
{
|
|
displayName = "Show Tonemap curve",
|
|
getter = () => data.lightingDebugSettings.showTonemapCurveAlongHistogramView,
|
|
setter = value => data.lightingDebugSettings.showTonemapCurveAlongHistogramView = value
|
|
});
|
|
exposureFoldout.children.Add(
|
|
new DebugUI.BoolField()
|
|
{
|
|
displayName = "Center Around Exposure",
|
|
getter = () => data.lightingDebugSettings.centerHistogramAroundMiddleGrey,
|
|
setter = value => data.lightingDebugSettings.centerHistogramAroundMiddleGrey = value
|
|
});
|
|
}
|
|
if (data.lightingDebugSettings.exposureDebugMode == ExposureDebugMode.FinalImageHistogramView)
|
|
{
|
|
exposureFoldout.children.Add(
|
|
new DebugUI.BoolField()
|
|
{
|
|
displayName = "Display RGB Histogram",
|
|
getter = () => data.lightingDebugSettings.displayFinalImageHistogramAsRGB,
|
|
setter = value => data.lightingDebugSettings.displayFinalImageHistogramAsRGB = value
|
|
});
|
|
}
|
|
|
|
exposureFoldout.children.Add(
|
|
new DebugUI.FloatField
|
|
{
|
|
displayName = "Debug Exposure Compensation",
|
|
getter = () => data.lightingDebugSettings.debugExposure,
|
|
setter = value => data.lightingDebugSettings.debugExposure = value
|
|
});
|
|
|
|
lighting.children.Add(exposureFoldout);
|
|
|
|
lighting.children.Add(new DebugUI.EnumField { displayName = "Debug Mode", getter = () => (int)data.lightingDebugSettings.debugLightingMode, setter = value => SetDebugLightingMode((DebugLightingMode)value), autoEnum = typeof(DebugLightingMode), onValueChanged = RefreshLightingDebug, getIndex = () => data.lightingDebugModeEnumIndex, setIndex = value => { data.ResetExclusiveEnumIndices(); data.lightingDebugModeEnumIndex = value; } });
|
|
lighting.children.Add(new DebugUI.BitField { displayName = "Hierarchy Debug Mode", getter = () => data.lightingDebugSettings.debugLightFilterMode, setter = value => SetDebugLightFilterMode((DebugLightFilterMode)value), enumType = typeof(DebugLightFilterMode), onValueChanged = RefreshLightingDebug, });
|
|
|
|
lighting.children.Add(new DebugUI.BoolField { displayName = "Light Layers Visualization", getter = () => data.lightingDebugSettings.debugLightLayers, setter = value => SetDebugLightLayersMode(value), onValueChanged = RefreshLightingDebug });
|
|
|
|
if (data.lightingDebugSettings.debugLightLayers)
|
|
{
|
|
var container = new DebugUI.Container();
|
|
container.children.Add(new DebugUI.BoolField
|
|
{
|
|
displayName = "Use Selected Light",
|
|
getter = () => data.lightingDebugSettings.debugSelectionLightLayers,
|
|
setter = value => data.lightingDebugSettings.debugSelectionLightLayers = value,
|
|
flags = DebugUI.Flags.EditorOnly,
|
|
onValueChanged = RefreshLightingDebug
|
|
});
|
|
|
|
if (data.lightingDebugSettings.debugSelectionLightLayers)
|
|
{
|
|
container.children.Add(new DebugUI.BoolField
|
|
{
|
|
displayName = "Switch to Light's Shadow Layers",
|
|
getter = () => data.lightingDebugSettings.debugSelectionShadowLayers,
|
|
setter = value => data.lightingDebugSettings.debugSelectionShadowLayers = value,
|
|
flags = DebugUI.Flags.EditorOnly,
|
|
onValueChanged = RefreshLightingDebug
|
|
});
|
|
}
|
|
else
|
|
{
|
|
var field = new DebugUI.BitField
|
|
{
|
|
displayName = "Filter Layers",
|
|
getter = () => data.lightingDebugSettings.debugLightLayersFilterMask,
|
|
setter = value => data.lightingDebugSettings.debugLightLayersFilterMask = (DebugLightLayersMask)value,
|
|
enumType = typeof(DebugLightLayersMask)
|
|
};
|
|
|
|
var asset = (RenderPipelineManager.currentPipeline as HDRenderPipeline).asset;
|
|
for (int i = 0; i < 8; i++)
|
|
field.enumNames[i + 1].text = asset.renderingLayerMaskNames[i];
|
|
container.children.Add(field);
|
|
}
|
|
|
|
var layersColor = new DebugUI.Foldout() { displayName = "Layers Color", flags = DebugUI.Flags.EditorOnly };
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
int index = i;
|
|
var asset = (RenderPipelineManager.currentPipeline as HDRenderPipeline).asset;
|
|
layersColor.children.Add(new DebugUI.ColorField
|
|
{
|
|
displayName = asset.renderingLayerMaskNames[i],
|
|
flags = DebugUI.Flags.EditorOnly,
|
|
getter = () => data.lightingDebugSettings.debugRenderingLayersColors[index],
|
|
setter = value => data.lightingDebugSettings.debugRenderingLayersColors[index] = value
|
|
});
|
|
}
|
|
|
|
container.children.Add(layersColor);
|
|
lighting.children.Add(container);
|
|
}
|
|
list.Add(lighting);
|
|
}
|
|
|
|
{
|
|
var material = new DebugUI.Container() { displayName = "Material Overrides" };
|
|
|
|
material.children.Add(new DebugUI.BoolField { displayName = "Override Smoothness", getter = () => data.lightingDebugSettings.overrideSmoothness, setter = value => data.lightingDebugSettings.overrideSmoothness = value, onValueChanged = RefreshLightingDebug });
|
|
if (data.lightingDebugSettings.overrideSmoothness)
|
|
{
|
|
material.children.Add(new DebugUI.Container
|
|
{
|
|
children =
|
|
{
|
|
new DebugUI.FloatField { displayName = "Smoothness", getter = () => data.lightingDebugSettings.overrideSmoothnessValue, setter = value => data.lightingDebugSettings.overrideSmoothnessValue = value, min = () => 0f, max = () => 1f, incStep = 0.025f }
|
|
}
|
|
});
|
|
}
|
|
|
|
material.children.Add(new DebugUI.BoolField { displayName = "Override Albedo", getter = () => data.lightingDebugSettings.overrideAlbedo, setter = value => data.lightingDebugSettings.overrideAlbedo = value, onValueChanged = RefreshLightingDebug });
|
|
if (data.lightingDebugSettings.overrideAlbedo)
|
|
{
|
|
material.children.Add(new DebugUI.Container
|
|
{
|
|
children =
|
|
{
|
|
new DebugUI.ColorField { displayName = "Albedo", getter = () => data.lightingDebugSettings.overrideAlbedoValue, setter = value => data.lightingDebugSettings.overrideAlbedoValue = value, showAlpha = false, hdr = false }
|
|
}
|
|
});
|
|
}
|
|
|
|
material.children.Add(new DebugUI.BoolField { displayName = "Override Normal", getter = () => data.lightingDebugSettings.overrideNormal, setter = value => data.lightingDebugSettings.overrideNormal = value });
|
|
|
|
material.children.Add(new DebugUI.BoolField { displayName = "Override Specular Color", getter = () => data.lightingDebugSettings.overrideSpecularColor, setter = value => data.lightingDebugSettings.overrideSpecularColor = value, onValueChanged = RefreshLightingDebug });
|
|
if (data.lightingDebugSettings.overrideSpecularColor)
|
|
{
|
|
material.children.Add(new DebugUI.Container
|
|
{
|
|
children =
|
|
{
|
|
new DebugUI.ColorField { displayName = "Specular Color", getter = () => data.lightingDebugSettings.overrideSpecularColorValue, setter = value => data.lightingDebugSettings.overrideSpecularColorValue = value, showAlpha = false, hdr = false }
|
|
}
|
|
});
|
|
}
|
|
|
|
material.children.Add(new DebugUI.BoolField { displayName = "Override Ambient Occlusion", getter = () => data.lightingDebugSettings.overrideAmbientOcclusion, setter = value => data.lightingDebugSettings.overrideAmbientOcclusion = value, onValueChanged = RefreshLightingDebug });
|
|
if (data.lightingDebugSettings.overrideAmbientOcclusion)
|
|
{
|
|
material.children.Add(new DebugUI.Container
|
|
{
|
|
children =
|
|
{
|
|
new DebugUI.FloatField { displayName = "AmbientOcclusion", getter = () => data.lightingDebugSettings.overrideAmbientOcclusionValue, setter = value => data.lightingDebugSettings.overrideAmbientOcclusionValue = value, min = () => 0f, max = () => 1f, incStep = 0.025f }
|
|
}
|
|
});
|
|
}
|
|
|
|
material.children.Add(new DebugUI.BoolField { displayName = "Override Emissive Color", getter = () => data.lightingDebugSettings.overrideEmissiveColor, setter = value => data.lightingDebugSettings.overrideEmissiveColor = value, onValueChanged = RefreshLightingDebug });
|
|
if (data.lightingDebugSettings.overrideEmissiveColor)
|
|
{
|
|
material.children.Add(new DebugUI.Container
|
|
{
|
|
children =
|
|
{
|
|
new DebugUI.ColorField { displayName = "Emissive Color", getter = () => data.lightingDebugSettings.overrideEmissiveColorValue, setter = value => data.lightingDebugSettings.overrideEmissiveColorValue = value, showAlpha = false, hdr = true }
|
|
}
|
|
});
|
|
}
|
|
|
|
list.Add(material);
|
|
}
|
|
|
|
list.Add(new DebugUI.EnumField { displayName = "Fullscreen Debug Mode", getter = () => (int)data.fullScreenDebugMode, setter = value => SetFullScreenDebugMode((FullScreenDebugMode)value), enumNames = s_LightingFullScreenDebugStrings, enumValues = s_LightingFullScreenDebugValues, onValueChanged = RefreshLightingDebug, getIndex = () => data.lightingFulscreenDebugModeEnumIndex, setIndex = value => { data.ResetExclusiveEnumIndices(); data.lightingFulscreenDebugModeEnumIndex = value; } });
|
|
|
|
if (data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceShadows)
|
|
{
|
|
list.Add(new DebugUI.UIntField { displayName = "Screen Space Shadow Index", getter = () => data.screenSpaceShadowIndex, setter = value => data.screenSpaceShadowIndex = value, min = () => 0u, max = () => (uint)(RenderPipelineManager.currentPipeline as HDRenderPipeline).GetMaxScreenSpaceShadows() });
|
|
}
|
|
|
|
switch (data.fullScreenDebugMode)
|
|
{
|
|
case FullScreenDebugMode.PreRefractionColorPyramid:
|
|
case FullScreenDebugMode.FinalColorPyramid:
|
|
case FullScreenDebugMode.DepthPyramid:
|
|
{
|
|
list.Add(new DebugUI.Container
|
|
{
|
|
children =
|
|
{
|
|
new DebugUI.FloatField { displayName = "Debug Mip", getter = () => data.fullscreenDebugMip, setter = value => data.fullscreenDebugMip = value, min = () => 0f, max = () => 1f, incStep = 0.05f },
|
|
new DebugUI.BoolField { displayName = "Enable Depth Remap", getter = () => data.enableDebugDepthRemap, setter = value => data.enableDebugDepthRemap = value },
|
|
new DebugUI.FloatField { displayName = "Depth range min value", getter = () => data.fullScreenDebugDepthRemap.x, setter = value => data.fullScreenDebugDepthRemap.x = value, min = () => 0f, max = () => 1f, incStep = 0.05f },
|
|
new DebugUI.FloatField { displayName = "Depth range max value", getter = () => data.fullScreenDebugDepthRemap.y, setter = value => data.fullScreenDebugDepthRemap.y = value, min = () => 0f, max = () => 1f, incStep = 0.05f }
|
|
}
|
|
});
|
|
break;
|
|
}
|
|
case FullScreenDebugMode.ContactShadows:
|
|
list.Add(new DebugUI.Container
|
|
{
|
|
children =
|
|
{
|
|
new DebugUI.IntField
|
|
{
|
|
displayName = "Light Index",
|
|
getter = () =>
|
|
{
|
|
return data.fullScreenContactShadowLightIndex;
|
|
},
|
|
setter = value =>
|
|
{
|
|
data.fullScreenContactShadowLightIndex = value;
|
|
},
|
|
min = () => - 1, // -1 will display all contact shadow
|
|
max = () => LightDefinitions.s_LightListMaxPrunedEntries - 1
|
|
},
|
|
}
|
|
});
|
|
break;
|
|
default:
|
|
data.fullscreenDebugMip = 0;
|
|
break;
|
|
}
|
|
|
|
list.Add(new DebugUI.EnumField { displayName = "Tile/Cluster Debug", getter = () => (int)data.lightingDebugSettings.tileClusterDebug, setter = value => data.lightingDebugSettings.tileClusterDebug = (TileClusterDebug)value, autoEnum = typeof(TileClusterDebug), onValueChanged = RefreshLightingDebug, getIndex = () => data.tileClusterDebugEnumIndex, setIndex = value => data.tileClusterDebugEnumIndex = value });
|
|
if (data.lightingDebugSettings.tileClusterDebug != TileClusterDebug.None && data.lightingDebugSettings.tileClusterDebug != TileClusterDebug.MaterialFeatureVariants)
|
|
{
|
|
var clusterDebugContainer = new DebugUI.Container();
|
|
|
|
clusterDebugContainer.children.Add(new DebugUI.EnumField { displayName = "Tile/Cluster Debug By Category", getter = () => (int)data.lightingDebugSettings.tileClusterDebugByCategory, setter = value => data.lightingDebugSettings.tileClusterDebugByCategory = (TileClusterCategoryDebug)value, enumNames = s_TileAndClusterDebugStrings, enumValues = s_TileAndClusterDebugValues, getIndex = () => data.tileClusterDebugByCategoryEnumIndex, setIndex = value => data.tileClusterDebugByCategoryEnumIndex = value });
|
|
if (data.lightingDebugSettings.tileClusterDebug == TileClusterDebug.Cluster)
|
|
{
|
|
clusterDebugContainer.children.Add(new DebugUI.EnumField { displayName = "Cluster Debug Mode", getter = () => (int)data.lightingDebugSettings.clusterDebugMode, setter = value => data.lightingDebugSettings.clusterDebugMode = (ClusterDebugMode)value, autoEnum = typeof(ClusterDebugMode), onValueChanged = RefreshLightingDebug, getIndex = () => data.clusterDebugModeEnumIndex, setIndex = value => data.clusterDebugModeEnumIndex = value });
|
|
|
|
if (data.lightingDebugSettings.clusterDebugMode == ClusterDebugMode.VisualizeSlice)
|
|
clusterDebugContainer.children.Add(new DebugUI.FloatField { displayName = "Cluster Distance", getter = () => data.lightingDebugSettings.clusterDebugDistance, setter = value => data.lightingDebugSettings.clusterDebugDistance = value, min = () => 0f, max = () => 100.0f, incStep = 0.05f });
|
|
}
|
|
|
|
list.Add(clusterDebugContainer);
|
|
}
|
|
|
|
list.Add(new DebugUI.BoolField { displayName = "Display Sky Reflection", getter = () => data.lightingDebugSettings.displaySkyReflection, setter = value => data.lightingDebugSettings.displaySkyReflection = value, onValueChanged = RefreshLightingDebug });
|
|
if (data.lightingDebugSettings.displaySkyReflection)
|
|
{
|
|
list.Add(new DebugUI.Container
|
|
{
|
|
children =
|
|
{
|
|
new DebugUI.FloatField { displayName = "Sky Reflection Mipmap", getter = () => data.lightingDebugSettings.skyReflectionMipmap, setter = value => data.lightingDebugSettings.skyReflectionMipmap = value, min = () => 0f, max = () => 1f, incStep = 0.05f }
|
|
}
|
|
});
|
|
}
|
|
|
|
list.Add(new DebugUI.BoolField { displayName = "Display Light Volumes", getter = () => data.lightingDebugSettings.displayLightVolumes, setter = value => data.lightingDebugSettings.displayLightVolumes = value, onValueChanged = RefreshLightingDebug });
|
|
if (data.lightingDebugSettings.displayLightVolumes)
|
|
{
|
|
var container = new DebugUI.Container
|
|
{
|
|
children =
|
|
{
|
|
new DebugUI.EnumField { displayName = "Light Volume Debug Type", getter = () => (int)data.lightingDebugSettings.lightVolumeDebugByCategory, setter = value => data.lightingDebugSettings.lightVolumeDebugByCategory = (LightVolumeDebug)value, autoEnum = typeof(LightVolumeDebug), getIndex = () => data.lightVolumeDebugTypeEnumIndex, setIndex = value => data.lightVolumeDebugTypeEnumIndex = value, onValueChanged = RefreshLightingDebug }
|
|
}
|
|
};
|
|
if (data.lightingDebugSettings.lightVolumeDebugByCategory == LightVolumeDebug.Gradient)
|
|
{
|
|
container.children.Add(new DebugUI.UIntField { displayName = "Max Debug Light Count", getter = () => (uint)data.lightingDebugSettings.maxDebugLightCount, setter = value => data.lightingDebugSettings.maxDebugLightCount = value, min = () => 0, max = () => 24, incStep = 1 });
|
|
}
|
|
|
|
list.Add(container);
|
|
}
|
|
|
|
list.Add(new DebugUI.BoolField { displayName = "Display Cookie Atlas", getter = () => data.lightingDebugSettings.displayCookieAtlas, setter = value => data.lightingDebugSettings.displayCookieAtlas = value, onValueChanged = RefreshLightingDebug });
|
|
if (data.lightingDebugSettings.displayCookieAtlas)
|
|
{
|
|
list.Add(new DebugUI.Container
|
|
{
|
|
children =
|
|
{
|
|
new DebugUI.UIntField { displayName = "Mip Level", getter = () => data.lightingDebugSettings.cookieAtlasMipLevel, setter = value => data.lightingDebugSettings.cookieAtlasMipLevel = value, min = () => 0, max = () => (uint)(RenderPipelineManager.currentPipeline as HDRenderPipeline).GetCookieAtlasMipCount()},
|
|
new DebugUI.BoolField { displayName = "Clear Cookie Atlas", getter = () => data.lightingDebugSettings.clearCookieAtlas, setter = value => data.lightingDebugSettings.clearCookieAtlas = value}
|
|
}
|
|
});
|
|
}
|
|
|
|
list.Add(new DebugUI.BoolField { displayName = "Display Planar Reflection Atlas", getter = () => data.lightingDebugSettings.displayPlanarReflectionProbeAtlas, setter = value => data.lightingDebugSettings.displayPlanarReflectionProbeAtlas = value, onValueChanged = RefreshLightingDebug });
|
|
if (data.lightingDebugSettings.displayPlanarReflectionProbeAtlas)
|
|
{
|
|
list.Add(new DebugUI.Container
|
|
{
|
|
children =
|
|
{
|
|
new DebugUI.UIntField { displayName = "Mip Level", getter = () => data.lightingDebugSettings.planarReflectionProbeMipLevel, setter = value => data.lightingDebugSettings.planarReflectionProbeMipLevel = value, min = () => 0, max = () => (uint)(RenderPipelineManager.currentPipeline as HDRenderPipeline).GetPlanarReflectionProbeMipCount()},
|
|
new DebugUI.BoolField { displayName = "Clear Planar Atlas", getter = () => data.lightingDebugSettings.clearPlanarReflectionProbeAtlas, setter = value => data.lightingDebugSettings.clearPlanarReflectionProbeAtlas = value},
|
|
}
|
|
});
|
|
}
|
|
|
|
list.Add(new DebugUI.FloatField { displayName = "Debug Overlay Screen Ratio", getter = () => data.debugOverlayRatio, setter = v => data.debugOverlayRatio = v, min = () => 0.1f, max = () => 1f });
|
|
|
|
m_DebugLightingItems = list.ToArray();
|
|
var panel = DebugManager.instance.GetPanel(k_PanelLighting, true);
|
|
panel.children.Add(m_DebugLightingItems);
|
|
}
|
|
|
|
void RegisterVolumeDebug()
|
|
{
|
|
var list = new List<DebugUI.Widget>();
|
|
|
|
int componentIndex = 0;
|
|
var componentNames = new List<GUIContent>() { new GUIContent("None") };
|
|
var componentValues = new List<int>() { componentIndex++ };
|
|
|
|
foreach (var type in VolumeDebugSettings.componentTypes)
|
|
{
|
|
componentNames.Add(new GUIContent() { text = VolumeDebugSettings.ComponentDisplayName(type) });
|
|
componentValues.Add(componentIndex++);
|
|
}
|
|
|
|
list.Add(new DebugUI.EnumField
|
|
{
|
|
displayName = "Component",
|
|
getter = () => data.volumeDebugSettings.selectedComponent,
|
|
setter = value => data.volumeDebugSettings.selectedComponent = value,
|
|
enumNames = componentNames.ToArray(),
|
|
enumValues = componentValues.ToArray(),
|
|
getIndex = () => data.volumeComponentEnumIndex,
|
|
setIndex = value => { data.volumeComponentEnumIndex = value; },
|
|
onValueChanged = RefreshVolumeDebug,
|
|
});
|
|
|
|
if (data.volumeDebugSettings.selectedComponent != 0)
|
|
{
|
|
componentIndex = 0;
|
|
componentNames = new List<GUIContent>() { new GUIContent("None") };
|
|
componentValues = new List<int>() { componentIndex++ };
|
|
|
|
#if UNITY_EDITOR
|
|
componentNames.Add(new GUIContent() { text = "Editor Camera" });
|
|
componentValues.Add(componentIndex++);
|
|
#endif
|
|
|
|
foreach (var camera in VolumeDebugSettings.cameras)
|
|
{
|
|
componentNames.Add(new GUIContent() { text = camera.name });
|
|
componentValues.Add(componentIndex++);
|
|
}
|
|
|
|
list.Add(new DebugUI.EnumField
|
|
{
|
|
displayName = "Camera",
|
|
getter = () => data.volumeDebugSettings.selectedCameraIndex,
|
|
setter = value => data.volumeDebugSettings.selectedCameraIndex = value,
|
|
enumNames = componentNames.ToArray(),
|
|
enumValues = componentValues.ToArray(),
|
|
getIndex = () => data.volumeCameraEnumIndex,
|
|
setIndex = value => { data.volumeCameraEnumIndex = value; },
|
|
onValueChanged = RefreshVolumeDebug,
|
|
});
|
|
|
|
if (data.volumeDebugSettings.selectedCameraIndex != 0)
|
|
{
|
|
DebugUI.Widget makeWidget(string name, VolumeParameter param)
|
|
{
|
|
if (param == null)
|
|
return new DebugUI.Value() { displayName = name, getter = () => "-" };
|
|
|
|
// Special overrides
|
|
if (param.GetType() == typeof(ColorParameter))
|
|
{
|
|
var p = (ColorParameter)param;
|
|
return new DebugUI.ColorField()
|
|
{
|
|
displayName = name,
|
|
hdr = p.hdr,
|
|
showAlpha = p.showAlpha,
|
|
getter = () => p.value,
|
|
setter = _ => {}
|
|
};
|
|
}
|
|
|
|
if (param.GetType() == typeof(BoolParameter))
|
|
{
|
|
var p = (BoolParameter)param;
|
|
return new DebugUI.BoolField()
|
|
{
|
|
displayName = name,
|
|
getter = () => p.value,
|
|
setter = _ => {}
|
|
};
|
|
}
|
|
|
|
// For parameters that do not override `ToString`
|
|
var property = param.GetType().GetProperty("value");
|
|
var toString = property.PropertyType.GetMethod("ToString", Type.EmptyTypes);
|
|
if ((toString == null) || (toString.DeclaringType == typeof(object)) || (toString.DeclaringType == typeof(UnityEngine.Object)))
|
|
{
|
|
// Check if the parameter has a name
|
|
var nameProp = property.PropertyType.GetProperty("name");
|
|
if (nameProp == null)
|
|
return new DebugUI.Value() { displayName = name, getter = () => "Debug view not supported" };
|
|
|
|
// Return the parameter name
|
|
return new DebugUI.Value()
|
|
{
|
|
displayName = name,
|
|
getter = () =>
|
|
{
|
|
var value = property.GetValue(param);
|
|
if (value == null || value.Equals(null))
|
|
return "None";
|
|
var valueString = nameProp.GetValue(value);
|
|
return valueString == null ? "None" : valueString;
|
|
}
|
|
};
|
|
}
|
|
|
|
// Call the ToString method
|
|
return new DebugUI.Value()
|
|
{
|
|
displayName = name,
|
|
getter = () =>
|
|
{
|
|
var value = property.GetValue(param);
|
|
return value == null ? "None" : value.ToString();
|
|
}
|
|
};
|
|
}
|
|
|
|
Type selectedType = data.volumeDebugSettings.selectedComponentType;
|
|
var stackComponent = data.volumeDebugSettings.selectedCameraVolumeStack.GetComponent(selectedType);
|
|
|
|
var volumes = data.volumeDebugSettings.GetVolumes();
|
|
var table = new DebugUI.Table() { displayName = "Parameter", isReadOnly = true };
|
|
|
|
var inst = (VolumeComponent)ScriptableObject.CreateInstance(selectedType);
|
|
|
|
// First row for volume info
|
|
float timer = 0.0f, refreshRate = 0.2f;
|
|
var row = new DebugUI.Table.Row()
|
|
{
|
|
displayName = "Volume Info",
|
|
children = { new DebugUI.Value() {
|
|
displayName = "Interpolated Value",
|
|
getter = () => {
|
|
// This getter is called first at each render
|
|
// It is used to update the volumes
|
|
if (Time.time - timer < refreshRate)
|
|
return "";
|
|
timer = Time.deltaTime;
|
|
if (data.volumeDebugSettings.selectedCameraIndex != 0)
|
|
{
|
|
var newVolumes = data.volumeDebugSettings.GetVolumes();
|
|
if (!data.volumeDebugSettings.RefreshVolumes(newVolumes))
|
|
{
|
|
for (int i = 0; i < newVolumes.Length; i++)
|
|
{
|
|
var visible = data.volumeDebugSettings.VolumeHasInfluence(newVolumes[i]);
|
|
table.SetColumnVisibility(i + 1, visible);
|
|
}
|
|
return "";
|
|
}
|
|
}
|
|
RefreshVolumeDebug(null, false);
|
|
return "";
|
|
}
|
|
} }
|
|
};
|
|
row.opened = true;
|
|
|
|
foreach (var volume in volumes)
|
|
{
|
|
var profile = volume.HasInstantiatedProfile() ? volume.profile : volume.sharedProfile;
|
|
row.children.Add(new DebugUI.Value()
|
|
{
|
|
displayName = volume.name + " (" + profile.name + ")",
|
|
getter = () =>
|
|
{
|
|
var scope = volume.isGlobal ? "Global" : "Local";
|
|
var weight = data.volumeDebugSettings.GetVolumeWeight(volume);
|
|
return scope + " (" + (weight * 100f) + "%)";
|
|
}
|
|
});
|
|
}
|
|
|
|
row.children.Add(new DebugUI.Value() { displayName = "Default Value", getter = () => "" });
|
|
table.children.Add(row);
|
|
|
|
// Build rows - recursively handles nested parameters
|
|
var rows = new List<DebugUI.Table.Row>();
|
|
void AddParameterRows(Type type, string baseName = null)
|
|
{
|
|
void AddRow(FieldInfo f, string prefix)
|
|
{
|
|
var fieldName = prefix + f.Name;
|
|
var attr = (DisplayInfoAttribute[])f.GetCustomAttributes(typeof(DisplayInfoAttribute), true);
|
|
if (attr.Length != 0)
|
|
fieldName = prefix + attr[0].name;
|
|
#if UNITY_EDITOR
|
|
// Would be nice to have the equivalent for the runtime debug.
|
|
else
|
|
fieldName = UnityEditor.ObjectNames.NicifyVariableName(fieldName);
|
|
#endif
|
|
|
|
int currentParam = rows.Count;
|
|
row = new DebugUI.Table.Row()
|
|
{
|
|
displayName = fieldName,
|
|
children = { makeWidget("Interpolated Value", stackComponent.parameters[currentParam]) }
|
|
};
|
|
|
|
foreach (var volume in volumes)
|
|
{
|
|
VolumeParameter param = null;
|
|
var profile = volume.HasInstantiatedProfile() ? volume.profile : volume.sharedProfile;
|
|
if (profile.TryGet(selectedType, out VolumeComponent component) && component.parameters[currentParam].overrideState)
|
|
param = component.parameters[currentParam];
|
|
row.children.Add(makeWidget(volume.name + " (" + profile.name + ")", param));
|
|
}
|
|
|
|
row.children.Add(makeWidget("Default Value", inst.parameters[currentParam]));
|
|
rows.Add(row);
|
|
}
|
|
|
|
var fields = type
|
|
.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
|
|
.OrderBy(t => t.MetadataToken);
|
|
foreach (var field in fields)
|
|
{
|
|
var fieldType = field.FieldType;
|
|
if (fieldType.IsSubclassOf(typeof(VolumeParameter)))
|
|
AddRow(field, baseName ?? "");
|
|
else if (!fieldType.IsArray && fieldType.IsClass)
|
|
AddParameterRows(fieldType, baseName ?? (field.Name + " "));
|
|
}
|
|
}
|
|
|
|
AddParameterRows(selectedType);
|
|
foreach (var r in rows.OrderBy(t => t.displayName))
|
|
table.children.Add(r);
|
|
|
|
data.volumeDebugSettings.RefreshVolumes(volumes);
|
|
for (int i = 0; i < volumes.Length; i++)
|
|
table.SetColumnVisibility(i + 1, data.volumeDebugSettings.VolumeHasInfluence(volumes[i]));
|
|
list.Add(table);
|
|
}
|
|
}
|
|
|
|
m_DebugVolumeItems = list.ToArray();
|
|
var panel = DebugManager.instance.GetPanel(k_PanelVolume, true);
|
|
panel.children.Add(m_DebugVolumeItems);
|
|
}
|
|
|
|
void RegisterRenderingDebug()
|
|
{
|
|
var widgetList = new List<DebugUI.Widget>();
|
|
|
|
widgetList.Add(
|
|
new DebugUI.EnumField { displayName = "Fullscreen Debug Mode", getter = () => (int)data.fullScreenDebugMode, setter = value => SetFullScreenDebugMode((FullScreenDebugMode)value), onValueChanged = RefreshRenderingDebug, enumNames = s_RenderingFullScreenDebugStrings, enumValues = s_RenderingFullScreenDebugValues, getIndex = () => data.renderingFulscreenDebugModeEnumIndex, setIndex = value => { data.ResetExclusiveEnumIndices(); data.renderingFulscreenDebugModeEnumIndex = value; } }
|
|
);
|
|
|
|
if (data.fullScreenDebugMode == FullScreenDebugMode.TransparencyOverdraw)
|
|
{
|
|
widgetList.Add(new DebugUI.Container
|
|
{
|
|
children =
|
|
{
|
|
new DebugUI.FloatField {displayName = "Max Pixel Cost", getter = () => data.transparencyDebugSettings.maxPixelCost, setter = value => data.transparencyDebugSettings.maxPixelCost = value, min = () => 0.25f, max = () => 2048.0f}
|
|
}
|
|
});
|
|
}
|
|
else if (data.fullScreenDebugMode == FullScreenDebugMode.QuadOverdraw)
|
|
{
|
|
widgetList.Add(new DebugUI.Container
|
|
{
|
|
children =
|
|
{
|
|
new DebugUI.UIntField {displayName = "Max Quad Cost", getter = () => data.maxQuadCost, setter = value => data.maxQuadCost = value, min = () => 1, max = () => 10}
|
|
}
|
|
});
|
|
}
|
|
else if (data.fullScreenDebugMode == FullScreenDebugMode.VertexDensity)
|
|
{
|
|
widgetList.Add(new DebugUI.Container
|
|
{
|
|
children =
|
|
{
|
|
new DebugUI.UIntField {displayName = "Max Vertex Density", getter = () => data.maxVertexDensity, setter = value => data.maxVertexDensity = value, min = () => 1, max = () => 100}
|
|
}
|
|
});
|
|
}
|
|
|
|
widgetList.AddRange(new DebugUI.Widget[]
|
|
{
|
|
new DebugUI.EnumField { displayName = "MipMaps", getter = () => (int)data.mipMapDebugSettings.debugMipMapMode, setter = value => SetMipMapMode((DebugMipMapMode)value), autoEnum = typeof(DebugMipMapMode), onValueChanged = RefreshRenderingDebug, getIndex = () => data.mipMapsEnumIndex, setIndex = value => { data.ResetExclusiveEnumIndices(); data.mipMapsEnumIndex = value; } },
|
|
});
|
|
|
|
if (data.mipMapDebugSettings.debugMipMapMode != DebugMipMapMode.None)
|
|
{
|
|
widgetList.Add(new DebugUI.Container
|
|
{
|
|
children =
|
|
{
|
|
new DebugUI.EnumField { displayName = "Terrain Texture", getter = () => (int)data.mipMapDebugSettings.terrainTexture, setter = value => data.mipMapDebugSettings.terrainTexture = (DebugMipMapModeTerrainTexture)value, autoEnum = typeof(DebugMipMapModeTerrainTexture), getIndex = () => data.terrainTextureEnumIndex, setIndex = value => data.terrainTextureEnumIndex = value }
|
|
}
|
|
});
|
|
}
|
|
|
|
widgetList.AddRange(new[]
|
|
{
|
|
new DebugUI.Container
|
|
{
|
|
displayName = "Color Picker",
|
|
flags = DebugUI.Flags.EditorOnly,
|
|
children =
|
|
{
|
|
new DebugUI.EnumField { displayName = "Debug Mode", getter = () => (int)data.colorPickerDebugSettings.colorPickerMode, setter = value => data.colorPickerDebugSettings.colorPickerMode = (ColorPickerDebugMode)value, autoEnum = typeof(ColorPickerDebugMode), getIndex = () => data.colorPickerDebugModeEnumIndex, setIndex = value => data.colorPickerDebugModeEnumIndex = value },
|
|
new DebugUI.ColorField { displayName = "Font Color", flags = DebugUI.Flags.EditorOnly, getter = () => data.colorPickerDebugSettings.fontColor, setter = value => data.colorPickerDebugSettings.fontColor = value }
|
|
}
|
|
}
|
|
});
|
|
|
|
widgetList.Add(new DebugUI.BoolField { displayName = "False Color Mode", getter = () => data.falseColorDebugSettings.falseColor, setter = value => data.falseColorDebugSettings.falseColor = value, onValueChanged = RefreshRenderingDebug });
|
|
if (data.falseColorDebugSettings.falseColor)
|
|
{
|
|
widgetList.Add(new DebugUI.Container
|
|
{
|
|
flags = DebugUI.Flags.EditorOnly,
|
|
children =
|
|
{
|
|
new DebugUI.FloatField { displayName = "Range Threshold 0", getter = () => data.falseColorDebugSettings.colorThreshold0, setter = value => data.falseColorDebugSettings.colorThreshold0 = Mathf.Min(value, data.falseColorDebugSettings.colorThreshold1) },
|
|
new DebugUI.FloatField { displayName = "Range Threshold 1", getter = () => data.falseColorDebugSettings.colorThreshold1, setter = value => data.falseColorDebugSettings.colorThreshold1 = Mathf.Clamp(value, data.falseColorDebugSettings.colorThreshold0, data.falseColorDebugSettings.colorThreshold2) },
|
|
new DebugUI.FloatField { displayName = "Range Threshold 2", getter = () => data.falseColorDebugSettings.colorThreshold2, setter = value => data.falseColorDebugSettings.colorThreshold2 = Mathf.Clamp(value, data.falseColorDebugSettings.colorThreshold1, data.falseColorDebugSettings.colorThreshold3) },
|
|
new DebugUI.FloatField { displayName = "Range Threshold 3", getter = () => data.falseColorDebugSettings.colorThreshold3, setter = value => data.falseColorDebugSettings.colorThreshold3 = Mathf.Max(value, data.falseColorDebugSettings.colorThreshold2) },
|
|
}
|
|
});
|
|
}
|
|
|
|
if (HDRenderPipeline.currentAsset?.currentPlatformRenderPipelineSettings.supportMSAA ?? true)
|
|
{
|
|
widgetList.AddRange(new DebugUI.Widget[]
|
|
{
|
|
new DebugUI.EnumField { displayName = "MSAA Samples", getter = () => (int)data.msaaSamples, setter = value => data.msaaSamples = (MSAASamples)value, enumNames = s_MsaaSamplesDebugStrings, enumValues = s_MsaaSamplesDebugValues, getIndex = () => data.msaaSampleDebugModeEnumIndex, setIndex = value => data.msaaSampleDebugModeEnumIndex = value },
|
|
});
|
|
}
|
|
|
|
widgetList.AddRange(new DebugUI.Widget[]
|
|
{
|
|
new DebugUI.EnumField { displayName = "Freeze Camera for culling", getter = () => data.debugCameraToFreeze, setter = value => data.debugCameraToFreeze = value, enumNames = s_CameraNamesStrings, enumValues = s_CameraNamesValues, getIndex = () => data.debugCameraToFreezeEnumIndex, setIndex = value => data.debugCameraToFreezeEnumIndex = value },
|
|
});
|
|
|
|
if (XRGraphicsAutomatedTests.enabled)
|
|
{
|
|
widgetList.Add(new DebugUI.BoolField { displayName = "XR single-pass test mode", getter = () => data.xrSinglePassTestMode, setter = value => data.xrSinglePassTestMode = value });
|
|
}
|
|
|
|
m_DebugRenderingItems = widgetList.ToArray();
|
|
var panel = DebugManager.instance.GetPanel(k_PanelRendering, true);
|
|
panel.children.Add(m_DebugRenderingItems);
|
|
}
|
|
|
|
void RegisterDecalsDebug()
|
|
{
|
|
var decalAffectingTransparent = new DebugUI.Container()
|
|
{
|
|
displayName = "Decals Affecting Transparent Objects",
|
|
children =
|
|
{
|
|
new DebugUI.BoolField { displayName = "Display Atlas", getter = () => data.decalsDebugSettings.displayAtlas, setter = value => data.decalsDebugSettings.displayAtlas = value},
|
|
new DebugUI.UIntField { displayName = "Mip Level", getter = () => data.decalsDebugSettings.mipLevel, setter = value => data.decalsDebugSettings.mipLevel = value, min = () => 0u, max = () => (uint)(RenderPipelineManager.currentPipeline as HDRenderPipeline)?.GetDecalAtlasMipCount() }
|
|
}
|
|
};
|
|
|
|
m_DebugDecalsAffectingTransparentItems = new DebugUI.Widget[] { decalAffectingTransparent };
|
|
var panel = DebugManager.instance.GetPanel(k_PanelDecals, true);
|
|
panel.children.Add(m_DebugDecalsAffectingTransparentItems);
|
|
}
|
|
|
|
internal void RegisterDebug()
|
|
{
|
|
RegisterDecalsDebug();
|
|
RegisterDisplayStatsDebug();
|
|
RegisterMaterialDebug();
|
|
RegisterLightingDebug();
|
|
RegisterVolumeDebug();
|
|
RegisterRenderingDebug();
|
|
DebugManager.instance.RegisterData(this);
|
|
}
|
|
|
|
internal void UnregisterDebug()
|
|
{
|
|
UnregisterDebugItems(k_PanelDecals, m_DebugDecalsAffectingTransparentItems);
|
|
|
|
DisableProfilingRecorders();
|
|
if (HDRenderPipeline.currentAsset?.currentPlatformRenderPipelineSettings.supportRayTracing ?? true)
|
|
DisableProfilingRecordersRT();
|
|
UnregisterDebugItems(k_PanelDisplayStats, m_DebugDisplayStatsItems);
|
|
|
|
UnregisterDebugItems(k_PanelMaterials, m_DebugMaterialItems);
|
|
UnregisterDebugItems(k_PanelLighting, m_DebugLightingItems);
|
|
UnregisterDebugItems(k_PanelVolume, m_DebugVolumeItems);
|
|
UnregisterDebugItems(k_PanelRendering, m_DebugRenderingItems);
|
|
DebugManager.instance.UnregisterData(this);
|
|
}
|
|
|
|
void UnregisterDebugItems(string panelName, DebugUI.Widget[] items)
|
|
{
|
|
var panel = DebugManager.instance.GetPanel(panelName);
|
|
if (panel != null)
|
|
panel.children.Remove(items);
|
|
}
|
|
|
|
void FillFullScreenDebugEnum(ref GUIContent[] strings, ref int[] values, FullScreenDebugMode min, FullScreenDebugMode max)
|
|
{
|
|
int count = max - min - 1;
|
|
strings = new GUIContent[count + 1];
|
|
values = new int[count + 1];
|
|
strings[0] = new GUIContent(FullScreenDebugMode.None.ToString());
|
|
values[0] = (int)FullScreenDebugMode.None;
|
|
int index = 1;
|
|
for (int i = (int)min + 1; i < (int)max; ++i)
|
|
{
|
|
strings[index] = new GUIContent(((FullScreenDebugMode)i).ToString());
|
|
values[index] = i;
|
|
index++;
|
|
}
|
|
}
|
|
|
|
void FillTileClusterDebugEnum()
|
|
{
|
|
string[] names = Enum.GetNames(typeof(TileClusterCategoryDebug));
|
|
for (int i = 0; i < names.Length; ++i)
|
|
{
|
|
var n = names[i];
|
|
names[i] = n.Replace("Environment", "ReflectionProbes");
|
|
}
|
|
|
|
s_TileAndClusterDebugStrings = names
|
|
.Select(t => new GUIContent(t))
|
|
.ToArray();
|
|
s_TileAndClusterDebugValues = (int[])Enum.GetValues(typeof(TileClusterCategoryDebug));
|
|
}
|
|
|
|
static string FormatVector(Vector3 v)
|
|
{
|
|
return string.Format("({0:F6}, {1:F6}, {2:F6})", v.x, v.y, v.z);
|
|
}
|
|
|
|
internal static void RegisterCamera(IFrameSettingsHistoryContainer container)
|
|
{
|
|
string name = container.panelName;
|
|
if (s_CameraNames.FindIndex(x => x.text.Equals(name)) < 0)
|
|
{
|
|
s_CameraNames.Add(new GUIContent(name));
|
|
needsRefreshingCameraFreezeList = true;
|
|
}
|
|
|
|
if (!FrameSettingsHistory.IsRegistered(container))
|
|
{
|
|
var history = FrameSettingsHistory.RegisterDebug(container);
|
|
DebugManager.instance.RegisterData(history);
|
|
}
|
|
}
|
|
|
|
internal static void UnRegisterCamera(IFrameSettingsHistoryContainer container)
|
|
{
|
|
string name = container.panelName;
|
|
int indexOfCamera = s_CameraNames.FindIndex(x => x.text.Equals(name));
|
|
if (indexOfCamera > 0)
|
|
{
|
|
s_CameraNames.RemoveAt(indexOfCamera);
|
|
needsRefreshingCameraFreezeList = true;
|
|
}
|
|
|
|
if (FrameSettingsHistory.IsRegistered(container))
|
|
{
|
|
DebugManager.instance.UnregisterData(container);
|
|
FrameSettingsHistory.UnRegisterDebug(container);
|
|
}
|
|
}
|
|
|
|
internal bool IsDebugDisplayRemovePostprocess()
|
|
{
|
|
return data.materialDebugSettings.IsDebugDisplayEnabled() || data.lightingDebugSettings.IsDebugDisplayRemovePostprocess() || data.mipMapDebugSettings.IsDebugDisplayEnabled();
|
|
}
|
|
|
|
internal void UpdateMaterials()
|
|
{
|
|
if (data.mipMapDebugSettings.debugMipMapMode != 0)
|
|
Texture.SetStreamingTextureMaterialDebugProperties();
|
|
}
|
|
|
|
internal void UpdateCameraFreezeOptions()
|
|
{
|
|
if (needsRefreshingCameraFreezeList)
|
|
{
|
|
s_CameraNames.Insert(0, new GUIContent("None"));
|
|
|
|
s_CameraNamesStrings = s_CameraNames.ToArray();
|
|
s_CameraNamesValues = Enumerable.Range(0, s_CameraNames.Count()).ToArray();
|
|
|
|
UnregisterDebugItems(k_PanelRendering, m_DebugRenderingItems);
|
|
RegisterRenderingDebug();
|
|
needsRefreshingCameraFreezeList = false;
|
|
}
|
|
}
|
|
|
|
internal bool DebugHideSky(HDCamera hdCamera)
|
|
{
|
|
return (IsMatcapViewEnabled(hdCamera) ||
|
|
GetDebugLightingMode() == DebugLightingMode.DiffuseLighting ||
|
|
GetDebugLightingMode() == DebugLightingMode.SpecularLighting ||
|
|
GetDebugLightingMode() == DebugLightingMode.DirectDiffuseLighting ||
|
|
GetDebugLightingMode() == DebugLightingMode.DirectSpecularLighting ||
|
|
GetDebugLightingMode() == DebugLightingMode.IndirectDiffuseLighting ||
|
|
GetDebugLightingMode() == DebugLightingMode.ReflectionLighting ||
|
|
GetDebugLightingMode() == DebugLightingMode.RefractionLighting
|
|
);
|
|
}
|
|
|
|
internal bool DebugNeedsExposure()
|
|
{
|
|
DebugLightingMode debugLighting = data.lightingDebugSettings.debugLightingMode;
|
|
DebugViewGbuffer debugGBuffer = (DebugViewGbuffer)data.materialDebugSettings.debugViewGBuffer;
|
|
return (debugLighting == DebugLightingMode.DirectDiffuseLighting || debugLighting == DebugLightingMode.DirectSpecularLighting || debugLighting == DebugLightingMode.IndirectDiffuseLighting || debugLighting == DebugLightingMode.ReflectionLighting || debugLighting == DebugLightingMode.RefractionLighting || debugLighting == DebugLightingMode.EmissiveLighting ||
|
|
debugLighting == DebugLightingMode.DiffuseLighting || debugLighting == DebugLightingMode.SpecularLighting || debugLighting == DebugLightingMode.VisualizeCascade) ||
|
|
(data.lightingDebugSettings.overrideAlbedo || data.lightingDebugSettings.overrideNormal || data.lightingDebugSettings.overrideSmoothness || data.lightingDebugSettings.overrideSpecularColor || data.lightingDebugSettings.overrideEmissiveColor || data.lightingDebugSettings.overrideAmbientOcclusion) ||
|
|
(debugGBuffer == DebugViewGbuffer.BakeDiffuseLightingWithAlbedoPlusEmissive) || (data.lightingDebugSettings.debugLightFilterMode != DebugLightFilterMode.None) ||
|
|
(data.fullScreenDebugMode == FullScreenDebugMode.PreRefractionColorPyramid || data.fullScreenDebugMode == FullScreenDebugMode.FinalColorPyramid || data.fullScreenDebugMode == FullScreenDebugMode.TransparentScreenSpaceReflections || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflections || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflectionsPrev || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceReflectionsAccum || data.fullScreenDebugMode == FullScreenDebugMode.LightCluster || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceShadows || data.fullScreenDebugMode == FullScreenDebugMode.NanTracker || data.fullScreenDebugMode == FullScreenDebugMode.ColorLog) || data.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceGlobalIllumination;
|
|
}
|
|
}
|
|
}
|