r.Shadow.Virtual.NonNanite.CulledInstanceAllocationFactor

r.Shadow.Virtual.NonNanite.CulledInstanceAllocationFactor

#Overview

name: r.Shadow.Virtual.NonNanite.CulledInstanceAllocationFactor

This variable is created as a Console Variable (cvar).

It is referenced in 3 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of r.Shadow.Virtual.NonNanite.CulledInstanceAllocationFactor is to control the allocation size for the buffer used to store instances after culling in the virtual shadow map system. This setting is specifically for non-Nanite objects in Unreal Engine 5’s rendering system.

This variable is primarily used in the Renderer module, specifically within the virtual shadow map subsystem. It’s part of Unreal Engine’s advanced rendering features, focusing on memory management for shadow rendering of non-Nanite objects.

The value of this variable is set as a console variable with a default value of 1.0f. It can be adjusted at runtime through the console or configuration files.

This variable interacts closely with CVarNonNaniteMaxCulledInstanceAllocationSize. Together, they determine the final size of the buffer used for culled instances.

Developers must be aware that:

  1. Lowering this value below 1.0 can potentially produce artifacts if the buffer overflows.
  2. The actual number of instances cannot be known on the CPU, as culling emits an instance for each clip/mip level that is overlapped.
  3. This variable is used to balance between memory usage and rendering accuracy.

Best practices when using this variable include:

  1. Keep it at 1.0 for fully conservative allocation.
  2. Adjust it carefully, monitoring for visual artifacts if lowered.
  3. Consider the trade-off between memory usage and potential rendering issues.

Regarding the associated variable CVarNonNaniteCulledInstanceAllocationFactor:

The purpose of CVarNonNaniteCulledInstanceAllocationFactor is identical to r.Shadow.Virtual.NonNanite.CulledInstanceAllocationFactor. It’s the internal representation of the console variable.

This variable is used in the same Renderer module, specifically in the virtual shadow map implementation.

Its value is set through the console variable system, sharing the same value as r.Shadow.Virtual.NonNanite.CulledInstanceAllocationFactor.

It interacts with CVarNonNaniteMaxCulledInstanceAllocationSize to calculate the final buffer size for culled instances.

Developers should be aware that this variable is accessed using GetValueOnRenderThread(), ensuring thread-safe access in the rendering code.

Best practices for using this variable are the same as for r.Shadow.Virtual.NonNanite.CulledInstanceAllocationFactor, as they represent the same setting.

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/VirtualShadowMaps/VirtualShadowMapArray.cpp:146

Scope: file

Source code excerpt:


TAutoConsoleVariable<float> CVarNonNaniteCulledInstanceAllocationFactor(
	TEXT("r.Shadow.Virtual.NonNanite.CulledInstanceAllocationFactor"),
	1.0f,
	TEXT("Allocation size scale factor for the buffer used to store instances after culling.\n")
	TEXT("The total size accounts for the worst-case scenario in which all instances are emitted into every clip or mip level.\n")
	TEXT("This is far more than we'd expect in reasonable circumstances, so this scale factor is used to reduce memory pressure.\n")
	TEXT("The actual number cannot be known on the CPU as the culling emits an instance for each clip/mip level that is overlapped.\n")
	TEXT("Setting to 1.0 is fully conservative. Lowering this is likely to produce artifacts unless you're certain the buffer won't overflow."),

#Associated Variable and Callsites

This variable is associated with another variable named CVarNonNaniteCulledInstanceAllocationFactor. They share the same value. See the following C++ source code.

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/VirtualShadowMaps/VirtualShadowMapArray.cpp:145

Scope: file

Source code excerpt:

);

TAutoConsoleVariable<float> CVarNonNaniteCulledInstanceAllocationFactor(
	TEXT("r.Shadow.Virtual.NonNanite.CulledInstanceAllocationFactor"),
	1.0f,
	TEXT("Allocation size scale factor for the buffer used to store instances after culling.\n")
	TEXT("The total size accounts for the worst-case scenario in which all instances are emitted into every clip or mip level.\n")
	TEXT("This is far more than we'd expect in reasonable circumstances, so this scale factor is used to reduce memory pressure.\n")
	TEXT("The actual number cannot be known on the CPU as the culling emits an instance for each clip/mip level that is overlapped.\n")

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/VirtualShadowMaps/VirtualShadowMapArray.cpp:2294

Scope: file

Source code excerpt:

	// This is far more than we'd expect in reasonable circumstances, so we use a scale factor to reduce memory pressure from these passes.
	const uint32 MaxCulledInstanceCount = uint32(CVarNonNaniteMaxCulledInstanceAllocationSize.GetValueOnRenderThread());
	const uint32 ScaledInstanceCount = static_cast<uint32>(static_cast<double>(TotalViewScaledInstanceCount) * CVarNonNaniteCulledInstanceAllocationFactor.GetValueOnRenderThread());
	ensureMsgf(ScaledInstanceCount <= MaxCulledInstanceCount, TEXT("Possible non-nanite VSM Instance culling overflow detected (esitmated required size: %d, if visual artifacts appear either increase the r.Shadow.Virtual.NonNanite.MaxCulledInstanceAllocationSize (%d) or reduce r.Shadow.Virtual.NonNanite.CulledInstanceAllocationFactor (%.2f)"), ScaledInstanceCount, MaxCulledInstanceCount, CVarNonNaniteCulledInstanceAllocationFactor.GetValueOnRenderThread());
	CullingResult.MaxNumInstancesPerPass = FMath::Clamp(ScaledInstanceCount, 1u, MaxCulledInstanceCount);

	FRDGBufferRef VisibleInstancesRdg = CreateStructuredBuffer(GraphBuilder, TEXT("Shadow.Virtual.VisibleInstances"), sizeof(FVSMVisibleInstanceCmd), CullingResult.MaxNumInstancesPerPass, nullptr, 0);

	FRDGBufferRef VisibleInstanceWriteOffsetRDG = CreateStructuredBuffer(GraphBuilder, TEXT("Shadow.Virtual.VisibleInstanceWriteOffset"), sizeof(uint32), 1, nullptr, 0);
	FRDGBufferRef OutputOffsetBufferRDG = CreateStructuredBuffer(GraphBuilder, TEXT("Shadow.Virtual.OutputOffsetBuffer"), sizeof(uint32), 1, nullptr, 0);