Voxels in the BGE - Download Available

Hey. I was messing around with an idea that I had a couple of days back for implementing voxels (kinda; the implementation in the BGE’s just cubes) into the BGE, and the results are pretty encouraging.

UPDATE:


:smiley:

This has a lot of implications for both Minecraft-like block based games, as well as games with a large amount of place-able and interact-able geometry.


(I asked if anyone wanted to guess to see how I achieved it; it was a stupid question. :p)

Okay, so here’s how I did it. Usually, other engines don’t just cull the blocks so that blocks behind other blocks aren’t drawn, and neither do they only draw the blocks in such a way so that only the block faces that are visible are drawn (though that does do a huge speed increase). They also draw the blocks in as few batches as possible - they merge the blocks added into a single mesh.

Unfortunately, the BGE can’t do this - neither can it add or delete faces from meshes. However, you can manipulate the faces that are there. So, what I did was create many, many cubes in a single object (they don’t have to be cubes; they can just be detached faces). Then, I wrote a function that I call Flatten, which takes other objects’ meshes and applies their vertex values to the source mesh (the cube-packed ‘fodder’ object that you see below).

So the idea is that the game first places a lot of objects (cube placeholders, really), and they are all set to be invisible. Then, the game adds the faces for the cubes, which are all in one object to draw in one batch. Finally, the Flatten function moves each of those vertices (and UV and normal values) to align to each vertex in each invisible cube placeholder, ending up with the result you see above. The remaining faces are pushed down 100000 BU so that they’re outside the camera’s view frustum (and so, the camera won’t draw those faces).


Here’s the Flatten script for those who are interested. There’s one major upside to this - it runs very quickly. :slight_smile: Unfortunately, there are also two downsides to this method.

  1. All faces have to have the same material and texture. Since the faces aren’t individual objects, you can’t replace their mesh, and changing materials for faces isn’t supported by the BGE (as of yet). Fortunately, the script copies UV values, so different blocks would indeed appear different, as long as they were all on a single texture image.

  2. It requires that you have enough faces available in your game to supplement each ‘chunk’ of land. The larger the chunk, the more faces each ‘fodder’ object must have to cover it. This makes the game start up slowly if your chunk data’s large (not even add the mesh slowly, just starting up and loading the polygons into memory is kinda slow). Fortunately, you only have to have one chunk data, as you can use LibNew to make a new mesh from the first one. Currently, it’s pretty usable. :slight_smile: So… Anybody want to try an open-source Minecraft from this? :rolleyes:

If you want to download the demo, you can do so here.

Did you come up with your own method for culling blocks that’s optimized for the way Minecraft works?

Nope. I’m not really doing any culling, really.

You changed the capping of the frames per second from 17fps to 60fps. :slight_smile:

Merging meshes maybe? :eyebrowlift2:

@Linkxgl - Haha, funny. No, you could see on the 17FPS screenshot that the Rasterizer’s working extra hard.
@Mobious - No, I didn’t (Wish it was possible to merge meshes, though). But you’re closer.

Just a wild guess.

You only have the exposed blocks in the the scene. When a block is destroyed, you look it up in a 3D array and add any blocks that were hidden by it to the scene.

Haha, yeah, I realized that right off the bat when I saw the screenshots :stuck_out_tongue:

I don’t know… Arrays?

@Mobious - No, though something similar would probably be done when destroying and creating of blocks is implemented.

@Linkxgl - Nope.

Update!


9521 blocks before a certain technique is applied


9521 blocks after a certain technique is applied

:smiley:

Well, if I try to cheat a bit… the blocks are converted to faces (flattened blocks?), so there are no faces on the back of the visible blocks…

Nope, though that would be a good idea. I actually tried that, and the results weren’t that great. :confused:

that actually adds more objects to the scene…
You hit a button and run a function to remove all objects that are not visible?

No, all of the objects that shouldn’t be visible (behind and under the hills, for example) are. :S

maybe you set all objects that are not needed to no collision? ^^

EDIT
whoops… just saw that the rasterizer is decreases drastically… so I don’t think it has something to do with no collision settngs xD

Maybe you merge objects before starting the engine into some clustered objects?

Are the blocks instances of the same object?
Did you take a screenshot and texture a flat plane?
Did you get a new computer?
Are you a witch? (Corollary: Do you way as much as a duck?)
Do you have empties at each block position that only add blocks if they’re visible?

That’s all I got.

Ok… I just made a simple Test with my Block Level Editor. There I also have the function to merge objects together and seperate them afterwards.
I created about 3800 Cubes. And started the bge. My rasterizer takes more than 50%.
Then I merged all Objects together and the rasterizer took only 2%.

I am interested in what you came up… :slight_smile:

If it’s not a python method where you’re removing occluded objects, I would guess that you’re using the Occlude physics type, which basically does the same thing.

Or is it a shader based solution? <- that would be interesting.

Either way, the difficulty in making minecraft goes beyond just spawning a large number of cubes. Even if it were possible to approach the scope of visible cubes in minecraft, there’s a whole sea of multi-player code that actually makes the game tick, and that’s the difficult part.

@ Magnum Opus - No, I’m not a witch, and this is the same computer that I’ve been using for years.
@ Goran - A shader based solution would probably be the fastest and best out of what I’ve tried. Yeah, the multi-player part would be pretty difficult…

I feel like a jerk for making people ask me now. XD

I updated the first post with the ‘solution’. It’s pretty inefficient, but at the same time, maybe it’s workable.

EDIT: I managed to work LibNew into the equation to make new meshes from the pre-made ‘fodder’ object - the logic drain went up, which isn’t good. It might help if I could figure out a good way to cull the blocks…

So this works kind of like my terrain systems, only you use place holders as a map, instead of a library. Does this mean that the landscape is not editable afterwards (I don’t know if they are in Minecraft…).
Very clever…

The terrain should be editable with some Python.