Closed hermesonbf closed 1 month ago
IIRC, meshes are culled per-actor? That would mean separate actors for chunks are good. There is some overhead in having lots of actors. Also, replication (if you're using that) is probably more suited to replicate properties per-actor. I don't use replication myself so take that with a grain of salt.
best way to check this would be to do some stress tests, but my guess is that 1 actor has bit more overhead than 1 component. Again, it depends. It always depends.
All the examples I found on the internet of people creating "Minecraft like" procedural games with chunks in Unreal use actors for chunks so I guess it is safer to use them instead of 1 actors with N components inside, maybe later in development this latter method will lead to regret with something related to multiplayer Idk, apparently individual chunk components inside a single actor do not have individual relevancy so if the server spawns 30 chunks inside this one actor it will be sent to all the clients by default or extra logic will have to be created to handle this while with individual actors they only replicate creation / destruction based on distance to each client automatically, that's just a hypothesis on why actors may be better for something like this
I have done some stress tests on the past, it's not perfect but it gived me some insights:
Category | PMC | RMC | RMC + 1 Polygroup | DMC |
---|---|---|---|---|
Creation | 961.723800 | 300.668200 | 293.594500 | 1052.288700 |
Mesh Setup | 2019.371700 | 2870.816100 | 2363.835600 | 1506.531400 |
Total Draw Calls | ~20k | ~20k | ~20k | ~20k |
Mesh Draw Calls | 11.600 | 11.300 | 11.800 | 11.250 |
Memory Usage | 68,337.48 kb | 37,634.53 kb | 39,079.67 kb | 57,556.23 kb |
Frame Time | 60 ms | 23.5 ms | 40 ms | 56 ms |
Game Time | 50 ms | 10.7 ms | 40 ms | 40.8 ms |
Draw Time | 40 ms | 22.5 ms | 7.40 ms | 33.93 ms |
RHIT Time | 22 ms | 14 ms | 14.5 ms | 19.83 ms |
GPU Time | 18.96 ms | 7 ms | 11.5 ms | 14.42 ms |
FPS Shipping | 22 fps | 128 fps | 68 fps | 48 fps |
Possibly has a memory leak problem which make this method inviable
Category | 10.000 |
---|---|
Creation | - |
Mesh Setup | 125,905 ms |
Total Draw Calls | 24745 |
Mesh Draw Calls | ? |
Memory Usage | Unknown |
Frame Time | 19.75 ms |
Game Time | 7.49 ms |
Draw Time | 11.28 ms |
RHIT Time | 11.05 ms |
GPU Time | 6.58 ms |
FPS Shipping | ? |
Category | RMC |
---|---|
Creation | 0.115900 ms |
Mesh Setup | 29,143 ms |
Total Draw Calls | 190 |
Mesh Draw Calls | 5.5 |
Memory Usage | 6,328.51 kb |
Frame Time | 8.33 ms |
Game Time | 6.02 ms |
Draw Time | 3.87 ms |
RHIT Time | 3.38 ms |
GPU Time | 2.41 ms |
FPS Shipping | 321 fps |
Category | RMC |
---|---|
Creation | 0.098600 ms |
Mesh Setup | 22.012700 ms |
Total Draw Calls | 187 |
Mesh Draw Calls | 3.5 |
Memory Usage | 1,646.33 kb |
Frame Time | 8.33 ms |
Game Time | 6.59 ms |
Draw Time | 4.17 ms |
RHIT Time | 3.58 ms |
GPU Time | 2.25 ms |
FPS Shipping | - |
Around 5ms
Around 3ms
With polygroups: around 5ms Without polygroups: around 3ms
Around 7ms
I noticed some things while doing the test, each section group is a draw call, so creating many sections in the same group will merge the draw calls (but I think they should have the same properties (visibility and collision) for that to work, not tested), but there is a cost for each section you add to the RMC, which can make it a little slow (29 seconds) when adding many sections (10.000) for one component. I Think draw calls would be a greater concern than the triangles, so the ideal is finding a sweet spot where you don't have sections that are not too big (to not make it slower to update) and neither too small (to prevent having many draw calls)
Also, the culling is per Primitive Component, so if you had only one actor which many components the culling would work normally
On the network side, I think it's pratically impossible to rely on the replication system if you want to replicate the terrain data it will spawn actors extremally slow
Suppose I want to spawn 16 x 16 chunks around the player in a multiplayer game similar to Minecraft, the chunks appear around the player in chunk meshes created by RealtimeMeshComponent, is it better to have 1 actor "ChunkManager" actor that creates / destroys StaticMeshComponents for the chunks inside itself or to create 1 actor for each chunk and create / destroy as the players move around in the world? I am trying to guess which method is more ideal for a multiplayer game since I guess coding in the wrong method may cause extra work to migrate the code to the correct solution later.