@Kirl
What's been holding voxels back? In my opinion it was a combination of memory footprint, processing power and lack of support from Graphic card vendors.
Nowadays theres more than enough processing power, the above engine is completely software rendered but there are raycasters implemented entirely on the GPU with an order of magnitude in increased power.
Memory footprint is no longer an issue. The sparse octree traversal algorithm is like the google search engine of voxel traversal. Only a tiny subset of the world needs to be physically defined. Any vast empty regions become compressed into a single integer. On the other hand any vast regions entirely made up of a single colour are also compressed into a single integer. This leaves a lot of room for fine detail where its needed. Traversal is also an order of magnitude faster than the meathod I used here. So you have massive terrains with a level of detail not possible with polygons, using an algorithm that runs at real time on todays hardware.
There's nothing holding it back anymore.
@Peeps who are having render issues
The problem is that the initial quadtree subdivision is performed according to the aspect ratio, which forces each block to be a perfect square...
// quadtree subdivision...
int S = Canvas.Width / max(Screen.AspectX, 1);
for (int y = 0; y < Screen.AspectY; y++)
for (int x = 0; x < Screen.AspectX; x++) QuadTree(x*S, y*S, S);
While further quadtree subdivisions are always into 4x4 squares. Which gives a loss in precision if the initial squares are not powers of two...
s = s/2;
QuadTree(x, y, s);
QuadTree(x+s, y, s);
QuadTree(x, y+s, s);
QuadTree(x+s, y+s, s);
I think the solution is something like this...
temp = s/2;
if (temp*2 == s) {
s = s/2;
QuadTree(x, y, s);
QuadTree(x+s, y, s);
QuadTree(x, y+s, s);
QuadTree(x+s, y+s, s);
} else {
// sub divide properly...
}
but its not that easy. The method I use for subdividing requires getting the greatest common divisor of the width and the height. But these are perfect squares. The greatest common divisor is the same as the size. Besides this is an important recursive function I would rather perform the extra overhead outside of this. And ensure that the initial squares are always powers of two. Anybody know how to do that?