While rendering voxels appears easy at a glance ("they're just cubes!"), there are actually many, many, trade-offs one has to take into account, mainly depending on the intended visual style and scale of the individual voxels.

Ultimately it depends on what your goals are; try not to set them too lofty!

Since there is no way to write about all possible methods, this article will talk about things in general, linking elsewhere for more details - if possible.

Hardware Acceleration

Talking about rendering is impossible without talking about hardware acceleration and thus GPUs (Graphics Processing Unit); so let's do that real quick!

The primary purpose of a GPU is to calculate/compute/solve a massive number of highly similar problems1 "all at once", by splitting up large sets of data into smaller groups, which are then worked thru by a large number of tiny processing units2.

Historically, the problem in question was mainly rasterization (and later fragment processing) of triangles via GPUs on dedicated graphics cards.

These days GPUs are much more general purpose and are used in so many applications that we won't bother listing them here.

To hopefully nobodies surprise, rendering voxels is such a massively parallel process, that not using GPUs would be very (very) silly.

How do we gain access to the awesome processing power of GPUs? Well...

Graphics Programming APIs

Unfortunately, directly accessing GPUs usually isn't possible, since:

  1. Operating systems must share GPU resources between multiple processes.
  2. There are a multitude of hardware vendors and thus GPUs, not to mention drivers!

As such, we are forced to use a Graphics Programming API... of which there are several.

However, since you are most likely to want to run your program across many platforms and hardware combinations, we can safely ignore a whole bunch of them and choose from one of three APIs:

  • To get started as fast as possible, with no regard as to how modern GPUs and their drivers work, use OpenGL.
  • To be future-proof and get as much performance as possible out of your GPU, use Vulkan.
  • If you're okay with proprietary stuff and are targeting mainly Microsoft Windows & Xbox, you can use Direct3D via DirectX.

Graphics Programming Libraries

If you find the previously mentioned APIs too burdensome or low-level, there are various rendering abstraction libraries available, using the lower APIs as backends:

Only well-known libraries directly exposing 3D graphics are listed.

NameLanguageBackend/s
wgpuRustvarious
bgfxC++various
OGREC++OpenGL / Direct3D
raylibCOpenGL
libGDXJavaOpenGL(ES)

Note:
Some of these libraries have bindings for other languages, so check out their documentation before rejecting any!

Windowing Abstraction Libraries

Creating a surface to actually draw into is, due to the many platforms that exist, terribly annoying, so it's best to leave it to a windowing library...

NameLanguagePlatforms
SDLCvarious
GLFWC++various
SFMLC++various
WinitRustvarious

General Rendering Methods

There are, in general, two families of volume rendering methods:

Within the former family of surface extraction, the volume is pre-processed into a surface-only representation, such as a mesh or a point-cloud, which can then be rasterized (eg: triangles ⇒ visible pixels).

In the latter family of volume marching, the volume itself is marched through via raycasting/raymarching (eg: visible pixels ⇒ voxels).

It is possible to combine both families for more complex techniques and effects.


Aspects of Lighting

Lighting is commonly defined via some variant of the Bidirectional Reflectance Distribution Function...

TODO: Create article just for lighting?

General Culling Methods

Depending on the method you choose to render voxels, you may have to cull your geometry, so as to not overload your GPU with drawcalls & geometry.


References


1

Commonly referred to as embarrassingly parallel.

2

Modern GPU's have literally hundreds, if not thousands, of 'units' running in parallel; the exact mapping of 'units' to 'threads' differs per GPU vendor.