InstancedStaticMeshComponent->AddInstance Performance

Hi, iam just messing around with the InstancedMeshComponent and noticed that when i create 64x64 instanced, in blueprint its generates just fine in the construction script like 1-2 sekonds. But when i do the same in c++ in the constructor it takes like 12-15 sekonds. Any advice on this?

Not much without the actual source. You are probably doing it wrong. From my experience, C++ runs faster then BP.

Hi,
You should not be doing this in the C++ class constructor. C++ constructor is meant to set default values only. Your construction is happening during CDO initialization, and also every other actor of this class in your level is doing the same when you enter PIE or simulation, basically. Either create instances in BeginPlay() function or bind delegate to OnConstruction(). Not quite sure about the latter, but should work i believe.

I also experience a huge lag wen i click the actor in the the Editor. BeginPlay is no option here because i need the thing to be present in the editor

Code i use:



constructor: part
blabla loadmeshstuffetc....

DirtInstances->bCastDynamicShadow = false;
DirtInstances->CastShadow = false;
DirtInstances->SetMobility(EComponentMobility::Static);

InitializeLevel(15, 15);	

void ALevelActor::InitializeLevel(int32 SizeX, int32 SizeY) {
	FDateTime startTime = FDateTime().Now();

	DirtInstances->ClearInstances();
	FVector boxExtent = DirtInstances->StaticMesh->GetBounds().BoxExtent;

	for (int32 x = 0; x < SizeX; x++) {
		for (int32 y = 0; y < SizeY; y++){
			FTransform instanceTransform = FTransform(FVector((x * boxExtent.X) * 2, (y * boxExtent.Y) * 2, 0));
			DirtInstances->AddInstance(instanceTransform);
		}
	}

	FDateTime endTime = FDateTime().Now();	
	FTimespan executionTime = endTime - startTime;
	
	UE_LOG(WTDebug, Log, TEXT("Generationtime: %f seconds"), executionTime.GetTotalSeconds());	
}

void ALevelActor::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
	Super::PostEditChangeProperty(PropertyChangedEvent);

	FName PropertyName = (PropertyChangedEvent.Property != NULL) ? PropertyChangedEvent.Property->GetFName() : NAME_None;

	if (PropertyName == TEXT("bGenerateNow"))
	{
		if (bGenerateNow == true) {
			bGenerateNow = false;

			InitializeLevel(fieldSize.X, fieldSize.Y);
		}
	}
}


when i use the bool it also takes ages to generate on the fly when i changed the Size

I also have a 64*32 (2048) instanced static mesh for a screen object, one instance per pixel. I think some things might be turned of automatically when handling the instanced static mesh trough the editor, either that or
maybe there is a way to add a amount of instances in one call, rather then adding them one by one slowly extending the container resizeing moving and reallocating?
Then the loop would just set the actual values of the instances instead of creating them?

maybe…

Hello guys.
Sorry for bumping old thread but looks like I have the same problems here.

I have created actor that uses instancing to place meshes in level. So it have instanced static mesh component and generates instances in loop to place them in x, y or z coordinates.

I tried 2 version of that, c++ and blueprint, and it looks like blueprint version works faster )))

1st is BP, 2nd is C++.

https://youtube.com/watch?v=75eNsJLdn2M

BP doing everything in construction script.
c++ version uses both OnConstruction and PostEditChangeProperty functions, but even with PostEditChangeProperty it takes large amount of time to recalculate instances.
But in my opinion c++ it works maybe 10x times slower.
Mathematics of placement loops it the same - increment loop index, multiply location shift on that index and set everything into instance transform.

So, is there any objective reasons for such performance difference?

Bump! Anyone?

LUL, just had the same issue, but already saw the problem, because Unreal was loading all instance transforms into the editor and I think this transform array is actually on the gpu already and to make it visible in the editor and on the cpu it writes it back with 100 slower speed, but this is just a guess from a total noob.
To solve this, define your ISMC like so:

UPROPERTY(VisibleDefaultsOnly)
UInstancedStaticMeshComponent* ISMC;

The VisibleDefaultsOnly will hide the Instances and Transforms when you click on your Actor, which is also the case when using BPs. You can make an interface to chose a Mesh or you click on your ISMC and select it there, but make sure you didn’t populate the array already by a huge number. Then switch back to your Actor(Instance) where the Instance dropdown with your 10k instances and their transforms is not visible anymore. Then you change your other values and voila, everything will be calculated in lightning speed.

1 Like

You are my hero! Thank you very much!