Click the image above to get to the demo
Voxels are a way to display 3D data that dates back to the days before 3D accelerators became popular. Voxels (VOLume piXELS) don’t store models as triangles or polygons, but instead
function much like a traditional bitmap, only these bitmaps have 3 dimensions, much like a video (where the third dimension is time). Today you find them mostly in medical scanners.
This demo however doesn’t use real voxel data (we get to the rendering in a second, this is just about the data itself), but a variant where there is only a two dimensional bitmap and a third channel
that contains the Z position of the pixel. The benefit is that there’s a lot less data, but there can only be one color for each pixel at all depths, which makes it well suited for terrains, but not so
much for anything else. This is the way most games used voxels and it even has found its way into modern games as "parallax mapping" for textures, which is really just voxel rendering
implemented as a shader.
The rendering itself isn’t real voxel rendering either. That would require a 3D buffer that’s currently not available to filters. Instead, a series of perspective renderings is just put
on top of each other, so these voxels don’t have any side surfaces, just the top. At steep angles this would pose a problem, but since we’re looking at it from (roughly) a 45 degree
angle, it works well enough.
Code-wise this is really just a simple evolution of the MarioKart demo and if you
want to know how the perspective rendering is done you should look there.
The only real difference is that this uses 5 different perspective renderings, stacked upon each other. Then there’s a bit of fairly simple brightness/contrast adjustments: The bottom layers
are made a little darker and the alpha channel gets higher contrast and a brightness adjustments depending on its height. The top ones are made to display only where the alpha
channel is entirely opaque/very bright, while the bottom ones pretty much ignore the alpha channel.
Frankly, I didn’t expect this to work, primarily because the filter is very, very long. It needs to process around 30 operations to generate each frame (4 operations for each of the 5 layers + 5 for the texture + 3 for the texture transformation)
, and that’s with a 768×512 surface. It’s not very difficult to understand, but there’s simply a lot of processing needed and the speed at which Firefox renders this is nothing short of amazing.