I run into 2 Issues when using HierarachicalInstancedStaticMeshComponents in the cooked version of our game. Both Issues don’t exists in the editor version and both issues appears very similar: Whole blocks of instances disappears depending on the position and especially the rotation of the camera. Sometimes they are flickering without moving the camera.
Issue #1: Wrong order while initializing
When loading the cooked content the HISM Component uses the unsorted instances to initialize the instance buffer.
I found the problem in UHierarchicalInstancedStaticMeshComponent::PostLoad()
:
First the AsyncBuildInstanceBufferTask ist started. In FAsyncBuildInstanceBuffer::DoWork()
it checked to use the remap table:
bool bUseRemapTable = Component->PerInstanceSMData.Num() == Component->InstanceReorderTable.Num();
But after that in PostLoad()
the BuildTree()
Function is called that will fill the InstanceReorderTable.
I fixed this issue with a simple reordering in PostLoad():
void UHierarchicalInstancedStaticMeshComponent::PostLoad()
{
Super::PostLoad();
// For some reason we don't have a tree, or it is out of date. Build one now!
if (StaticMesh && PerInstanceSMData.Num() > 0 && (!ClusterTreePtr.IsValid() || ClusterTreePtr->Num() == 0 || (NumBuiltInstances != PerInstanceSMData.Num()) || GetLinkerUE4Version() < VER_UE4_REBUILD_HIERARCHICAL_INSTANCE_TREES))
{
UE_LOG(LogStaticMesh, Warning, TEXT("Rebuilding foliage, please resave map %s."), *GetFullName());
check(!IsAsyncBuilding());
StaticMesh->ConditionalPostLoad();
BuildTree();
}
if (CVarASyncInstaneBufferConversion.GetValueOnGameThread() > 0)
{
UWorld* World = GetWorld();
if (World && World->IsGameWorld() && PerInstanceSMData.Num())
{
World->AsyncPreRegisterLevelStreamingTasks.Increment();
while( InstancingRandomSeed == 0 )
{
InstancingRandomSeed = FMath::Rand();
}
AsyncBuildInstanceBufferTask = new FAsyncTask<FAsyncBuildInstanceBuffer>(this, World);
AsyncBuildInstanceBufferTask->StartBackgroundTask();
}
}
}
Issue #2: Clusters are culled
This issue only occurs at our big map with world composition and world origin rebasing but I don’t know the reason for this. I tracked down the issue to SceneVisibility.cpp OcclusionCull()
.
There the result of RHICmdList.GetRenderQueryResult(PastQuery, NumSamples, true)
is sometimes NumSamples == 0
althrough the instances should be visible. I tried to use r.HZBOcclusion
with values 0, 1 and 2 with exactly the same results.
As a workaround I solved the Issue with setting r.AllowSubPrimitiveQueries = 0
but I think the performance could be worser than.
UE 4.10.4 (Launcher Version and self compiled Version)