Minecraft imitation

Hi,

I’m a bit new to the 3d programming and so i tried to imitate Minecraft as a first step. But I even got stuck in the beginning. My first attempt was/is to create a world with many different blocks (boxes with different textures). As a test i created a 10x10x10 box made of 1000 boxes . This worked fine. Then i tried 20x20x20, but the fps got below 30. Here is my code:



[java]int SIZE = 20;

Box b = new Box(Vector3f.ZERO, 0.5f, 0.5f, 0.5f);

Material mat = new Material(assetManager, “Common/MatDefs/Misc/SolidColor.j3md”);

mat.setColor(“m_Color”, ColorRGBA.Blue);

for(int x = 0; x < SIZE; x++) {

for(int y = 0; y < SIZE; y++) {

for(int z = 0; z < SIZE; z++) {

Geometry block = new Geometry(“blue cube”, b);

block.setMaterial(mat);

block.setLocalTranslation(x, y, z);

rootNode.attachChild(block);

}

}

}[/java]





I don’t know how to improve the fps. The only thing i know is that Minecraft can manage much more boxes then 20x20x20 and it has textures and lots of other things that are missing in my first attempt.



Mabey there is a trick to manage the boxes differently, I’m glad for every help i can get.



thank you all,

markusm1s

Well 20^3 is 8000, 8 times as much as your 10 by ten grid.



I think minecraft does not do it this way.

It might have a 20^3 cube, but it moste certainly does not render all of them unless nessecary. Whic it will never be.



What you want to do is probebly figuring out, what of there 8000 can you see with your cam.

Do not render the other 7999 boxes :stuck_out_tongue:

Thank you for your answer.



I thought jME renders only the shapes that are in view.



How can i decide boxes are in view and what do I do with the others ?

Shall i always remove/attach the boxes which get into/out of view?

You can just set the CullHint of the Spatials so they are not rendered.



And if you want to know how to decide what to render and what not… Culling is what you are searching for. There are many different ways to do that so feel free to search for a way you like. (:

1 Like

Great hint, thank you

I’m working on a similar block building game with elements similar to minecraft, and it’s much harder than you would think. Culling is the way to go, especially if you’re planning to move blocks around.

What you mentioned is something like a visibility system, these are static and the only current engine I know of , that uses them is the source engine.



Jme only does frustrum culling, so basically everything to far left right up down out of the camera is not renderd, however it is not capable of organizing the data in it. (Just imagine you have some transparent blocks. since all blocks use shaderd materials they could look like everything imaginable, so it would be impossible to do such thing without additional informations regarding the use.



Short:

You need to think of an algorithm that reduces all unneeded cubes

maybee combines several identicall to only one mesh to reduce object count (much objects are always a bottleneck though large is somewhere around 3000 depending on hardware)



Then you need to think of a system that reduces the rendering of not visible blocks further, however the reduction mentioned might already be good enough so you might be able to save working on this.

EmpirePhoenix said:
You need to think of an algorithm that reduces all unneeded cubes
maybee combines several identicall to only one mesh to reduce object count (much objects are always a bottleneck though large is somewhere around 3000 depending on hardware)


Then how does MineCraft do it? There are hundreds of thousands of blocks on the screen at one time.

You quoted the answer: “maybe combines several identical to only one mesh to reduce object count”

since i’m actually trying to create a voxel-like map with the same idea, this is what i’ve done :


  • reuse your mesh in several geometry, if you got several meshes.


  • check for each voxel if one of the 6 sides of the cube is not occuped by another cube. In this case set a flag indicating that the voxel/cube is not visible. During the transformation from map to representation, set the culling for geometry of this voxel to "never", since it can not be shown. In may 100*100*3 map, this helped quite a bit, but should be even better for higher z.

  • combine several geometry into one : a method i used was to check how many cell/voxel at the same height / column had the same type (material), and replaced these with one geometry scaled along the y axis : a simple (and longer) cube. Thus i created 100 100*1*1 cube instead of 10000 1*1*1 (for one z). Please note that if at least one voxel is visible you should set the new geometry as visible.



regards
Guillaume
1 Like

Thank you all for your help !!!

I’ll certainly try all these things :smiley:

Just to add an information :

There was a related question on stackoverflow, with a nice 2d solution (this would already help), that could be extended to 3d :

http://stackoverflow.com/questions/1726632/dynamic-programming-largest-square-block



regards

Guillaume

JME3 now has a GeometryBatchFactory for all you box lovers :wink:

normen said:
JME3 now has a GeometryBatchFactory for all you box lovers ;)

However do note that its not a magic wand, you have to use it correctly to batch the blocks in spatial groups, not the whole thing many times.

One thing you can try is to combine a group of cubes into a single mesh avoiding the faces that are ocluded by adyacent cubes, but I think you’ll have to define your custom mesh or manipulate the vertex array of a Box object if it is possible.

Here is how i did it when i tried a minecraft clone, when i was in the draw phase of my code(after loading my section of the world into an array) i ran a loop that checked the blocks directly around the block i was drawing and drew only the ones touching air(later i specified it to only the faces of the block touching air or nothing) this basically left a large empty/non-drawn space under the surface and dramatically improved performance, although i didn’t go far enough to make the world dynamically generate or load as i walked so that may cause slowdown when you get into that portion of the code.