4

I am doing some research into how feasible it is to use voxels to represent largish (256x256x256 voxels) battlegrounds with destructible terrain for server-hosted multiplayer games. Only one battleground will exist for any game at a time. However, to be able to broadcast rooms and changes to their terrain, I am trying to find an algorithm that can group the voxels into the fewest rectangular blocks as possible.

As a simplistic example, if the bottom half of the level was completely filled with voxels of one type and the top half with voxels of another type, the level should be divided into two blocks, one representing the bottom half of the level, and the other representing the top. Ideally, this algorithm should be able to run in real time so any deformation in the terrain could be accounted for on a per-frame basis and broadcast to the clients. This should enable the clients to render the terrain efficiently without worrying about duplicating terrain destruction logic in the clients.

Here are the approaches I have tried and the problems I find with them. The block counts reported are for filling a 256^3 space by randomly dropping more than 4,194,304 "EARTH" voxels into as far close to the bottom as they can go for the randomly selected (x,z) coordinate. Only "EARTH" blocks are counted.

  • Octrees: very fast, but if I split at the middle of a space, it produces a ridiculously large number of blocks (800,000+).
  • k-D trees splitting to minimize weighted entropy after a split: slightly slower than octrees, but much fewer blocks (~350,000).
  • k-D trees splitting to maximize information gain ratio: twice as fast as than the previous k-D trees method, generating far fewer blocks (~167,000), but still to slow.
  • k-D trees splitting to minimize Gower similarity: very slow, but generates fewer blocks than any other k-D tree method (~155,000).
  • Greedily grabbing the largest subset of non-intersecting, largest volume blocks available when considering each unclaimed "EARTH" block as the block's defining point: even threaded, this algorithm is obscenely slow (~16 minutes with 8 threads on an 8-core system), but it generates the fewest blocks of all (<65,536).
  • Greedily grabbing the largest subset of non-intersecting blocks while treating a block's dimensions as objective scores to maximize: much slower than the other greedy approach and generates a few thousand more blocks, too.

Considering that a maximum acceptable number of blocks is one block per (x,y) coordinate to represent a single column, only the greedy volume is having results that could be considered even close to optimal.

I do not know how to compute the minimum block count without using a brute force approach that never ends, so I do not know whether it is possible to do better than the greedy volume approach. Furthermore, I do not know how I can make it any faster. Can anyone give me an algorithm to try or at least point me in the right direction? I'd like to another way to approach my problem if this cannot be done any better.

user4157124
  • 2,809
  • 13
  • 27
  • 42
sadakatsu
  • 1,255
  • 18
  • 36
  • Perhaps you approach the problem by using normal image compression algorithms? Ie split it into 256 bitmaps (where each pixel represents a type of block, and each bitmap represents a layer of blocks). Then you can compress each bitmap to something like a PNG for transmission? – Simon Todd Jul 19 '13 at 14:58
  • I think it would be more efficient to transmit the location, dimensions, and types of the blocks. I have some test files, and they're pretty small. In addition, that means that the client will have to figure out how to represent the information in those bitmaps as 3D geometry, which is the same problem I'm trying to solve here. – sadakatsu Jul 19 '13 at 15:03
  • I'd say compress only 2D layers via quadtrees or other algorithms you tried, and provide all set of them without ever attempting to shorten the number of layers. See, battleground seems to be like "ground below, air above" with walls or other structures with upper layers smaller dimension-wise than lower layers (like a pyramid). This will lead 3D algorithms to get stuck over slopes, as you need to align the block boundaries to axes. – Vesper Jul 19 '13 at 16:01
  • I've tried a new method: k-D trees, splitting to minimize the entropy and then maximize the volume of one side of the split. This approach is much slower than the other k-D tree methods and generates ~360,000 blocks. It's no good. – sadakatsu Jul 19 '13 at 19:27
  • @Vesper I've now tried a few approaches using your idea. The best block count I get is ~303,000 using the greedy volume (area?) grabbing approach. It still takes too long and generates too many blocks for rendering. – sadakatsu Jul 19 '13 at 20:02
  • 2
    (if its a plane terrain so) i would compress the height axis with RLE compresion and set the air voxel as background color. (RLE compression/decompression is really fast) that should save a lot of memory (enough to forget about trees). according to terraain complexity you can go from 256^3 -> 32*256*256 – Spektre Sep 16 '13 at 17:29

0 Answers0