Cooked build shows low-res mips only on some ISMs (ISM inside PLA inside Level Instance)

Hello.

In editor everything looks correct. In cooked builds, some InstancedStaticMeshComponents render with very low-res mips.

Using "r.Streaming.FullyLoadUsedTextures 1 ", the same objects become perfectly sharp, issue seems to be that texture streaming never gets correct primitive/texture usage for those ISMs.

The ISM is part of a Packed Level Actor (PLA), which is then placed inside a Level Instance.

Only ONE/SOME of the ISMs under that PLA have wrong mips; other nearby actors/meshes stream correctly. Other ISMs inside the same PLA works correctly.

Debug steps tried:

  • When using show bounds,we don’t see bounds around the problematic LI area
  • Being “UT_GroundDebris_01a_Albedo” one of the textures not streaming, using the command “InvestigateTexture UT_GroundDebris_01a_Albedo” when standing by it shows the following output:

[Image Removed]

Note the “Wanted Mips” staying low and the first reference being a static one with very small OnScreenSize*.*

The same command in editor shows:

[Image Removed]

Note WantedMips, DynamicReference being the correct one, and OnScreenSize.

  • Patching the engine based on: [Low res mips only on certain [Content removed] and

InstancedStaticMesh.cpp

void UInstancedStaticMeshComponent::ApplyComponentInstanceData(FInstancedStaticMeshComponentInstanceData* InstancedMeshData)
{
...
// Restore the texture streaming data.
StreamingTextureData = InstancedMeshData->StreamingTextureData;
#if WITH_EDITORONLY_DATA
MaterialStreamingRelativeBoxes = InstancedMeshData->MaterialStreamingRelativeBoxes;
#endif
#endif // WITH_EDITOR
}

void UInstancedStaticMeshComponent::ApplyInheritedPerInstanceData(const UInstancedStaticMeshComponent* InArchetype)
{
check(InArchetype);
PerInstanceSMData = InArchetype->PerInstanceSMData;
PerInstanceSMCustomData = InArchetype->PerInstanceSMCustomData;
NumCustomDataFloats = InArchetype->NumCustomDataFloats;
if (StreamingTextureData.Num() == 0 && InArchetype->StreamingTextureData.Num() > 0)
{
StreamingTextureData = InArchetype->StreamingTextureData;
}

#if WITH_EDITORONLY_DATA
if (MaterialStreamingRelativeBoxes.Num() == 0 && InArchetype->MaterialStreamingRelativeBoxes.Num() > 0)
{
MaterialStreamingRelativeBoxes = InArchetype->MaterialStreamingRelativeBoxes;
}
#endif
}

InstancedStaticMeshComponent.h:

virtual void ApplyToComponent(UActorComponent* Component, const ECacheApplyPhase CacheApplyPhase) override
{
UInstancedStaticMeshComponent* ISM = CastChecked<UInstancedStaticMeshComponent>(Component);
ISM->PreApplyComponentInstanceData(this);
ISM->StreamingTextureData = StreamingTextureData;
#if WITH_EDITORONLY_DATA
ISM->MaterialStreamingRelativeBoxes = MaterialStreamingRelativeBoxes;
#endif
// The Super::ApplyToComponent will cause the scene proxy to be recreated, so we must do what we can to make sure the state is ok before that.
Super::ApplyToComponent(Component, CacheApplyPhase);
ISM->ApplyComponentInstanceData(this);
ISM->UpdateBounds();
IStreamingManager::Get().NotifyPrimitiveUpdated(ISM);
}

....
FInstancedStaticMeshComponentInstanceData(const UInstancedStaticMeshComponent* InComponent)
: FSceneComponentInstanceData(InComponent)
, StaticMesh(InComponent->GetStaticMesh())
{
StreamingTextureData = InComponent->StreamingTextureData;
#if WITH_EDITORONLY_DATA
MaterialStreamingRelativeBoxes = InComponent->MaterialStreamingRelativeBoxes;
#endif

}
UPROPERTY()
TArray<FStreamingTextureBuildInfo> StreamingTextureData;
#if WITH_EDITORONLY_DATA
UPROPERTY()
TArray<uint32> MaterialStreamingRelativeBoxes;
#endif

[Attachment Removed]

Steps to Reproduce
InstancedStaticMeshComponent is part of a Packed Level Actor (PLA), which is then placed inside a Level Instance (LI).

In cooked build: only the ISMs under that PLA/LI path have wrong mips; other nearby actors/meshes stream correctly.

[Attachment Removed]

Hi Federico,

Thanks for reaching out about this issue. Can you submit your proposed fix via a pull request on GitHub? That is our preferred method for reviewing code changes from licensees. Please let me know if you have any further questions.

Cheers,

Tim

[Attachment Removed]

Hi Tim,

Thanks for your answer.

To be clear, the fix was just an attempt, but we didn’t succed in solving the issue. We’re still looking for help in finding a solution.

Anyways I opened a PR: https://github.com/EpicGames/UnrealEngine/pull/14338

Please let me know if you need anything else from our side.

Thanks,

Federico

[Attachment Removed]

Hi Federico,

Sorry, I misread your initial post. I will still need to review the code a bit with the dev team and get back to you with some updates. I should have some answers for you by next week, but let me know if you need them sooner.

Cheers,

Tim

[Attachment Removed]

Hi Federico, I am still trying to get you a proper answer. In the meantime, I saw a licensee resolve a similar issue with Fast Geo-related texture streaming. Are you using Fast Geo in your game? Here is the ticket for reference: [Content removed]

[Attachment Removed]

Hi Tim.

Yea, we’re using Fast Geo. Seems like the solution proposed there actually helps and we’re not seeing low res textures around anymore.

Will keep you updated!

Does “s.StreamableAssets.UseSimpleStreamableAssetManager=1” have any performance/unknown implications or is it fine to turn on?

[Attachment Removed]

Hi Federico,

Glad to hear that this option is helping you. It is actually required that you enable that cvar in order to use virtual texture streaming with Fast Geo, as pointed out in our official World Building guide: https://dev.epicgames.com/community/learning/knowledge\-base/r6wl/unreal\-engine\-world\-building\-guide (see the Important Changes in 5.6 section). Therefore, I assume the performance impact will be negligible, but I advise you to still profile your changes to understand the impact of using the streamable asset manager. I hope that clears up your concerns; let me know if you need any further clarification.

[Attachment Removed]

Hi Tim,

Thanks again.

We were seeing another issue where required mips were always the highest ones now.

We found this: FSimpleStreamableAssetManager required mips - #3 by RichMawlow

and applied the changes from CL 43827369, as stated in the post.

Apart from this, seems like everything is working good now.

Thanks for your support!

[Attachment Removed]

Ok, thanks for adding that as an extra callout in case other people come across the same issue. I will close out the case then

[Attachment Removed]