r.Forward.MaxCulledLightsPerCell
r.Forward.MaxCulledLightsPerCell
#Overview
name: r.Forward.MaxCulledLightsPerCell
The value of this variable can be defined or overridden in .ini config files. 1
.ini config file referencing this setting variable.
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
Controls how much memory is allocated for each cell for light culling. When r.Forward.LightLinkedListCulling is enabled, this is used to compute a global max instead of a per-cell limit on culled lights.
It is referenced in 6
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of r.Forward.MaxCulledLightsPerCell is to control the memory allocation for light culling in each cell of the light grid used in forward rendering. This setting is part of Unreal Engine’s rendering system, specifically the forward rendering pipeline.
The Unreal Engine subsystem that relies on this setting variable is the Renderer module, particularly the light culling and injection system for forward rendering. This can be seen from the file path “Engine/Source/Runtime/Renderer/Private/LightGridInjection.cpp”.
The value of this variable is set through the Unreal Engine console variable system. It’s initialized with a default value of 32 and can be modified at runtime using console commands.
This variable interacts closely with GMaxCulledLightsPerCell, which is the associated C++ variable that directly holds the value set by r.Forward.MaxCulledLightsPerCell. It also interacts with GLightLinkedListCulling, which affects how the MaxCulledLightsPerCell value is used.
Developers must be aware that:
- This variable affects memory allocation, so setting it too high might lead to excessive memory usage.
- When r.Forward.LightLinkedListCulling is enabled, this variable is used to compute a global maximum instead of a per-cell limit on culled lights.
- The value of this variable impacts performance and visual quality, as it determines how many lights can be considered for each cell in the light grid.
Best practices when using this variable include:
- Balancing between performance and visual quality. Higher values allow more lights per cell but increase memory usage and potentially processing time.
- Monitoring performance and memory usage when adjusting this value.
- Considering the target hardware capabilities when setting this value, especially for games targeting a wide range of devices.
Regarding the associated variable GMaxCulledLightsPerCell:
- It directly holds the value set by r.Forward.MaxCulledLightsPerCell.
- It’s used in various parts of the light grid injection process, including memory allocation for light culling data structures and as a parameter in the light grid injection compute shader.
- Developers should be aware that changing r.Forward.MaxCulledLightsPerCell will directly affect GMaxCulledLightsPerCell, and thus the behavior of the light culling system.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/Android/AndroidEngine.ini:84, section: [ConsoleVariables]
- INI Section:
ConsoleVariables
- Raw value:
8
- Is Array:
False
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/LightGridInjection.cpp:64
Scope: file
Source code excerpt:
int32 GMaxCulledLightsPerCell = 32;
FAutoConsoleVariableRef CVarMaxCulledLightsPerCell(
TEXT("r.Forward.MaxCulledLightsPerCell"),
GMaxCulledLightsPerCell,
TEXT("Controls how much memory is allocated for each cell for light culling. When r.Forward.LightLinkedListCulling is enabled, this is used to compute a global max instead of a per-cell limit on culled lights."),
ECVF_Scalability | ECVF_RenderThreadSafe
);
int32 GLightLinkedListCulling = 1;
#Associated Variable and Callsites
This variable is associated with another variable named GMaxCulledLightsPerCell
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/LightGridInjection.cpp:62
Scope: file
Source code excerpt:
);
int32 GMaxCulledLightsPerCell = 32;
FAutoConsoleVariableRef CVarMaxCulledLightsPerCell(
TEXT("r.Forward.MaxCulledLightsPerCell"),
GMaxCulledLightsPerCell,
TEXT("Controls how much memory is allocated for each cell for light culling. When r.Forward.LightLinkedListCulling is enabled, this is used to compute a global max instead of a per-cell limit on culled lights."),
ECVF_Scalability | ECVF_RenderThreadSafe
);
int32 GLightLinkedListCulling = 1;
FAutoConsoleVariableRef CVarLightLinkedListCulling(
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/LightGridInjection.cpp:756
Scope: file
Source code excerpt:
ForwardLightData->NumGridCells = LightGridSizeXY.X * LightGridSizeXY.Y * GLightGridSizeZ;
ForwardLightData->CulledGridSize = FIntVector(LightGridSizeXY.X, LightGridSizeXY.Y, GLightGridSizeZ);
ForwardLightData->MaxCulledLightsPerCell = GLightLinkedListCulling ? NumLocalLightsFinal: GMaxCulledLightsPerCell;
ForwardLightData->LightGridPixelSizeShift = FMath::FloorLog2(GLightGridPixelSize);
ForwardLightData->SimpleLightsEndIndex = SimpleLightsEnd;
ForwardLightData->ClusteredDeferredSupportedEndIndex = ClusteredSupportedEnd;
ForwardLightData->ManyLightsSupportedStartIndex = FMath::Min<int32>(ManyLightsSupportedStart, NumLocalLightsFinal);
ForwardLightData->DirectLightingShowFlag = ViewFamily.EngineShowFlags.DirectLighting ? 1 : 0;
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/LightGridInjection.cpp:815
Scope: file
Source code excerpt:
ForwardLightData->NumReflectionCaptures);
const uint32 CulledLightLinksElements = MaxNumCells * GMaxCulledLightsPerCell * LightLinkStride;
FRDGBufferRef CulledLightLinksBuffer = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateStructuredDesc(sizeof(uint32), CulledLightLinksElements), TEXT("CulledLightLinks"));
FRDGBufferRef StartOffsetGridBuffer = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateStructuredDesc(sizeof(uint32), MaxNumCells), TEXT("StartOffsetGrid"));
FRDGBufferRef NextCulledLightLinkBuffer = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateStructuredDesc(sizeof(uint32), 1), TEXT("NextCulledLightLink"));
FRDGBufferRef NextCulledLightDataBuffer = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateStructuredDesc(sizeof(uint32), 1), TEXT("NextCulledLightData"));
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/LightGridInjection.cpp:832
Scope: file
Source code excerpt:
const SIZE_T LightIndexTypeSize = sizeof(FLightIndexType);
const EPixelFormat CulledLightDataGridFormat = PF_R16_UINT;
FRDGBufferRef CulledLightDataGrid = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateBufferDesc(LightIndexTypeSize, MaxNumCells * GMaxCulledLightsPerCell), TEXT("CulledLightDataGrid"));
CulledLightDataGridSRV = GraphBuilder.CreateSRV(CulledLightDataGrid, CulledLightDataGridFormat);
CulledLightDataGridUAV = GraphBuilder.CreateUAV(CulledLightDataGrid, CulledLightDataGridFormat);
}
else
{
const SIZE_T LightIndexTypeSize = sizeof(FLightIndexType32);
const EPixelFormat CulledLightDataGridFormat = PF_R32_UINT;
FRDGBufferRef CulledLightDataGrid = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateStructuredDesc(LightIndexTypeSize, MaxNumCells * GMaxCulledLightsPerCell), TEXT("CulledLightDataGrid"));
CulledLightDataGridSRV = GraphBuilder.CreateSRV(CulledLightDataGrid);
CulledLightDataGridUAV = GraphBuilder.CreateUAV(CulledLightDataGrid);
}
FLightGridInjectionCS::FParameters *PassParameters = GraphBuilder.AllocParameters<FLightGridInjectionCS::FParameters>();
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/LightGridInjection.cpp:869
Scope: file
Source code excerpt:
PassParameters->NumReflectionCaptures = ForwardLightData->NumReflectionCaptures;
PassParameters->NumLocalLights = ForwardLightData->NumLocalLights;
PassParameters->MaxCulledLightsPerCell = GMaxCulledLightsPerCell;
PassParameters->NumGridCells = ForwardLightData->NumGridCells;
PassParameters->LightGridPixelSizeShift = ForwardLightData->LightGridPixelSizeShift;
#if ENABLE_LIGHT_CULLING_VIEW_SPACE_BUILD_DATA
check(ViewSpacePosAndRadiusData.Num() == ForwardLocalLightData.Num());
check(ViewSpaceDirAndPreprocAngleData.Num() == ForwardLocalLightData.Num());