3d: Part IV

By Alias and MA*SNART

 

In Ma Snart's 3D articles, he describes many methods of making 3D polygons, textures, and such, the things that can be accelerated with 3D cards. There are many ways of drawing 3D objects, and thankfully, they are not all polygons. The one I am going to talk about in this series is the voxel method. Ma Snart mentioned these vaguely, saying he preferred them, but he's not planning on covering them, so I will.

Alternate 3d method: Voxels

 

 
A voxel is hard to describe, but I have one analogy that may work: in 2D space (screen space) we have PIXELS which are approximations of area. They are square, arranged in a grid, and can be set to any color possible.

A voxel, on the other hand, is an approximation of volume, in 3D space. They are arranged in 3D grids (more on this later) and can be set to any color OR transparent. This way, we can make a volume-based drawing of an object, as opposed to recreating the surface of the object, as we do with polygons.

The big analogy here is the 3D / 2D counterparts. For example, a cube is the 3D counterpart of a square, a line is the 2D counterpart of a plane, a sphere is the 3D counterpart of a circle, and a pixel is a 2D counterpart to a voxel.

Now we can really get into voxels. As I said, a voxel is an approximation of volume. The most effective way to simulate a volume is with a cube-shaped volume. This way, when your 3D grid is drawn, there are no gaps. However, drawing a cube is horribly slow, and drawing enough of them to simulate a small item would bring any Cray XMP to its knees, let alone actual PCs! So, we have to fudge a little. We cannot draw a full cube, but on any of the 6 sides of a cube, it looks just like a square. So, where there should be a cube, we will draw a square that is large enough to completely cover the visual area a cube would cover. With that in place, we can draw a voxel knowing that it will look alright, and that there will be no gaps between pixels.

By the way, if your voxels are too small you will get gaps between them, which are quite visible - and very ugly. If you experience gaps, increase the size of your voxels one or two, and see if that makes a difference. I have seen many people try to do just points for their voxels - it doesn't work. You have to use squares larger than one pixel, typically 3-5 pixels wide. Another good idea is to pick odd numbers for sizes, that way, the voxels will be evenly centered, instead of being biased half a pixel in one direction. Biasing is a serious problem, especially in small maps, as two adjacent voxels may go in opposite directions and leave an empty spot, or gap. As I cannot possibly emphasize enough, GAPS ARE BAD.

 

Voxel-based Rendering...

 
 

Alright, now we have the basics of how to draw a voxel, how do we make our really cool 3D object? Before we do that, we have to understand 3 different types of voxels: landscape, list, and grid. Landscapes are the most popular and the most useless. They are simply height maps of a ground level. The landscape that is drawn from them usually looks very realistic. We will not be covering landscapes yet. List and Grid voxels are basically the same thing, just organized differently. A grid voxel map is a 3-dimensional array that holds points in a 3D grid. When the voxel is drawn, every point is translated, projected, and drawn (or not drawn) in and according to its color. For the example in this series we will set color #0 to be transparent, and any voxels in color 0 will not be drawn. As for list types, this is a list of the x, y, z, and c values of each voxel. For this method, color 0 will be visible and drawn. List voxel maps are generally considered more versatile as they can be larger and more complex and faster, but they have the drawback of being more difficult to create and program.

The first example we will do is a grid voxel. First, we have to dimension our voxel (16 x 16 x 16 in this example; you can make yours whatever you want, should you choose to write your own code) and fill it with proper values. This is one of the biggest challenges in voxel technology, because there are not many ways to represent a 3D grid on a 2D screen very well. MA SNART has, conveniently enough, created a program that solves this problem elegantly. It is easy to use and powerful - a great combination! Have a look at voxeler.txt in the zip file for the documentation. Voxeler.bas is the actual program. It requires no special libraries.

Now we have to translate and project the voxels. Code for this is already in place in the editor (press D to turn on, < and > to rotate) so make a cool voxel and have a blast! The actual code is in there somewhere but MA SNART said he hadn't organized the code well, and, er, he was right. If you can separate the program into something more modifiable, send it here. Oh, yes, and if you make a really cool example voxel, send that here too!

Just for those of you REALLY curious, the voxels are not truly projected. They are translated in an isometric projection, but I will not cover that until article 3.

Included in the ZIP file are several example files. Loading them is easy, just look in the editor documentation for instructions on loading. Saving is equally easy, just be sure to send us your best work. A list of example files is in voxeler.txt.

Next time we are going to do alot - firstly, we are covering list voxels and landscapes, as well as a thorough revamp of our current editor, rewritten for flicker-free DirectQB. 'Till then!

Explain to alias that you already wrote a renderer that does 50,000 voxels/sec on a P100 here.

Download the voxel editor!

Back to Top