p.AsyncInterpolationMultiplier
p.AsyncInterpolationMultiplier
#Overview
name: p.AsyncInterpolationMultiplier
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
How many multiples of the fixed dt should we look behind for interpolation
It is referenced in 10
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of p.AsyncInterpolationMultiplier is to control the interpolation behavior in the Chaos physics system of Unreal Engine 5. Specifically, it determines how far back in time the system should look for interpolation purposes when using asynchronous physics simulation.
This setting variable is primarily used in the Chaos physics subsystem, which is part of Unreal Engine’s experimental physics framework. It’s particularly relevant for asynchronous physics simulations.
The value of this variable is set as a console variable, which means it can be adjusted at runtime. It’s initialized with a default value of 2.0f, but can be changed using the console command “p.AsyncInterpolationMultiplier”.
The AsyncInterpolationMultiplier interacts closely with the fixed time step (FixedDT) of the physics simulation. It’s used to calculate the interpolated time for physics objects, which is typically the current time minus (FixedDT * AsyncInterpolationMultiplier).
Developers should be aware that:
- This variable directly affects the smoothness and accuracy of interpolated physics results.
- A higher value will look further back in time, which can help smooth out physics interactions but may introduce more latency.
- It’s used in both the main game thread and in physics simulation threads, so changes can have wide-ranging effects.
Best practices when using this variable include:
- Experiment with different values to find the right balance between smoothness and responsiveness for your specific game.
- Monitor performance impacts when adjusting this value, as looking further back in time may require more memory and computation.
- Consider the nature of your game’s physics interactions when setting this value. Fast-paced games might benefit from a lower value for quicker response times.
The associated variable AsyncInterpolationMultiplier is essentially the same as p.AsyncInterpolationMultiplier, just accessed in different contexts. It’s used directly in the physics simulation code to perform the actual time calculations for interpolation. The same considerations and best practices apply to this associated variable.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/Framework/PhysicsSolverBase.cpp:208
Scope (from outer to inner):
file
namespace Chaos
Source code excerpt:
CHAOS_API FRealSingle AsyncInterpolationMultiplier = 2.f;
FAutoConsoleVariableRef CVarAsyncInterpolationMultiplier(TEXT("p.AsyncInterpolationMultiplier"), AsyncInterpolationMultiplier, TEXT("How many multiples of the fixed dt should we look behind for interpolation"), LambdaMul);
// 0 blocks on any physics steps generated from past GT Frames, and blocks on none of the tasks from current frame.
// 1 blocks on everything except the single most recent task (including tasks from current frame)
// 1 should guarantee we will always have a future output for interpolation from 2 frames in the past
// 2 doesn't block the game thread. Physics steps could be eventually be dropped if taking too much time.
int32 AsyncPhysicsBlockMode = 0;
#Associated Variable and Callsites
This variable is associated with another variable named AsyncInterpolationMultiplier
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Programs/HeadlessChaos/Private/HeadlessChaosTestPhysicsScene.cpp:18
Scope (from outer to inner):
file
namespace Chaos
Source code excerpt:
namespace Chaos
{
extern CHAOS_API float AsyncInterpolationMultiplier;
}
namespace ChaosTest {
using namespace Chaos;
using namespace ChaosInterface;
#Loc: <Workspace>/Engine/Source/Programs/HeadlessChaos/Private/HeadlessChaosTestPhysicsScene.cpp:1311
Scope (from outer to inner):
file
namespace ChaosTest
function GTEST_TEST
Source code excerpt:
Time += GTDt;
const FReal InterpolatedTime = Time - FixedDT * Chaos::AsyncInterpolationMultiplier;
const FReal ExpectedVFromForce = Time;
if (InterpolatedTime < 0)
{
//not enough time to interpolate so just take initial value
EXPECT_NEAR(Particle.X()[2], ZStart, 1e-2);
EXPECT_NEAR(Particle2.V()[2], 0, 1e-2);
#Loc: <Workspace>/Engine/Source/Programs/HeadlessChaos/Private/HeadlessChaosTestPhysicsScene.cpp:1328
Scope (from outer to inner):
file
namespace ChaosTest
function GTEST_TEST
Source code excerpt:
EXPECT_EQ(Callback->Count, NumPTSteps);
const FReal LastInterpolatedTime = NumGTSteps * GTDt - FixedDT * Chaos::AsyncInterpolationMultiplier;
EXPECT_NEAR(Particle.X()[2], ZStart + ZVel * LastInterpolatedTime, 1e-2);
EXPECT_NEAR(Particle.V()[2], ZVel, 1e-2);
}
void ExpectVectorEqual(const FVec3& V0, const FVec3& V1)
{
#Loc: <Workspace>/Engine/Source/Programs/HeadlessChaos/Private/HeadlessChaosTestPhysicsScene.cpp:1588
Scope (from outer to inner):
file
namespace ChaosTest
function GTEST_TEST
Source code excerpt:
Time += GTDt;
const FReal InterpolatedTime = Time - FixedDT * Chaos::AsyncInterpolationMultiplier;
if (InterpolatedTime < 0)
{
//not enough time to interpolate so just take initial value
EXPECT_NEAR(Particle.X()[2], ZStart, 1e-2);
}
else
#Loc: <Workspace>/Engine/Source/Programs/HeadlessChaos/Private/HeadlessChaosTestPhysicsScene.cpp:1668
Scope (from outer to inner):
file
namespace ChaosTest
function GTEST_TEST
Source code excerpt:
}
const FReal LastInterpolatedTime = NumGTSteps * GTDt - FixedDT * Chaos::AsyncInterpolationMultiplier;
EXPECT_EQ(Particle.V()[2], ZVel);
EXPECT_EQ(Particle.V()[1], YVelAfterChange);
}
GTEST_TEST(EngineInterface, FlushCommand)
{
#Loc: <Workspace>/Engine/Source/Programs/HeadlessChaos/Private/HeadlessChaosTestRewind.cpp:4328
Scope (from outer to inner):
file
namespace ChaosTest
function GTEST_TEST
Source code excerpt:
GTEST_TEST(AllTraits, RewindTest_InterpolatedTwoChannels)
{
Chaos::AsyncInterpolationMultiplier = 3.0f;
int32 PrevNumActiveChannels = Chaos::DefaultNumActiveChannels;
Chaos::DefaultNumActiveChannels = 2;
//Have two moving particles, one in each channel to see that there's a delay in time on second channel
TRewindHelper::TestDynamicSphere([](auto* Solver, FReal SimDt, int32 Optimization, auto Proxy, auto Sphere)
{
if (!Solver->IsUsingAsyncResults()) { return; }
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/Framework/PhysicsSolverBase.cpp:207
Scope (from outer to inner):
file
namespace Chaos
Source code excerpt:
});
CHAOS_API FRealSingle AsyncInterpolationMultiplier = 2.f;
FAutoConsoleVariableRef CVarAsyncInterpolationMultiplier(TEXT("p.AsyncInterpolationMultiplier"), AsyncInterpolationMultiplier, TEXT("How many multiples of the fixed dt should we look behind for interpolation"), LambdaMul);
// 0 blocks on any physics steps generated from past GT Frames, and blocks on none of the tasks from current frame.
// 1 blocks on everything except the single most recent task (including tasks from current frame)
// 1 should guarantee we will always have a future output for interpolation from 2 frames in the past
// 2 doesn't block the game thread. Physics steps could be eventually be dropped if taking too much time.
int32 AsyncPhysicsBlockMode = 0;
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/Framework/PhysicsSolverBase.cpp:240
Scope (from outer to inner):
file
namespace Chaos
function FPhysicsSolverBase::FPhysicsSolverBase
Source code excerpt:
, ExternalSteps(0)
, AsyncBlockMode(EAsyncBlockMode(AsyncPhysicsBlockMode))
, AsyncMultiplier(AsyncInterpolationMultiplier)
#if !UE_BUILD_SHIPPING
, bStealAdvanceTasksForTesting(false)
#endif
{
UE_LOG(LogChaos, Verbose, TEXT("FPhysicsSolverBase::AsyncDt:%f"), IsUsingAsyncResults() ? AsyncDt : -1);
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Public/Chaos/Framework/PhysicsSolverBase.h:50
Scope (from outer to inner):
file
namespace Chaos
Source code excerpt:
extern CHAOS_API int32 UseAsyncInterpolation;
extern CHAOS_API int32 ForceDisableAsyncPhysics;
extern CHAOS_API FRealSingle AsyncInterpolationMultiplier;
struct FSubStepInfo
{
FSubStepInfo()
: PseudoFraction(1.0)
, Step(1)