r.Nanite.ShowStats
r.Nanite.ShowStats
#Overview
name: r.Nanite.ShowStats
This variable is created as a Console Variable (cvar).
- type:
Var
- help: ``
It is referenced in 21
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of r.Nanite.ShowStats is to control the display of statistics for Unreal Engine 5’s Nanite virtualized geometry system. This setting variable is primarily used for debugging and performance analysis of the Nanite rendering system.
The Nanite subsystem within the Unreal Engine 5 renderer relies on this setting variable. It is referenced in various parts of the rendering code, particularly in the Nanite-specific files and the deferred shading renderer.
The value of this variable is set through the console variable system, as seen in the FAutoConsoleVariableRef
declaration. It can be changed at runtime using console commands.
This variable interacts closely with GNaniteShowStats
, which is the actual integer variable that stores the state. They share the same value, with r.Nanite.ShowStats
being the console-accessible name and GNaniteShowStats
being the C++ variable used in the code.
Developers should be aware that enabling this variable may have performance implications, as it involves additional computation and memory usage to gather and display statistics. It should primarily be used for debugging and performance analysis, not in shipping builds.
Best practices when using this variable include:
- Only enable it when needed for debugging or performance analysis.
- Be aware of the potential performance impact when enabled.
- Use in conjunction with other Nanite debugging tools and variables for a comprehensive view of the system’s performance.
Regarding the associated variable GNaniteShowStats
:
The purpose of GNaniteShowStats
is to serve as the internal C++ representation of the r.Nanite.ShowStats
console variable. It is used throughout the Nanite rendering code to determine whether statistics should be gathered and displayed.
This variable is used in various Nanite-related systems, including the main Nanite rendering, culling, rasterization, and shadow rendering code.
The value of GNaniteShowStats
is set by the console variable system when r.Nanite.ShowStats
is modified.
GNaniteShowStats
interacts with several other variables and systems within the Nanite rendering pipeline. It’s often used in conditional statements to determine whether certain statistics-related code should be executed.
Developers should be aware that this variable is used extensively throughout the Nanite rendering code, and changing its value will have wide-ranging effects on the statistics gathering and display systems.
Best practices for using GNaniteShowStats
include:
- Avoid modifying it directly in C++ code; instead, use the
r.Nanite.ShowStats
console variable to change its value. - When adding new Nanite-related features, consider whether they should respect this variable for statistics gathering.
- Be mindful of the performance implications when this variable is non-zero, especially in performance-critical code paths.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/Nanite.cpp:16
Scope: file
Source code excerpt:
int32 GNaniteShowStats = 0;
FAutoConsoleVariableRef CVarNaniteShowStats(
TEXT("r.Nanite.ShowStats"),
GNaniteShowStats,
TEXT("")
);
FString GNaniteStatsFilter;
FAutoConsoleVariableRef CVarNaniteStatsFilter(
#Associated Variable and Callsites
This variable is associated with another variable named GNaniteShowStats
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/DeferredShadingRenderer.cpp:106
Scope: file
Source code excerpt:
#endif
extern int32 GNaniteShowStats;
extern int32 GNanitePickingDomain;
extern DynamicRenderScaling::FBudget GDynamicNaniteScalingPrimary;
static TAutoConsoleVariable<int32> CVarClearCoatNormal(
TEXT("r.ClearCoatNormal"),
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/DeferredShadingRenderer.cpp:2440
Scope (from outer to inner):
file
function void FDeferredShadingSceneRenderer::Render
Source code excerpt:
if (bNaniteEnabled)
{
if (GNaniteShowStats != 0)
{
for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++)
{
const FViewInfo& View = Views[ViewIndex];
if (IStereoRendering::IsAPrimaryView(View))
{
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/Nanite.cpp:14
Scope: file
Source code excerpt:
#define NUM_PRINT_STATS_PASSES 5
int32 GNaniteShowStats = 0;
FAutoConsoleVariableRef CVarNaniteShowStats(
TEXT("r.Nanite.ShowStats"),
GNaniteShowStats,
TEXT("")
);
FString GNaniteStatsFilter;
FAutoConsoleVariableRef CVarNaniteStatsFilter(
TEXT("r.Nanite.StatsFilter"),
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/Nanite.cpp:42
Scope (from outer to inner):
file
function void NaniteStatsFilterExec
Source code excerpt:
// Convenience, force on Nanite debug/stats and also shader printing.
GNaniteShowStats = 1;
ShaderPrint::SetEnabled(true);
// parse parameters
for (;;)
{
FString Parameter = FParse::Token(Cmd, 0);
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/Nanite.cpp:70
Scope (from outer to inner):
file
function void NaniteStatsFilterExec
Source code excerpt:
{
// disable stats
GNaniteShowStats = 0;
return;
}
else
{
GNaniteStatsFilter = Parameter;
}
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/Nanite.cpp:285
Scope (from outer to inner):
file
namespace Nanite
function bool IsStatFilterActive
Source code excerpt:
bool IsStatFilterActive(const FString& FilterName)
{
if (GNaniteShowStats == 0)
{
// Stats are disabled, do nothing.
return false;
}
return (GNaniteStatsFilter == FilterName);
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/Nanite.cpp:296
Scope (from outer to inner):
file
namespace Nanite
function bool IsStatFilterActiveForLight
Source code excerpt:
bool IsStatFilterActiveForLight(const FLightSceneProxy* LightProxy)
{
if (GNaniteShowStats == 0)
{
return false;
}
const FString LightFilterName = Nanite::GetFilterNameForLight(LightProxy);
return IsStatFilterActive(LightFilterName);
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/Nanite.cpp:405
Scope (from outer to inner):
file
namespace Nanite
function void ExtractShadingDebug
Source code excerpt:
}
if (GNaniteShowStats != 0 && Nanite::GGlobalResources.GetStatsBufferRef())
{
const bool bShadeBinning = ShadeBinning.ShadingBinArgs != nullptr;
FCalculateShadingStatsCS::FParameters* PassParameters = GraphBuilder.AllocParameters<FCalculateShadingStatsCS::FParameters>();
PassParameters->RenderFlags = Nanite::GGlobalResources.StatsRenderFlags;
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/Nanite.cpp:450
Scope (from outer to inner):
file
namespace Nanite
function void PrintStats
Source code excerpt:
// Print stats
if (GNaniteShowStats != 0 && Nanite::GGlobalResources.GetStatsBufferRef())
{
auto& MainPassBuffers = Nanite::GGlobalResources.GetMainPassBuffers();
auto& PostPassBuffers = Nanite::GGlobalResources.GetPostPassBuffers();
// Shader compilers have a hard time handling the size of the full PrintStats shader, so we split it into multiple passes.
// This reduces the FXC compilation time from 2-3 minutes to just a few seconds.
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/NaniteCullRaster.cpp:317
Scope: file
Source code excerpt:
DynamicRenderScaling::FBudget GDynamicNaniteScalingShadow( TEXT("DynamicNaniteScalingShadow"), &GetDynamicNaniteScalingShadowSettings);
extern int32 GNaniteShowStats;
extern int32 GSkipDrawOnPSOPrecaching;
// Set to 1 to pretend all programmable raster draws are not precached yet
TAutoConsoleVariable<int32> CVarNaniteTestPrecacheDrawSkipping(
TEXT("r.Nanite.TestPrecacheDrawSkipping"),
0,
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/NaniteCullRaster.cpp:2924
Scope (from outer to inner):
file
namespace Nanite
function FRenderer::FRenderer
Source code excerpt:
RenderFlags |= Configuration.bEditorShowFlag ? NANITE_RENDER_FLAG_EDITOR_SHOW_FLAG_ENABLED : 0u;
#endif
RenderFlags |= GNaniteShowStats != 0 ? NANITE_RENDER_FLAG_WRITE_STATS : 0u;
if (UseMeshShader(ShaderPlatform, SharedContext.Pipeline))
{
RenderFlags |= NANITE_RENDER_FLAG_MESH_SHADER;
}
else if (UsePrimitiveShader())
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/NaniteCullRaster.cpp:4622
Scope (from outer to inner):
file
namespace Nanite
Source code excerpt:
PassParameters->VisiblePatchesSize = VisiblePatches->GetSize() / 16;
PassParameters->OutStatsBuffer = GNaniteShowStats != 0u ? GraphBuilder.CreateUAV(StatsBuffer) : nullptr;
if (VirtualShadowMapArray)
{
PassParameters->VirtualShadowMap = VirtualTargetParameters;
}
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/NaniteCullRaster.cpp:4634
Scope (from outer to inner):
file
namespace Nanite
Source code excerpt:
PermutationVector.Set< FPatchSplitCS::FVirtualTextureTargetDim >( VirtualShadowMapArray != nullptr );
PermutationVector.Set< FPatchSplitCS::FSplineDeformDim >( NaniteSplineMeshesSupported() );
PermutationVector.Set< FPatchSplitCS::FWriteStatsDim >(GNaniteShowStats != 0u);
auto ComputeShader = SharedContext.ShaderMap->GetShader< FPatchSplitCS >( PermutationVector );
ClearUnusedGraphResources(ComputeShader, PassParameters);
GraphBuilder.AddPass(
RDG_EVENT_NAME("PatchSplit"),
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/NaniteMaterials.cpp:40
Scope: file
Source code excerpt:
);
extern int32 GNaniteShowStats;
static bool UseLegacyCulling()
{
return !UseNaniteComputeMaterials();
}
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/NaniteShading.cpp:25
Scope: file
Source code excerpt:
extern int32 GSkipDrawOnPSOPrecaching;
extern int32 GNaniteShowStats;
#if WANTS_DRAW_MESH_EVENTS
static FORCEINLINE const TCHAR* GetShadingMaterialName(const FMaterialRenderProxy* InShadingMaterial)
{
if (InShadingMaterial == nullptr)
{
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/NaniteShading.cpp:1469
Scope (from outer to inner):
file
function FShadeBinning ShadeBinning
Source code excerpt:
const uint32 ShadingBinCountPow2 = FMath::RoundUpToPowerOfTwo(ShadingBinCount);
const bool bGatherStats = GNaniteShowStats != 0;
const FUintVector4 ViewRect = FUintVector4(uint32(InViewRect.Min.X), uint32(InViewRect.Min.Y), uint32(InViewRect.Max.X), uint32(InViewRect.Max.Y));
const uint32 PixelCount = InViewRect.Width() * InViewRect.Height();
const int32 QuadWidth = FMath::DivideAndRoundUp(InViewRect.Width(), 2);
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ShadowDepthRendering.cpp:138
Scope: file
Source code excerpt:
ECVF_RenderThreadSafe);
extern int32 GNaniteShowStats;
extern int32 GEnableNonNaniteVSM;
namespace Nanite
{
extern bool IsStatFilterActive(const FString& FilterName);
extern bool IsStatFilterActiveForLight(const FLightSceneProxy* LightProxy);
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ShadowDepthRendering.cpp:1494
Scope (from outer to inner):
file
function static void RenderShadowDepthAtlasNanite
lambda-function
Source code excerpt:
CullingConfig.SetViewFlags(SceneView);
if (GNaniteShowStats != 0)
{
FString AtlasFilterName = FString::Printf(TEXT("ShadowAtlas%d"), AtlasIndex);
CullingConfig.bExtractStats = Nanite::IsStatFilterActive(AtlasFilterName);
}
Nanite::FRasterContext RasterContext = Nanite::InitRasterContext(GraphBuilder, SharedContext, ViewFamily, AtlasSize, FullAtlasViewRect, Nanite::EOutputBufferMode::DepthOnly);
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ShadowDepthRendering.cpp:1785
Scope (from outer to inner):
file
function void FSceneRenderer::RenderShadowDepthMaps
Source code excerpt:
FString CubeFilterName;
if (GNaniteShowStats != 0)
{
// Get the base light filter name.
CubeFilterName = Nanite::GetFilterNameForLight(LightSceneInfo.Proxy);
CubeFilterName.Append(TEXT("_Face_"));
}
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ShadowDepthRendering.cpp:1833
Scope (from outer to inner):
file
function void FSceneRenderer::RenderShadowDepthMaps
Source code excerpt:
FString CubeFaceFilterName;
if (GNaniteShowStats != 0)
{
CubeFaceFilterName = CubeFilterName;
CubeFaceFilterName.AppendInt(CubemapFaceIndex);
CullingConfig.bExtractStats = Nanite::IsStatFilterActive(CubeFaceFilterName);
}