Attaching large geometry without performance issues

This is what a basic world looks like riught now, keep in mind that this is more than one chunk though. This world contains a 16x16 grid of chunks (so its 256 chunks).

Also i should add, it does not render any blocks out of view.

My point is not in culling, but that several techniques are required, and probably tweaked. You can’t just create a world and throw it at the scene, unfortunately. A lot of gaming is smoke and daggers. Tricks, if you will. It all boils down to maths.

Wouldn’t removing and adding the nodes result to the same problem but multiplied? since i would be modified the nodes so much?

IMO you have a pretty high object count for your scene, it says 2554 objects, i would expect a number near to the number of chunks…
But object count aside, this screenshot is not very helpful, if your upload time is too high, it means you are sending too many vertices, even if the size of your chunk sounds reasonable the algorithm you are using to merge the blocks may not be good enough.

1 Like

The lag spike is caused by the upload of the geometry on the GPU memory. JME just gives the data to lwjgl or whatever back-end you use to feed opengl with it. Opengl is not multi threadedable, you can’t have a rendering thread and an “upload the data to the GPU” thread.
You’ll have to wait for Vulkan to do that I guess, but it will never come in opengl.

So here what I’d try in order:

  • make sure your blocs are not cubes… Probably obvious, I don’t know the details of your implem, but if your mesh is made of assembled cubes you are doing it wrong and you are wasting a lot of vertices.
  • find the best trade off between chunk size / perf.
  • use impostors: distant land should be simplified meshes. An impostor can cover several chunks even.
  • if the uploads occur during a “change of area” you could consider fading out the screen and fading in when the upload is done. Loading screen…
  • Use a GPU with a killer bandwitdh…
1 Like

The blocks are not made of cubes, my old system used that and i only got 1 fps. Right now i have a custom cube face enumeration that stores the vertices of each face respectively. This is then combined into a big mesh for the chunks.

Ok I was just checking, since it’s a common pitfall of box worlds dev.
Did you try to profile your app when the freeze occur? We are making the assumption that it’s the GPU upload that freezes it but it can be a GC freeze or things like this. In that case you’d have more options to fix the issue.

You should do at least the greedy mesh algorithm. I thought these articles were very nice when I looked into how to make “box worlds”. Meshing in a Minecraft Game | 0 FPS

Alright little progress update, I decided to rewrite the entire code that generates the mesh and its actually going suprisingly well. I looked into what @RiccardoBlb said and found a mistake that lowered the object count to right about the number of chunks (which seems to be good). Now i’m running into one issue though, texture mapping the blocks is a real pain and i cant seem to get the textures to align properly with the blocks.

Can anyone take a look and see if they can spot a mistake with it? I can’t seem to figure it out.
Here’s the code for chunk mesh generation: hastebin
Here’s the BlockType class: hastebin

This is the texture image: Blocks

That’s currently about everything that’s being used to generate the mesh, thanks in advance if anyone is willing to help me out! (And also to anyone who helped out previously :smiley: )

1 Like

set your mag filter to nearest on the texture. there are many posts about this problem. its not quite as simple as a one liner, usually, though, as you will encounter.

1 Like

Have you thought about using a texture array instead of an atlas? You can safely store up to 256 full size textures in one texture array if you use opengl 3.3+ and have enough vram and there is no texture bleeding.

1 Like

When I started beta testing Spoxel I was astonished at the number of people that have cards that don’t support opengl 3.3. You get a ton of people that expect to be able to play it because “X” game works just fine. I probably get a bit more of that because of the demographic Spoxel seems to attract (aka younger with no disposable income >.<).

but you can have two contexts. and upload your data in the second context.

then what?
you ping pong with the contexts? not sure it’s practical.

Well, opengl 3.3 makes things easier because the implementation requires the hardware vendor to support at least 256 layers, but you can actually use texture arrays in opengl 3.0 aswell, it’s just a little more complex because you don’t know beforehand the number of layers that are supported by the hardware but you can read the GL_MAX_ARRAY_TEXTURE_LAYERS property and split your textures in multiple arrays if their number exceed the maximum.
Then you can write a shader with multiple texture arrays and use defines to disable the ones you don’t need.

I think it’s quite reasonable to expect the players to have hardware made in the last decade, but for sure you are right, it depends on the demography, there are probably people that still use opengl 1 hardware (or drivers) and got very upset when minecraft dropped support.

From what I saw I wasn’t able to attach multiple textures to a mesh, the only way I could find was to use one big texture and then define the coordinates for each block, is there a way to do it seperately? (That would honestly be much better)

Also, damn this conversation is pretty interesting. I didn’t expect this many people to join in and talk about it this extensively, pretty cool.

Yes, you have to write a custom material and shader

Thanks everyone so much for helping me figure this out! This was really one of the best experiences I’ve ever had on a programming related forum, you all rock!

After some tweaking, rewriting and rewriting my mesh generation over and over again I have managed to improve my performance massively. From about 40 fps with a 16x16 chunk grid to a whopping 1600 fps!

There’s still a few things I have to figure out, mainly what causes this weird little yellow effect:
EDIT: This was caused by me accidentally picking the wrong MinFilter for my texture atlas. I had to set it to NearestrNoMipMaps to fix the issue.

And how to make faces different colors like I used to have (to make it look more 3D), right now it looks really flat. I haven’t figured out how to apply it to this way of generating the mesh yet. This is what it looks like closeup:

You can clearly see that it doesnt really look as 3D as before anymore so I still have to figure out a couple things here and there. But man, thanks to every single one of you guys! I didn’t expect this question to go such a long way and get such a massive discussion started :smiley:


Nice work

1 Like

1 Like