1
\$\begingroup\$

I am developing a clone Minecraft for the purpose of study. I am working with Java and LibGDX. I have read some other codes on web, and reading LibGDX tutorials and currently I could develop something on map using Perlin Noise, etc.

But my biggest problem is the render performance. I splitted my map in chunks, as Minecraft does, but even with few elements on screen (2.000 blocks) the FPS drops to 20 by second on Desktop. Even if I not looking for any block.

My logic is that:

  1. Main() calls Region.draw() to draw all loaded region chunks (currently about 16 chunks);
  2. Region.draw() calls each Chunk.draw() to draw all blocks on each chunks, about 128 blocks (total 2048 blocks).

I really do not see reason to performance be poor like that. I read that small things like that send a lot of instructions to GPU, like each vertices coordinates, etc. and it make sense. But Minecraft do thinks even more complicated like that and works without lag on my PC. I could simulate, on Minecraft, a render of 51.522 blocks without FPS issues. So I think that there are some method to avoid upload my blocks each time to GPU, and just call draw on it directly (I don't know if I am on right direction).

I'm studying 3D game development currently, and I have a similar problem on Unity (lot of objects, low performance).

What I missing?

My current code

My current render with 20 FPS:

\$\endgroup\$
1
\$\begingroup\$

Are you optimizing the geometry at all? Cull the unseen blocks and faces and combine like faces together so instead of four blocks side by side rendering eight triangles, you combine the four into one face, so only two triangles. This is called Greedy Meshing and I would highly suggest that you look into it. I also wrote a little something about this here, however, it is pretty outdated and juvenile compared to an Actual Greedy Mesh generator.

My other recommendation is to use "Chunks" like Minecraft does, and mesh this chunk into a single model, therefore you have only a single draw call instead of other deprecated ways of doing it, like rendering each block individually.

Good luck on your project. I had a lot of fun on my little voxel game.

\$\endgroup\$
1
\$\begingroup\$

One solution that is used in voxel-based engines is to compact zones of blocks into bigger block-zones, thus reducing the draw calls.

Let's take a 10x1x10 surface of blocks. You could compact this into 1 single cube instance and send that information to the gpu, instead of sending 100 block's info.

Of course you'd need to loop the textures instead of resizing them, and you may bump into other problems, but I'll let you expand on that idea by yourself.

\$\endgroup\$
-1
\$\begingroup\$

That's pretty normal. The draw calls themselves affect performance a great deal. 2000 draw calls is simply way too many.

If you can't use instancing then you will have to somehow reduce the number of blocks you send.

\$\endgroup\$
  • \$\begingroup\$ This. In your picture i see two types of blocks: grass and dirt. If you have 300 grassblocks and 700 dirtblocks, just copy the geometry and texture information once to the graphics card for each type instead of 1000 times. Also, do you have any form of occlussion culling implemented? \$\endgroup\$ – Djindjidj Sep 26 '16 at 6:11
  • \$\begingroup\$ Adding to this answer is you'll probably want to extract all the vertices instead and combine boxes where it's possible to send less faces to the graphics card (what is known as run-length encoding). So if there is a full row of boxes that could just as easily be one long box for render purposes. \$\endgroup\$ – Mikael Sep 26 '16 at 7:21
-1
\$\begingroup\$

The problem is, you're maxing out what your computer can handle, calls wise.

Look for objects that don't need to be updated.

If you look at minecraft, there are a lot of weird quirks that have to do with not updating all the blocks, such as "BUDs".

It's up to you to decide what's important and what's not important, separate it into chunks that take advantage of the data types, such as 16x16x16 chunks. Only update chunks near non static objects, such as players; minecraft doesn't even update near water half the time.

It's up to you to optimize your difficult-to-optimize type of game. Either that, or build a supercomputer.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.