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]