Best way to draw voxelized pyramid?

Started by
3 comments, last by Waterlimon 8 years, 4 months ago

Hello, in the past couple of days I have been thinking of a problem with voxels. Like if I make a pyramid shape, which has 4 triangles and quad as a base, not tetrahedron with voxels. Would drawing each "floor" or layer whatever you would call it, by using cubes with 5 sides be a good idea? Would there be drawbacks, when there would not be any kind of connection between some of the vertices? I guess this might lead to glitched graphics?

I am using pyramid as an example of a problem that I was thinking. For example lets say I have 2x2x2 cube, which could be represented by single cube, 6 faces. Then I add one 1x1x1 block so that it is sharing one face of the previous cube. Now I would need to add only 5 faces and let the z-buffer hide the 1/4th of one of the faces that is behind the 1x1x1 cube. Now I would have 11 visible faces but I am just wondering if there is some draw back using this kind of method. Maybe mobile devices wouldn't like redrawing parts of the area again and again?

What I am trying to achieve is trying to optimize the mesh at least a bit, while maintaining the ability to actually modify the mesh. I feel like if I tried to actually triangulate the whole mesh, it becomes quite hard to maintain the ability to add / remove cubes to the already existing mesh vs just trying to find as big quads as possibly to present one single surface despite having part of the surface overlapped by other voxels.

Thank you in advance.

.

Advertisement

I currently have a similar problem. I have an app that draws some fractals, one of them is Menger Sponge. To keep things easy to code I made it out of many cubes. At later iterations there is a staggering amount of faces that will never be seen. At the 3rd iteration there are 8,000 cubes which my phone handles fine (Nexus 5, 50+ fps) but the next iteration there are 160,000 cubes which makes the fps drop to about 20 - which was sort of ok but now I've attempted to add shadows which it really can't deal with with that much stuff going on.

Depending on your model you can optimize it a bit. I briefly tried a voxel based version of my own using points instead of cubes and for that I was able to work out if a voxel is visible or not and if it isn't I removed it from being drawn. I effectively hollowed it out. My model was 8 million points but once hollowed it was simply the points on the surface and it runs really well (until I started carving it to higher iterations of the Menger Sponge.

If you have neighbouring information you could work out how many visible neighbours there are and choose an appropriate 'cube' - e.g. a 1 faces cube when there are 5 neighbours, 5 faces when there are 1 and so on as you suggested.

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

It looks like my own train of thought is pretty close to something called greedy meshing if I understand the greedy meshing correctly that is. It seems to generate bit more vertices for pyramid kind of shape, but I suppose it is better to do it in the way of greedy meshing, rather than creating partially visible faces.

The greedy meshing could possibly work in reducing the geometry of Merger Sponge as well, at least a bit. Looking the cube after 2nd iteration where there is 1 big hole, and 9 small ones in one face, the front face could be drawn with 4 vertical rectangles and 4 horizontal. Although I am not sure what the result would look like, since there would be 4 places where the rectangles would overlap each other, but at least it would reduce the geometry a bit to 8 quads per outer face. On deeper level of recursions, you wouldn't be anymore able to draw whole face length rectangles unless using some alpha channel to create partially invisible faces, but that would be more like a hacky approach rather than a good solution, and would it really work that well, I have no idea since that is just something that came to my mind when I saw the picture what the Merger Sponge looks like.

Your thread inspired me to try and improve the performance of my own app. I got it to use 65% less vertices/faces, which when I start with 5.7 million that's a great improvement. The way I did it was to have 'cubes' as before but not in the sense that they have faces etc, just abstract cubes. then I generated neighbour information for them. Finally pass them a vector of vertices and just ask them to add their own vertices to the list. They can then check if they have a neighbour in a direction, if so they just don't add vertices for that side. I will take a look at that greedy mesh method too.

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

The primary drawback with that method, is that while the number of vertices drawn goes down, the number of fragments/pixels processed goes up (assuming you do hidden-face elimination which is the most important optimization here!)

Reducing to boxes never decreases number of fragments drawn. In practically all situations, it will drastically increase their amount.

Doing this would only make sense if doing this vertices-for-fragments trade results in net performance increase.

One possible scenario would be far-away chunks - where each voxel takes just few pixels on screen, shading is cheap because you dont even need textures or proper lighting at extreme distances, and further you dont need to be able to easily edit those chunks because theyre too far for such things to matter.

So, the disadvantages in a normal voxel grid scenario with high fragments-to-vertices ratio:

-Overall performance significantly decreases because theres vastly more fragments to shade (even with early depth eliminations and whatnot)

(the problem is hidden face elimination. Reducing to boxes is a limited form of hidden face elimination. Its better than the naive "just render many boxes" approach, but much less effective than complete per-voxel hidden surface elimination.)

-Cost of modifying object increases (need to recalculate the 'optimized' boxes)

-No flexibility with per-voxel/per-vertex changes (like how minecraft renders its lighting with some per-face shadow texture things IIRC). Also you cant make nonlinear transformations on the voxels because this will detach box faces and vertices from each other spatially (with normal voxels there are only vertex-vertex connections as you say)

The first one (that its a highly less effective form of hidden surface removal) is the most relevant here (discussing performance).

The conclusion would be that AS LONG AS you do not 'break' normal hidden surface elimination, this kind style of optimization helps (still the other disadvantages apply):

-you can apply it to the 2D surfaces surviving hidden surface elimination only, instead of 3D voxel regions (like you seem to have decided to do)

-you can apply it to 3D voxel regions, if most of the resulting box is visible (not hidden)

And if you DO decide to still use it, heres a performance tip for making it practical:

Perform hidden surface removal on the boxes! Only replace a voxel region with a box, when some faces of the box can be removed such that most of the resulting box surface is visible (not hidden).

Like you could split your pyramid such that each layer is formed by 4 thin and long boxes, with the 'inside' faces removed/hidden. That would be very close to an optimal mesh.

o3o

This topic is closed to new replies.

Advertisement