[Runtime] USD components randomly fail to display in Packaged Build, especially in large levels

[Runtime] USD components randomly fail to display in Packaged Build, especially in large levels

Description

When using UsdImporter to load a USD file at runtime, some components of the USD asset may randomly fail to appear in the Packaged Build.

The most important observation is:

The issue does NOT occur when running in the Unreal Editor . The same USD file loads and displays correctly in the Editor every time. The issue only occurs after packaging the project.

The missing components are non-deterministic. Different components may fail to appear on different runs, even when loading exactly the same USD file.

Based on my testing, the probability and severity of the issue appear to be strongly related to the amount of existing content in the level.


Editor vs. Packaged Build

Environment Result
Unreal Editor / PIE Works correctly
Packaged Development Build Issue occurs
Packaged Shipping Build Issue occurs / [please confirm if tested]

In the Editor, I have repeatedly tested the same USD file under the same conditions, and all USD components are displayed correctly.

After packaging the project, some USD components may randomly fail to appear.

This difference between Editor and Packaged Build is currently the most significant characteristic of the issue.


Observed Behavior

When loading a USD file into an existing level at runtime in a Packaged Build:

  • Some USD components may fail to appear.

  • The missing components are random and are not always the same between runs.

  • The issue is not consistently reproducible with the same missing components.

  • The issue becomes significantly more frequent as the amount of existing content in the level increases.

  • When the issue occurs, a larger level also tends to result in more missing USD components.

  • Loading the same USD file into an almost empty level greatly reduces the frequency of the issue, but does not completely eliminate it.


Correlation with Existing Level Content

I tested the same USD file under different level conditions.

Empty Level

When the USD file is loaded into an almost empty level:

  • The issue occurs much less frequently.

  • However, the issue can still occur occasionally.

Large Level

When the level already contains a large number of Static Mesh Actors:

  • The issue occurs much more frequently.

  • More USD components tend to be missing when the issue occurs.

Increasing the number of existing Static Meshes in the level also increases the probability of missing USD components.

Therefore, the amount of existing level content appears to be the strongest correlation I have observed.


Correlation with USD File Size

I also tested USD files with different sizes/complexities.

Larger USD files appear to increase the probability of missing components.

However, the impact of USD size appears to be significantly smaller than the amount of existing content in the level.

Based on my current testing, the approximate relationship is:

Existing Level Content > USD File Size

in terms of impact on the probability of the issue.


Tests I Have Performed

1. Level Size / Existing Content

Test Result
Load USD into an empty level Issue frequency significantly reduced, but still occurs
Load USD into a level containing many Static Mesh Actors Issue frequency increases significantly
Increase the number of Static Meshes in the level Higher probability of missing USD components

2. Collision Settings

I tested different collision configurations during USD loading/import:

Collision Configuration Result
Generate simple collision (e.g. Cube) Issue still occurs
Generate complex collision Issue still occurs
Do not generate collision Issue still occurs

Therefore, the issue does not appear to be directly related to collision generation.

3. Rendering State

After the USD models were created, I also tried resetting/refreshing the rendering state of the generated models.

The issue still occurred.

4. Editor vs. Packaged Build

The same USD file and loading code were tested in both environments:

Environment Result
Editor / PIE No issue observed
Packaged Build Random USD components may be missing

Runtime Loading Code

The relevant runtime loading code is:

AUsdStageActor* StageActor_Root =
    GetWorld()->SpawnActor<AUsdStageActor>(
        AUsdStageActor::StaticClass(),
        FVector::ZeroVector,
        FRotator::ZeroRotator
    );

if (StageActor_Root)
{
    StageActor_Root->GetRootComponent()->SetMobility(
        EComponentMobility::Movable
    );

    StageActor_Root->AttachToActor(
        root,
        FAttachmentTransformRules::KeepWorldTransform
    );

    FString CachePath =
        TEXT("/Game/DP_Runtime/BPs/BP_USD/USDAssetCache");

    USDAssetCache = Cast<UUsdAssetCache3>(
        StaticLoadObject(
            UUsdAssetCache3::StaticClass(),
            nullptr,
            *CachePath
        )
    );

    if (USDAssetCache)
    {
        StageActor_Root->SetUsdAssetCache(USDAssetCache);
    }

    StageActor_Root->SetSubdivisionLevel(1);

    StageActor_Root->SetKindsToCollapse(18);

    StageActor_Root->SetFallbackCollisionType(
        EUsdCollisionType::Cube
    );

    UE::FUsdStage UsdStage = UnrealUSDWrapper::OpenStage(
        *FullPath,
        EUsdInitialLoadSet::LoadAll,
        bUseStageCache,
        bForceReloadLayersFromDisk
    );

    if (!UsdStage)
    {
        UE_LOG(
            LogTemp,
            Error,
            TEXT("[StepEditorDiag][UsdImporter] Failed to open USD stage. Path=%s"),
            *FullPath
        );

        StageActor_Root->Destroy();
        return;
    }

    UsdUtils::SetUsdStageMetersPerUnit(
        UsdStage,
        DesiredMetersPerUnit
    );

    UsdUtils::SetUsdStageUpAxis(
        UsdStage,
        EUsdUpAxis::ZAxis
    );

    // This uses the already-opened and already-configured stage.
    StageActor_Root->SetUsdStage(UsdStage);
}


Test USD File

I have attached/provided the USD file used for testing:


Expected Behavior

When the same USD file is loaded at runtime, all valid USD components should be created and displayed consistently.

The result should not depend on whether the application is running in the Editor or as a Packaged Build, nor should unrelated content already present in the level cause valid USD components to disappear.


Actual Behavior

In a Packaged Build, some USD components randomly fail to appear after loading the USD file at runtime.

The missing components are non-deterministic.

The issue is strongly correlated with the amount of existing content in the level:

  • Small/empty levels → issue occurs less frequently.

  • Large levels → issue occurs much more frequently.

  • Larger USD files → issue frequency also increases, but less significantly than level size.

The same loading operation works correctly in the Unreal Editor / PIE.


Questions

Could this issue be related to differences between the Editor and Packaged Build, such as:

  • Cooked assets / asset registry

  • Runtime asset loading

  • Async loading

  • Component registration

  • Render resource initialization

  • Garbage collection

  • Resource allocation or memory pressure

  • Package/IoStore behavior

  • Shader/resource initialization

  • USD asset cache behavior

  • Differences in the runtime USD import pipeline between Editor and Packaged Build

In particular, I would like to know whether there are any known limitations or conditions under which UsdStageActor::SetUsdStage() may fail to create, register, or render some USD components in a Packaged Build, especially when the target level already contains a large amount of content.

Any suggestions for additional debugging or instrumentation would also be greatly appreciated.