Download

Warehouse Viewer (100K+ duplicated mesh to render) - Performances

Hello everyone,

I need your help!
I would like to represent a warehouse in 3D but having some issues for the optimization (I don’t need the graphics quality to be photorealistic like, neither 60 FPS)…

Basically, I’ll have two simple models (rack and pallet), that just need to be spawned multiple tim and stay at their position (no move, no animation, no shadow).
The only thing I need to be able to do is raycasting on the pallets (each pallet will contain some information that I need to retrieve on raycast).

Here is what I’ve done:

  • No collision / overlap / physics
  • No shadows
  • 2 materials (which are just two different unlit colors)
  • Instanced the static mesh
  • Disabled ticks on my actor which creating my instances

I tested it (you can find the code below), and I have 5 FPS for 100,000 instanced of my model (which is 670 triangles, 1300 vertices, 70kb).
It seems very low to me (the model is simple), do you have any idea/advice that could enhance this result ? I would like to get a 20/30 FPS…

Here is my code:



AGenerationDirector::AGenerationDirector()
{
	PrimaryActorTick.bCanEverTick = false;


	// Defaults parameters value
	ObjectsCountX = 10;
	ObjectsCountY = 10;
	ObjectsCountZ = 10;


	USceneComponent* SceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
	SceneComponent->SetMobility(EComponentMobility::Movable);
	RootComponent = SceneComponent;

	
	// Retrieve the mesh of the bomb and define it as the root
	//static ConstructorHelpers::FObjectFinder<UStaticMesh> MeshAsset(TEXT("/Game/Geometry/Meshes/1M_Cube"));
	static ConstructorHelpers::FObjectFinder<UStaticMesh> MeshAsset(TEXT("/Game/Geometry/Meshes/Rack/Rack6"));

	if (MeshAsset.Succeeded())
	{
		StaticMesh = MeshAsset.Object;
	}


	// Retrieve the materials
	static ConstructorHelpers::FObjectFinder<UMaterial> Matterial0Asset(TEXT("/Game/Geometry/Meshes/Rack/Rack_M0"));
	static ConstructorHelpers::FObjectFinder<UMaterial> Matterial1Asset(TEXT("/Game/Geometry/Meshes/Rack/Rack_M1"));

	if (Matterial0Asset.Succeeded())
	{
		Material0 = Matterial0Asset.Object;
	}

	if (Matterial1Asset.Succeeded())
	{
		Material1 = Matterial1Asset.Object;
	}


	InstancedMeshes = CreateDefaultSubobject<UInstancedStaticMeshComponent>(TEXT("InstancedMeshes"));
}

// Called when the game starts or when spawned
void AGenerationDirector::BeginPlay()
{
	Super::BeginPlay();


	if (StaticMesh != nullptr)
	{
		// Set Static Mesh
		InstancedMeshes->SetStaticMesh(StaticMesh);

		// Set Materials
		if (Material0 != nullptr && Material1 != nullptr)
		{
			InstancedMeshes->SetMaterial(0, Material0);
			InstancedMeshes->SetMaterial(1, Material1);
		}

		for (int x = 0; x < ObjectsCountX; x++)
		{
			for (int y = 0; y < ObjectsCountY; y++)
			{
				for (int z = 0; z < ObjectsCountZ; z++)
				{
					FTransform InstanceTransform = GetTransform();
					InstanceTransform.SetLocation(FVector(x*300.f, y*150.f, z*200.f));

					InstancedMeshes->AddInstance(InstanceTransform);
				}
			}
		}

		InstancedMeshes->AttachToComponent(RootComponent, FAttachmentTransformRules(EAttachmentRule::KeepWorld, false));
	}
}


I’m not an expert in 3D modelling so I took a model from the Sketchup library and converted it to OBJ, maybe it’s too big for what I’m trying to achieve… ?

Thank you all for your help!