ShowFlag.PhysicsField
ShowFlag.PhysicsField
#Overview
name: ShowFlag.PhysicsField
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
Allows to override a specific showflag (works in editor and game, \
It is referenced in 26
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of ShowFlag.PhysicsField
is to control the visualization of physics fields in the Unreal Engine 5 rendering system. This show flag is used to toggle the visibility of physics field debug information in the game viewport.
The Physics Field system is primarily used in the Unreal Engine’s physics and rendering subsystems. Based on the provided code snippets, it interacts with the following modules and components:
- Chaos Cloth simulation
- Niagara particle system
- Animation system (RigidBody nodes)
- World and Scene management
- Field System components
- Geometry Collection components
- Deferred Shading Renderer
The value of this variable is set through the engine’s show flags system, which allows developers to toggle various debug visualization options in the editor and at runtime.
The ShowFlag.PhysicsField
interacts closely with the World->PhysicsField
object, which is an instance of UPhysicsFieldComponent
. This component is responsible for managing and evaluating physics fields in the world.
Developers should be aware of the following when using this variable:
- It’s primarily used for debug visualization and should be disabled in shipping builds.
- Enabling this flag may have performance implications, especially in complex scenes with many physics fields.
- The visualization is rendered in the deferred shading pass, which means it may not be visible in forward rendering or mobile platforms.
Best practices when using this variable include:
- Use it during development and debugging phases to visualize and verify physics field behaviors.
- Ensure it’s disabled in release builds to avoid unnecessary performance overhead.
- Combine it with other debug tools and visualizations to get a comprehensive understanding of the physics simulation.
Regarding the associated variable PhysicsField
, it is an instance of UPhysicsFieldComponent
stored in the UWorld
class. This component is responsible for managing physics fields in the world, including:
- Storing and evaluating field commands
- Providing interfaces for other systems (like cloth simulation and particle systems) to interact with physics fields
- Handling world origin shifts and other world-related operations
The PhysicsField
component is created and managed by the UWorld
class, and it’s used extensively throughout the engine to provide physics field functionality to various subsystems. Developers working with physics fields should familiarize themselves with the UPhysicsFieldComponent
class and its methods to effectively utilize physics fields in their projects.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/ShowFlagsValues.inl:337
Scope: file
Source code excerpt:
SHOWFLAG_FIXED_IN_SHIPPING(0, VisualizeMeshDistanceFields, SFG_Visualize, NSLOCTEXT("UnrealEd", "MeshDistanceFieldsSF", "Mesh DistanceFields"))
/** Physics field */
SHOWFLAG_FIXED_IN_SHIPPING(0, PhysicsField, SFG_Visualize, NSLOCTEXT("UnrealEd", "PhysicsField", "Physics Field"))
/** Global Distance field */
SHOWFLAG_FIXED_IN_SHIPPING(0, VisualizeGlobalDistanceField, SFG_Visualize, NSLOCTEXT("UnrealEd", "GlobalDistanceFieldSF", "Global DistanceField"))
/** Enable the debug visualization of diffuse/specular lighting (direct and indirect) using probes */
SHOWFLAG_FIXED_IN_SHIPPING(0, VisualizeLightingOnProbes, SFG_Visualize, NSLOCTEXT("UnrealEd", "VisualizeLightingOnProbesSF", "Visualize Lighting on Probes"))
/** Screen space AO, for now SHOWFLAG_ALWAYS_ACCESSIBLE because r.GBuffer need that */
SHOWFLAG_ALWAYS_ACCESSIBLE(ScreenSpaceAO, SFG_LightingFeatures, NSLOCTEXT("UnrealEd", "ScreenSpaceAOSF", "Screen Space Ambient Occlusion"))
#Associated Variable and Callsites
This variable is associated with another variable named PhysicsField
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Plugins/ChaosCloth/Source/ChaosCloth/Private/ChaosCloth/ChaosClothingSimulation.cpp:397
Scope (from outer to inner):
file
function void FClothingSimulation::UpdateWorldForces
Source code excerpt:
{
UWorld* OwnerWorld = OwnerComponent->GetWorld();
if (OwnerWorld && OwnerWorld->PhysicsField && Solver)
{
const FBox BoundingBox = OwnerComponent->CalcBounds(OwnerComponent->GetComponentTransform()).GetBox();
OwnerWorld->PhysicsField->FillTransientCommands(false, BoundingBox, Solver->GetTime(), Solver->GetPerSolverField().GetTransientCommands());
OwnerWorld->PhysicsField->FillPersistentCommands(false, BoundingBox, Solver->GetTime(), Solver->GetPerSolverField().GetPersistentCommands());
}
}
}
void FClothingSimulation::ResetStats()
{
#Loc: <Workspace>/Engine/Plugins/Experimental/ChaosNiagara/Source/ChaosNiagara/Private/NiagaraDataInterfacePhysicsField.cpp:84
Scope (from outer to inner):
file
function void FNDIPhysicsFieldData::Init
Source code excerpt:
TimeSeconds = World->GetTimeSeconds();
UPhysicsFieldComponent* FieldComponent = World->PhysicsField;
if (FieldComponent && FieldComponent->FieldInstance && FieldComponent->FieldInstance->FieldResource)
{
FieldResource = FieldComponent->FieldInstance->FieldResource;
}
}
LWCConverter = SystemInstance->GetLWCConverter();
#Loc: <Workspace>/Engine/Plugins/Experimental/ChaosNiagara/Source/ChaosNiagara/Private/NiagaraDataInterfacePhysicsField.cpp:103
Scope (from outer to inner):
file
function void FNDIPhysicsFieldData::Update
Source code excerpt:
TimeSeconds = World->GetTimeSeconds();
UPhysicsFieldComponent* FieldComponent = World->PhysicsField;
if (FieldComponent && FieldComponent->FieldInstance)
{
FieldCommands = FieldComponent->FieldInstance->FieldCommands;
}
}
}
#Loc: <Workspace>/Engine/Plugins/Experimental/PhysicsControl/Source/PhysicsControl/Private/AnimNode_RigidBodyWithControl.cpp:1486
Scope (from outer to inner):
file
function void FAnimNode_RigidBodyWithControl::PreUpdate
Source code excerpt:
CurrentTransform = SKC->GetComponentToWorld();
if (World->PhysicsField)
{
const FBox BoundingBox = SKC->CalcBounds(SKC->GetComponentTransform()).GetBox();
World->PhysicsField->FillTransientCommands(false, BoundingBox, WorldTimeSeconds, PerSolverField.GetTransientCommands());
World->PhysicsField->FillPersistentCommands(false, BoundingBox, WorldTimeSeconds, PerSolverField.GetPersistentCommands());
}
}
}
}
int32 FAnimNode_RigidBodyWithControl::GetLODThreshold() const
#Loc: <Workspace>/Engine/Source/Runtime/AnimGraphRuntime/Private/BoneControllers/AnimNode_RigidBody.cpp:1531
Scope (from outer to inner):
file
function void FAnimNode_RigidBody::PreUpdate
Source code excerpt:
CurrentTransform = SKC->GetComponentToWorld();
if (World->PhysicsField)
{
const FBox BoundingBox = SKC->CalcBounds(SKC->GetComponentTransform()).GetBox();
PRAGMA_DISABLE_UNSAFE_TYPECAST_WARNINGS
World->PhysicsField->FillTransientCommands(false, BoundingBox, WorldTimeSeconds, PerSolverField.GetTransientCommands());
World->PhysicsField->FillPersistentCommands(false, BoundingBox, WorldTimeSeconds, PerSolverField.GetPersistentCommands());
PRAGMA_RESTORE_UNSAFE_TYPECAST_WARNINGS
}
}
}
if (bUseExternalClothCollision && ClothColliders.IsEmpty())
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Engine/World.h:1431
Scope (from outer to inner):
file
class class UWorld final : public UObject, public FNetworkNotify
Source code excerpt:
/** Physics Field component. */
UPROPERTY(Transient)
TObjectPtr<class UPhysicsFieldComponent> PhysicsField;
private:
/** Array of components that need to wait on tasks before end of frame updates */
UPROPERTY(Transient, NonTransactional)
TSet<TObjectPtr<UActorComponent>> ComponentsThatNeedPreEndOfFrameSync;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/PhysicsField/PhysicsFieldComponent.cpp:1229
Scope (from outer to inner):
file
function FVector UPhysicsFieldStatics::EvalPhysicsVectorField
Source code excerpt:
const EFieldPhysicsType PhysicsType = GetFieldTargetTypes(Field_Output_Vector)[TargetType];
UPhysicsFieldComponent* FieldComponent = ThisWorld->PhysicsField;
if (FieldComponent && FieldComponent->FieldInstance)
{
EvaluateFieldVectorNodes(FieldComponent->FieldInstance->FieldCommands, PhysicsType, FieldContext, SampleResults, SampleMax);
return SampleMax[0];
}
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/PhysicsField/PhysicsFieldComponent.cpp:1260
Scope (from outer to inner):
file
function float UPhysicsFieldStatics::EvalPhysicsScalarField
Source code excerpt:
const EFieldPhysicsType PhysicsType = GetFieldTargetTypes(Field_Output_Scalar)[TargetType];
UPhysicsFieldComponent* FieldComponent = ThisWorld->PhysicsField;
if (FieldComponent && FieldComponent->FieldInstance)
{
EvaluateFieldScalarNodes(FieldComponent->FieldInstance->FieldCommands, PhysicsType, FieldContext, SampleResults, SampleMax);
return SampleMax[0];
}
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/PhysicsField/PhysicsFieldComponent.cpp:1291
Scope (from outer to inner):
file
function int32 UPhysicsFieldStatics::EvalPhysicsIntegerField
Source code excerpt:
const EFieldPhysicsType PhysicsType = GetFieldTargetTypes(Field_Output_Scalar)[TargetType];
UPhysicsFieldComponent* FieldComponent = ThisWorld->PhysicsField;
if (FieldComponent && FieldComponent->FieldInstance)
{
EvaluateFieldIntegerNodes(FieldComponent->FieldInstance->FieldCommands, PhysicsType, FieldContext, SampleResults, SampleMax);
return SampleMax[0];
}
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/World.cpp:706
Scope (from outer to inner):
file
function void UWorld::Serialize
Source code excerpt:
Ar << PersistentLineBatcher;
Ar << ForegroundLineBatcher;
Ar << PhysicsField;
Ar << MyParticleEventManager;
Ar << GameState;
Ar << AuthorityGameMode;
Ar << NetworkManager;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/World.cpp:777
Scope (from outer to inner):
file
function void UWorld::AddReferencedObjects
Source code excerpt:
Collector.AddReferencedObject( This->PersistentLineBatcher, This );
Collector.AddReferencedObject( This->ForegroundLineBatcher, This );
Collector.AddReferencedObject( This->PhysicsField, This);
Collector.AddReferencedObject( This->MyParticleEventManager, This );
Collector.AddReferencedObject( This->GameState, This );
Collector.AddReferencedObject( This->AuthorityGameMode, This );
Collector.AddReferencedObject( This->NetworkManager, This );
Collector.AddReferencedObject( This->NavigationSystem, This );
Collector.AddReferencedObject( This->AvoidanceManager, This );
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/World.cpp:2561
Scope (from outer to inner):
file
function void UWorld::ClearWorldComponents
Source code excerpt:
}
if (PhysicsField && PhysicsField->IsRegistered())
{
PhysicsField->UnregisterComponent();
}
}
void UWorld::UpdateWorldComponents(bool bRerunConstructionScripts, bool bCurrentLevelOnly, FRegisterComponentContext* Context)
{
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/World.cpp:2614
Scope (from outer to inner):
file
function void UWorld::UpdateWorldComponents
Source code excerpt:
if (PhysicsFieldEnableClipmapCVar && PhysicsFieldEnableClipmapCVar->GetInt() == 1 && Scene && !IsMobilePlatform(Scene->GetShaderPlatform()))
{
if (!PhysicsField)
{
PhysicsField = NewObject<UPhysicsFieldComponent>();
}
if (!PhysicsField->IsRegistered())
{
PhysicsField->RegisterComponentWithWorld(this, Context);
}
}
}
if ( bCurrentLevelOnly )
{
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/World.cpp:7015
Scope (from outer to inner):
file
function bool UWorld::SetNewWorldOrigin
Source code excerpt:
}
if (PhysicsField)
{
PhysicsField->ApplyWorldOffset(Offset, true);
}
FIntVector PreviosWorldOriginLocation = OriginLocation;
// Set new world origin
OriginLocation = InNewOriginLocation;
RequestedOriginLocation = InNewOriginLocation;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/ShowFlagsValues.inl:337
Scope: file
Source code excerpt:
SHOWFLAG_FIXED_IN_SHIPPING(0, VisualizeMeshDistanceFields, SFG_Visualize, NSLOCTEXT("UnrealEd", "MeshDistanceFieldsSF", "Mesh DistanceFields"))
/** Physics field */
SHOWFLAG_FIXED_IN_SHIPPING(0, PhysicsField, SFG_Visualize, NSLOCTEXT("UnrealEd", "PhysicsField", "Physics Field"))
/** Global Distance field */
SHOWFLAG_FIXED_IN_SHIPPING(0, VisualizeGlobalDistanceField, SFG_Visualize, NSLOCTEXT("UnrealEd", "GlobalDistanceFieldSF", "Global DistanceField"))
/** Enable the debug visualization of diffuse/specular lighting (direct and indirect) using probes */
SHOWFLAG_FIXED_IN_SHIPPING(0, VisualizeLightingOnProbes, SFG_Visualize, NSLOCTEXT("UnrealEd", "VisualizeLightingOnProbesSF", "Visualize Lighting on Probes"))
/** Screen space AO, for now SHOWFLAG_ALWAYS_ACCESSIBLE because r.GBuffer need that */
SHOWFLAG_ALWAYS_ACCESSIBLE(ScreenSpaceAO, SFG_LightingFeatures, NSLOCTEXT("UnrealEd", "ScreenSpaceAOSF", "Screen Space Ambient Occlusion"))
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/FieldSystem/Source/FieldSystemEngine/Private/Field/FieldSystemComponent.cpp:188
Scope (from outer to inner):
file
function void UFieldSystemComponent::DispatchFieldCommand
Source code excerpt:
{
UWorld* World = GetWorld();
if (World && World->PhysicsField)
{
FFieldSystemCommand LocalCommand = InCommand;
LocalCommand.InitFieldNodes(World->GetTimeSeconds(), Name);
if (!IsTransient)
{
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/FieldSystem/Source/FieldSystemEngine/Private/Field/FieldSystemComponent.cpp:198
Scope (from outer to inner):
file
function void UFieldSystemComponent::DispatchFieldCommand
Source code excerpt:
{
WorldGPUPersistentFields.Add(LocalCommand);
World->PhysicsField->AddPersistentCommand(LocalCommand, true);
}
if (bIsChaosField)
{
WorldCPUPersistentFields.Add(LocalCommand);
World->PhysicsField->AddPersistentCommand(LocalCommand, false);
}
}
else
{
if (bIsWorldField)
{
World->PhysicsField->AddTransientCommand(LocalCommand, true);
}
if (bIsChaosField)
{
World->PhysicsField->AddTransientCommand(LocalCommand, false);
}
}
}
}
}
}
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/FieldSystem/Source/FieldSystemEngine/Private/Field/FieldSystemComponent.cpp:253
Scope (from outer to inner):
file
function void UFieldSystemComponent::ClearFieldCommands
Source code excerpt:
{
UWorld* World = GetWorld();
if (World && World->PhysicsField)
{
if (bIsWorldField)
{
for (auto& FieldCommand : WorldGPUPersistentFields)
{
World->PhysicsField->RemovePersistentCommand(FieldCommand, true);
}
}
if (bIsChaosField)
{
for (auto& FieldCommand : WorldCPUPersistentFields)
{
World->PhysicsField->RemovePersistentCommand(FieldCommand, false);
}
}
}
}
WorldGPUPersistentFields.Reset();
WorldCPUPersistentFields.Reset();
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/FieldSystem/Source/FieldSystemEngine/Private/Field/FieldSystemComponent.cpp:298
Scope (from outer to inner):
file
function void UFieldSystemComponent::AddFieldCommand
Source code excerpt:
UWorld* World = GetWorld();
if (World && World->PhysicsField)
{
const FName Name = GetOwner() ? *GetOwner()->GetName() : TEXT("");
FFieldSystemCommand LocalCommand = Command;
LocalCommand.InitFieldNodes(World->GetTimeSeconds(), Name);
World->PhysicsField->AddConstructionCommand(LocalCommand);
}
}
}
BufferCommands.AddFieldCommand(GetFieldPhysicsName(Target), Field, MetaData);
}
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/GeometryCollectionEngine/Private/GeometryCollection/GeometryCollectionComponent.cpp:5876
Scope (from outer to inner):
file
function void UGeometryCollectionComponent::GetInitializationCommands
Source code excerpt:
UWorld* World = GetWorld();
if (World && World->PhysicsField)
{
const FName Name = GetOwner() ? *GetOwner()->GetName() : TEXT("");
FFieldSystemCommand LocalCommand = NewCommand;
LocalCommand.InitFieldNodes(World->GetTimeSeconds(), Name);
World->PhysicsField->AddConstructionCommand(LocalCommand);
}
}
}
}
// Legacy path : only there for old levels. New ones will have the commands directly stored onto the component
else if (FieldSystemActor->GetFieldSystemComponent()->GetFieldSystem())
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/DeferredShadingRenderer.cpp:3217
Scope (from outer to inner):
file
function void FDeferredShadingSceneRenderer::Render
Source code excerpt:
RendererModule.RenderOverlayExtensions(GraphBuilder, Views, SceneTextures);
if (ViewFamily.EngineShowFlags.PhysicsField && Scene->PhysicsField)
{
RenderPhysicsField(GraphBuilder, Views, Scene->PhysicsField, SceneTextures.Color.Target);
}
if (ViewFamily.EngineShowFlags.VisualizeDistanceFieldAO && ShouldRenderDistanceFieldLighting())
{
GraphBuilder.SetCommandListStat(GET_STATID(STAT_CLM_RenderDistanceFieldLighting));
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/RendererScene.cpp:2913
Scope (from outer to inner):
file
function void FScene::SetPhysicsField
lambda-function
Source code excerpt:
[Scene, PhysicsFieldSceneProxy] (FRHICommandListBase&)
{
Scene->PhysicsField = PhysicsFieldSceneProxy;
});
}
void FScene::ShowPhysicsField()
{
// Set the shader print/debug values from game thread if
// physics field visualisation has been enabled
if (PhysicsField && PhysicsField->FieldResource && PhysicsField->FieldResource->FieldInfos.bShowFields)
{
// Force ShaderPrint on.
ShaderPrint::SetEnabled(true);
ShaderPrint::RequestSpaceForLines(128000);
}
}
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/RendererScene.cpp:2936
Scope (from outer to inner):
file
function void FScene::ResetPhysicsField
lambda-function
Source code excerpt:
[Scene] (FRHICommandListBase&)
{
Scene->PhysicsField = nullptr;
});
}
void FScene::UpdatePhysicsField(FRDGBuilder& GraphBuilder, FViewInfo& View)
{
if (PhysicsField)
{
PhysicsField->FieldResource->FieldInfos.ViewOrigin = View.ViewMatrices.GetViewOrigin();
if (View.Family )
{
PhysicsField->FieldResource->FieldInfos.bShowFields = View.Family->EngineShowFlags.PhysicsField;
}
}
}
void FScene::AddDecal(UDecalComponent* Component)
{
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ScenePrivate.h:3150
Scope (from outer to inner):
file
class class FScene : public FSceneInterface
Source code excerpt:
/** Global Field Manager */
class FPhysicsFieldSceneProxy* PhysicsField = nullptr;
/** The wind sources in the scene. */
TArray<class FWindSourceSceneProxy*> WindSources;
/** Wind source components, tracked so the game thread can also access wind parameters */
TArray<UWindDirectionalSourceComponent*> WindComponents_GameThread;
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/SceneRendering.cpp:1193
Scope (from outer to inner):
file
function void SetupPhysicsFieldUniformBufferParameters
Source code excerpt:
void SetupPhysicsFieldUniformBufferParameters(const FScene* Scene, FEngineShowFlags EngineShowFlags, FViewUniformShaderParameters& ViewUniformShaderParameters)
{
if (Scene && Scene->PhysicsField && Scene->PhysicsField->FieldResource)
{
FPhysicsFieldResource* FieldResource = Scene->PhysicsField->FieldResource;
if (FieldResource->FieldInfos.bBuildClipmap)
{
ViewUniformShaderParameters.PhysicsFieldClipmapBuffer = FieldResource->ClipmapBuffer.SRV.GetReference();
}
else
{