Description

We've noticed smearing in grass due to wrong motion vectors. This appears to be caused by lack of previous frame support in the periodic world space node.

This is how we fixed it:

In MaterialTemplate.ush

// Periodic World Position

float3 GetPeriodicWorldOrigin(float3 Scale)
{
    // Following three lines can be replaced with `ScaledPos = DFDivide(ResolvedView.PreViewTranslation, Scale)` but this is faster and reasonably precise.
    float3 InvScale = rcp(Scale);
    FDFVector3 ScaledPos = DFTwoProduct(ResolvedView.PreViewTranslation.High, InvScale);
    ScaledPos.Low += ResolvedView.PreViewTranslation.Low * InvScale;

    return DFFracDemote(ScaledPos) * Scale;
}

float3 GetPeriodicWorldOrigin_Pow2(float3 Scale)
{
    return DFFmodByPow2Demote(ResolvedView.PreViewTranslation, Scale);
}

// CHANGE BEGIN
float3 GetPrevPeriodicWorldOrigin(float3 Scale)
{
    // Following three lines can be replaced with `ScaledPos = DFDivide(ResolvedView.PrevPreViewTranslation, Scale)` but this is faster and reasonably precise.
    float3 InvScale = rcp(Scale);
    FDFVector3 ScaledPos = DFTwoProduct(ResolvedView.PrevPreViewTranslation.High, InvScale);
    ScaledPos.Low += ResolvedView.PrevPreViewTranslation.Low * InvScale;

    return DFFracDemote(ScaledPos) * Scale;
}

float3 GetPrevPeriodicWorldOrigin_Pow2(float3 Scale)
{
    return DFFmodByPow2Demote(ResolvedView.PrevPreViewTranslation, Scale);
}
// CHANGE END

In HLSLMaterialTranslator.cpp

int32 FHLSLMaterialTranslator::CalculatePeriodicWorldPositionOrigin(int TileScaleIndex)
{
    // float3 PeriodicWorldOrigin = GetPeriodicWorldOrigin(Scale);
    FString PeriodicWorldOrigin = CreateSymbolName(TEXT("PeriodicWorldOrigin"));
    // CHANGE BEGIN
    FString FuncName = IsConstFloatOfPow2Expression(TileScaleIndex) ?
        (bCompilingPreviousFrame ? TEXT("GetPrevPeriodicWorldOrigin_Pow2") : TEXT("GetPeriodicWorldOrigin_Pow2")) :
        (bCompilingPreviousFrame ? TEXT("GetPrevPeriodicWorldOrigin") : TEXT("GetPeriodicWorldOrigin"));
    // CHANGE END
    FString Code = FString::Format(TEXT(" float3 {0} = {1}({2},{3}"), *PeriodicWorldOrigin, *FuncName, *GetParameterCode(TileScaleIndex), HLSL_LINE_TERMINATOR );

    AddInlinedCodeChunk(EMaterialValueType::MCT_VoidStatement, *Code);
    return AddCodeChunk(MCT_Float3, *PeriodicWorldOrigin);
}
Steps to Reproduce

Steps to Reproduce

Use Periodic World Space coordinate and hook it up to World Position Offset

Note smearing due to TSR/TAA. We've only noticed it in packaged builds with high frame rate but theoretically you should also see it in-editor

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-379620 in the post.

0
Login to Vote

Unresolved
ComponentUE - Rendering - Graphics Features
Affects Versions5.6
CreatedMay 13, 2026
UpdatedMay 18, 2026
View Jira Issue