Why is UE4 so sluggish with 4200 cubes?

Minecraft can handle at least that many even with “Realistic Shaders” and whatnot. Why does UE4 choke in this same circumstance? Is there some sort of culling option I have to enable or?

Because I spawned a bunch of cubes with a top-down perspective. It would take about 20 screens to get from one side to the other. Everything flickered and popped. It was laggy like crazy. My “MEM:” is now 1,427. What gives? My cubes just have a base color material instance on them with a roughness value. No opacity or anything.

I checked ProfileGPU and it says that the major culprits are:

“ShadowFrustumQueries” in “BeginOcclusionTests Leaf Events” (3.39)

“PostProcessing” which is odd given the numbers literally don’t add up. The two that are above 0.03 are “BokehDOFRecombine#2” and “TemporalAA” which seems fine at a total of .77ms (2.12)

“AmbientOcclusionPS” in “LightCompositionTasks_PreLighting” (1.16)

“UEDPCTestLevel.LightSource_0” in “Lights” (2.39)

====
In Editor Stat Unit:

Game - 27MS
GPU - 80MS
The other two are below 10 and are thus “okay”.

Profiling out of the editor says: (Working on it)

This comes hot on the heels of this: Generating levels in Multiplayer? (And Instanced Static Mesh POPPING) - Blueprint - Unreal Engine Forums

Which was clearly not solved by switching to static meshes. Oddly.

…Answerhub literally is the bane of my existence. I clicked post. IT DELETED IT. ._.

tl;dr found this, asking the person who made it if they might help me.


Not a minecraft style game, thought the engine had occlusion so none of the cubes I couldn’t see would be drawn, blah blah blah please kill me.

Have you tried using ISMC in a BP for each group/section?
The BP will have to be updated if you want to modify them as you cannot add instances to ISMC from the object properties.
(Rama has a plugin on the forums to do this in editor)

Well I think you cannot compare Minecraft to spawning hundreds of blocks in Unreal Engine 4. I will just give you my opinion. First, Minecraft is a game written in different language, which does not mean much but it is good to point out. Second, I believe that in Minecraft, while you might think there are thousands of blocks, only visible sides of the blocks are rendered, while in Unreal you would have to set up that logic. Simply by putting hundreds of meshes into the level is far from Minecraft logic. As I said, that is what I think. If it would be so easy, anyone could do “Minecraft game” within few hours. Don’t blame the engine :slight_smile:

Sorry, yeah that was part of my paragraph that was deleted. And my original post linked in the OP.

I was using Instanced Static Mesh Hierarchical Component(s) to drive my original level spawning blueprint, The difference between it and the normal ISMC is that it culls. As far as I’m aware it’s just the better version.

Also you can most definitely add them manually whether hierarch or not. There’s a + button in the details panel o.O but I’m generating them using the “Add Instance” node so it doesn’t really matter much.

Minecraft is using Voxels to render its game, Unreal Engine 4 uses Geometry so although visually it might look the same, there’s a big difference in what the engines are doing.
4,200 cubes is actually 50,400 triangles and although this isn’t very high poly your performance depends on many other factors. The number of draw calls in the scene is going to be the biggest impact and that will change depending on how you’ve set these cubes up. If each cube has a unique texture applied to every face, then this would drastically affect performance. Also if each cube is simulating physics (because you said you spawned them) this will mean that your GPU isn’t doing the heavy lifting but instead your CPU is.

I’m curious why you’re spawning these cubes. Are you not trying to build out a world made of cubes? If you’re trying to create a minecraft like game, you’re using the wrong type of engine. Look for a voxel based engine.

From the sound of it, you’re new to UE4 and don’t yet understand what causes performance issues and how the engine works from a technical standpoint.

Edit: This post is a lie. I forgot to place a “Is Authority?” node and thus it was just running on both. I’ll keep testing and see what I can do.

Said Lie:

Updating this to mention that I just created a brand new actor which just spawns 4 cubes, 2 instanced static mesh components and 2 hierarchical instanced […] I set the actor to replicate and then used blueprints to spawn it into my level just by changing which actor spawned (switching from my LevelSpawner actor to “TestActor”) and it replicated. All of them did. So now I have a pretty good idea as to what the problem is.

The problem, and I’m willing to bet on this (jk I’m broke) is that Construction doesn’t replicate. So because I was calling the Custom Event via Construction (to previsualize the level while I was working on parameters) it didn’t replicate.

This isn’t a complete answer though. I still haven’t quite figured out how to remove popping. Once I do I’ll post it here.

I’d say that that’s fair. I don’t know how the engine works under the hood. For the most part I know what sorts of things should cause performance issues but with Unreal’s pretty bad documentation I find it difficult to learn by any means other than experimentation and crossing my fingers while Googling.

Currently I have no textures in my material files. Perhaps a material instance is just as bad though. I’ll check that out. I would definitely not EVER apply 6 different textures to a single cube haha. Unless I was going for something really specific that somehow couldn’t be done in a single texture + material which… I don’t think is a thing.

Simulate physics can’t even be turned on in a HISMC. I also have turned “Cast Shadows” off as one of the first things I tried.

Definitely not looking to make a minecraft like game. In this test it’s just a square “plane” of cubes. Trying to generate a level with cubes though. Mainly because they’re easy to use and small building blocks. I tried the “room generation” style and it just wasn’t what I was going for.

Ok so what exactly are you trying to accomplish with the scene? If you give me a better idea I might be able to help you figure out how to approach it. I’m no expert with the engine myself, but I have been a level designer/environment artist since 1999. Are you just wanting to create a system where people can build objects with cubes? UE4 should be able to handle 4,200 (why this number I have no idea) cubes without too much trouble.

As an experiment, I created two example scenes of exactly 4,200 cubes. In the first scene, all cubes are contained in a single FBX file meaning that they are seen as one static mesh inside UE4. As you can see, UE4 has no problem rendering this. I’m getting about 120fps on a Geforce GTX 780.

So as not to take up too much space on this page, I’m only linking to this screenshot rather than embeding it:

In the second scene, I imported a single cube and then duplicated it 4,200 times inside the editor so each mesh is an instance of the original.

This caused the FPS to drop significantly down to about 80fps but the devil is in the details:

You can see the same information in your scene by opening the console with the ~ key and typing stat d3d and then using your arrow keys to choose the D3D11RHI option. (don’t know why there’s more info in the instanced meshes readout)

You can see that by creating 4,200 instanced meshes the draw call (Create bound shader state time) goes up by almost exactly 4,200. The reason for this I believe is that it has to render each cube separately. Instancing meshes does help performance a bit, but when there are so many instances of the same asset, it will adversely affect performance…

^ With 200 cube instances + 1 Cube static mesh. Lighting is unrelated.

Also, not that it matters but it’s “GlobalConstantBufferUpdateTime” that goes up by almost 4,200. It might matter but it’s still a draw call so I don’t believe that it does.

I appreciate you taking the extreme amount of effort you have to help me. Would you have any ideas as to how I could solve this problem?

In case you missed it, this exists: Minecraft-Like Infinite Voxel World in Unreal Engine 4 - YouTube

In the forum thread he said that he made it possible by:

“I decided to use Instanced Static Mesh Components for the blocks, the game is divided up into chunks of at the moment 20x20x70 blocks where every block type has it’s own ISMC.” (That’s 28,000)

“The whole project s 100% blueprint with no C++ being used. I think this project is a great example for the power of blueprint.”

“This project profits greatly from the BP->C++ converter, which is not a surprise with having a SimplexNoise algorithm implemented in blueprint.”

“if I disable the BP->C++ converter and profile the game, the nodes that take most time are actually +, -, *, / BP nodes”

…Now when you look at a Voxel engine, although visually it looks like the world is built of thousands of individual cubes, what you’ll find is that it actually renders the world as one piece and when you break off cubes, its separating out that individual cube at that draw call so there are less objects being rendered than you would think. So its as if you were taking the single asset with 4,200 cubes and when you hit one, it swaps out the original asset and replaces it with the one cube missing and then loads a “giblet mesh” to give the visual of destruction. That way the draw call stays low.
I’m over simplifying, and again I’m no programmer so I don’t know the exact technical details but that’s the basic difference between a voxel based engine and a geometry based engine. Voxels are solid pieces whereas geometry is a wireframe with a 2D texture applied.

Minecraft isn’t built of cubes for a visual aesthetic, its built that way because more complex voxels (i.e. smaller cubes to allow for curves) would be incredibly system intensive.

So the screen shot is only showing one cube… are you spawning them all in the same location? It may be the method you’re using to create them that is causing the FPS hit, not the cubes themselves. That’s why I’m asking for a more detailed description of what you’re trying to accomplish.

Touche - I misread the line. It is most assuredly the GCBUT that goes up. I have no idea what each of those lines means but yeah, more draw calls = bad.

Well you have to understand that UE4 is a framework. You have access to the engine code and if you know what you’re doing, you could program the engine to do pretty much whatever you want it to. I’d be curious to know if the guy who made that mine craft world actually programmed in a voxel rendering pipeline. As I said, they behave very differently than geometry. That said, with the proper setup, you could probably do something very similar using geo if you set up level streaming and use visual tricks to get better performance.
Whoops, I’m answering as I read your post and it said he used blueprints to create the world so my guess is he just really knows what he’s doing. Like I said, I’m rendering 4,200 cubes without issue and if you were to set up level streaming you’d likely be able to get better results. Have you tried posting on his thread to see how he achieved his results?
As he states in his video he’s set up intelligent block occlusion which means he’s not rendering all blocks at once and he’s using dynamic loading of chunks which means the same as level streaming in that not all 28,000 cubes are visible or rendered at the same time. You can even see that the viewable area is quite small.

I’d suggest at the very least you download his project and start looking at how he set everything up.

On a side note, what is your hardware setup? CPU, GPU, RAM?
Try downloading the Realistic Rendering project scene and tell me what your frame rate is there.

Downloading it now;

Windows 10 64 Bit
8GB RAM
A8-5600K 3.6GHZ Quad Core
Radeon 270 GPU with mid 900 clock speeds.

I’m creating with the assumption (based on Steam’s Stats) that I’m the “Ultra” scenario and that my goal is to have my PC run the game on Epic Settings at ~80fps. Anything lower and I probably won’t hit my target audience. I don’t know that and I have testers but that’s my mindset atm.

Also he doesn’t have his project uploaded anywhere. He uploaded the packaged game but nothing of use. What I’m trying to do is generate a level that looks like this:

I have it working (as in it does look like that. Or it did before I mangled my blueprints >-> ) but the performance is pretty bad.


Everything seemed fine.

Ok so you’re trying to create a top down shooter and you want to build the level out of cubes? Why are you spawning them at all as mentioned in your first post? Wouldn’t you just be placing them manually in the scene? Also in the Realistic Rendering scene can you type Stat FPS and tell me what the frame rate is?

I have a feeling your low frame rate has something to do with the way you’re going about creating the level.

Although if you wanted to achieve optimal performance, what I’d do is make a dozen or so different solid wall pieces and just flip and rotate them to make up the level. I’ll show you what I mean in a minute… just making some food.

  1. ms to FPS is simple. I’m getting 14.43ms in that image which means… Wow. This actually doesn’t exist. What even. HOW. Anyway, if 60FPS is 16.65 then by really bad math I’d say it’s probably…

16.65*60 = 999 (1000ms per second)
14.43 * 69.3 = 999.999
So 69FPS

=====

I spawn them all because I’m generating them using an algorithm which makes use of random values so that players don’t see the same level twice. Placing them manually wouldn’t afford this.

How I generate the in that test actor is suuper simple.

That’s just a test. And it shows the same results as the way I generate the level normally (just without as much lag and easier to experiment with).

That’s a really good idea; to be honest I was originally going to do something similar but came across the method by which the game actually generates their levels and decided to port it over. I made the assumption that instances would be able to handle it but I think I’m long past that by now. I think I’ll do that (:

In my design documentation I initially wrote that it would be perfectly fine to have static levels as long as all of the dynamics changed (spawn point, enemy locations, items, ect.) but I’m a sucker for algorithmic generation. My original reason for even getting into said generation is because of Spelunky. I learned that it’s actually room based with tiles added and removed and so I tried making rooms in UE4 using like. 12 cubes in a single blueprint and sticking them together and then making an algorithm that placed those blueprints aaaaaand…

It crashed. Lmfao it crashed so hard. I immediately found out about HISMC and tried to make it work that way using meshes I made in Blender but it wasn’t clicking so I decided to use cubes to generate a level like Nuclear Throne’s and uh. here I am. Full circle on a tangent. I think that what you’ve proposed is the best of both worlds though. I can retain design control where it matters (what I wanted) and the world isn’t exactly the same in its geographical layouts. I was worried that I’d have to start generating them, recreating them in Blender, and then storing them in memory, blowing up the size of the game while taking time to model some (honestly) inflexible and boring meshes.

Anyway, thank you VERY much for all of the help you’ve given me. I think it’s time to mark this one as answered. :3 You’ve more than earned it!

Maybe you have an idea for this part as well?
Just ran into a problem. Tl;Dr how to fill in the gaps/outer walls?

My generation looked like this before:
Make floor. On place cubes set its XYZ to a Vector Array.
Get the min x, min y, max X, max Y, and do a for loop to fill in the locations with cubes if a cube wasn’t already there (vector array contains? Node). How would one do this in this situation? Specifically with a “floor panel” that isn’t uniform at all and rotates and translates… How do I even fit them together so that they don’t overlap? Coming up with one solution as we speak but idk.

Since they’re pieces that can be rotated I could get the 4 possible rotations and just build separate wall meshes for each side thag can be disabled based on whether it’s an exterior wall based on some check? Idk.

Overlap issue is covered by smart design probably. Flat edges with no weird jutting unless it’s an “edge piece” and only jut on the outside not the inside.

I’m sure I’ll figure it out. Yay sleeping. XD

Edit: edge pieces always go on the outside to make walls, sure. Then different inner pieces with built in walls that can rotate. Just have to work out how to prevent unwalkable areas. Eh hem. Tomorrow.