Some time ago, in my first ever blog entry, I mentioned that I was interested in the concept of hexagonal pixels:
Exploring utterly frivolous hexagonal pixel rendering technique… virtually no practical value in it but it’s just sticking in my head and I’m finding myself wishing that hardware could support hexagonal pixels and triangular shading rather than the more convential square bilinear approach.
Now, after more than two-and-a-half years, I finally got around to trying out the technique on some real images!
[ NOTE: in an attempt to avoid ambiguity I will herein use the term texel to refer to a color sample from a regular source image, or texmap, and the term hexel to refer to a color sample from a hexmap, an image specially prepared so that its samples are arranged in a honeycomb pattern. ]
The following two images represent the two most common methods for displaying, zooming and resizing a standard bitmap. To people accustomed to using image editing software or playing 3D games, the visual characteristics should be very familiar.
The first is your classic unfiltered or nearest-neighbour approach, where each texel shows up as a square. It’s cheap, common and ugly, and generally what texture mapping looked like in the good ol’ days of software based 3D engines.
The second uses standard bilinear filtering, a technology now available even on the cheapest graphics hardware, but still relatively expensive to implement in software [which is why bitmaps in flash animations often look more like the first image than the second].
Hexagonal texels, or hexels
Now compare with the following images, which were created quite differently, using a specially prepared hexmap [instead of a regular texmap]:
Instead of appearing as squares on a grid, the unfiltered version now consists of tiny hexagons layed out in a honeycomb arrangement.
The difference between filtered texels and filtered hexels is a little more subtle; instead of a soft stripey appearance we get a kind of dotty look, as though the image is being viewed through a bumpy screen. Although there is an extra sharpness there, there seems to be some additional noise as well.
The difference between a texmap and a hexmap is that a texmap’s values are taken from points on a regular square grid, whereas a hexmap’s values are taken from points on a triangular grid – Note here the relationship between the underlying grid and the honeycomb arrangement of the hexels themselves.
When displaying an unfiltered hexmap, the nearest-neighbour approach is used, whereby the color of a destination pixel is determined by the nearest hexel only. To display a filtered [or smoothed] hexmap, the three surrounding [nearest] hexel values are interpolated [equivalent to Gouraud shading].
I wanted to try this is because in the real world small objects tend to pack most efficiently in a honeycomb formation [rather than a grid], and I wanted to know if a similar sort of effect could be observed when using such a layout for image storage. The result was pretty close to what I expected, in that the technique seems to lend itself best to organic shapes, whereas sharp, straight edges tend to acquire a slightly dotty appearance.
[ Perhaps D&D players will have an instinctive understanding as to why this is the case ;) ]
Note that the two very different maps were created to be [as close as possible to] the same overall size. The dimensions of the regular bitmap are 128×128, whereas the dimensions of the hexmap are 120×136.
Whether or not I will use these methods for anything beyond experimentation I don’t know yet, but I’m quite pleased with the results so far. It’s possible that current generation 3D hardware could be used to render hexmaps at super speeds, but [ until I get around to investigating programmable shaders ] I can’t say for sure. If it can be done without a performance hit, it might be worth doing for the novelty factor.
And it’s just nice to try something different now and again…
You can download a 430K demo [Win32 only] of filtered and unfiltered hexmap rendering, and allows you to toggle between regular texture-mapping and hexmapping.
NOTE: I am not claiming to have invented the concept of hexels, nor to be the first to implement it – I do this kind of stuff because it is fun and/or challenging, and I don’t mind at all if that means I spend a lot of my time reinventing the wheel… I’m used to it ;)