Multiplatform low-resolution voxel 3d engine. For losers, by losers.
Wikipedia: A voxel represents a value on a regular grid in three-dimensional space.
This project contains simple 3d data structures and code to support a graphics engine, along with some sample voxel structures and demonstration application.
Here's a quick overview of how the code represents voxel data
- A
Position
describes a point in 3d Cartesian space, with x, y, and z values. - A
Voxel
is aPosition
and an integer value. - A
Grid
is a collection ofVoxels
Then there's how to display these:
Translation
is a mutable form ofPosition
.- A
Camera
keeps track of where we're looking, by translating a grid to its local space. - A
Projection
converts a Position to a pixel location, given a Camera and a pixel size. There'sFlat
,Cabinet
, andPseudoPerspective
Projections. - A
UI
keeps track of the Grid, the Camera, and the Projection, and actually renders the result in a platform-specific way. The Swing UI implementation uses a variety ofSwingRenderer
classes, seen below.
You can run SwingWannabe, a Kotlin/Swing implementation that I'm using as my testbed. Run its main method from the IDE, or try ./gradlew swing_demo:run
on the command line. It has a selection of sample grids, along with projection and render mode selections.
Rotation Video tests (click to play)
Projection and Render tests (Click for larger views.)
One of the cool sample Grids is a heightmap where shades of gray are translated to height and color and shown as voxels.
Given this original heightmap:
The sample applicaiton renders the upper-left 50x50 pixels of the heightmap as voxels. As shown in the animations above, there's a number of render modes available. Shown here are filled circles, rounded-squares, squares, and "3d" squares.
And there's non-filled versions of the same shapes:
As you can see from the samples, this isn't a photorealistic engine. It's geared more for pixel-art and retro-style visuals, but allows for some nifty things, as the combinations of projections and renderers allow for very different looks.
Grids should be considered the smallest practical unit of animation. Voxels inside a grid don't move relative to one another. Grids can support adding and removing voxels, but a voxel should only be in a single Grid.
My expectation is that the camera will always be looking down the z-axis. The position of the camera may change, but not the direction.
This is a way to learn some little bits about 3d graphics while working in a simple space. And potentially it can be a good platform from which to develop some small games. Also helps me think about and write about the process from a developer's standpoint.
I chose the MIT license at this time. Please contribute back fixes you come across!