Voxels

I realized I’m horrible at posting, mostly because I’m overthinking it and keep working on a draft until it doesn’t feel relevant anymore. However, I’m putting a fair amount of time and effort into a personal game at the moment and I’m in the happy screenshot phase so lets try something new: Month in review, in screenshots!

I’ve been working on this game in Zig for a while now and I might write more about that experience at some point. The game is written from “scratch” in the sense that I rely on no game engine or bigger third-party library. I’ve worked on all types of systems, from a Vulkan and Metal backend to gameplay systems. This month I’ve been revisiting the voxel raycaster and world generation. This is probably my 5th iteration of a voxel raycaster and I now have something that I feel might be a bit more friendly for incorporating actual gameplay elements.

Voxels

This is basically where I started this month. A simple chunk of terrain. I’m very happy with the hot-reloading I’ve implemented which lets me actually change the code that generates the terrain on the fly.

Voxels

Look, tiles!

Voxels Voxels

Not a real graphics post without a few bugs. One of the most frustrating things I’ve been dealing with this month is rounding errors.

Voxels

Initial attempt of getting some coloring going. Above was a very failed attempt of the typical mountain slope grass flats…

Voxels

Pushing it all a bit further, I got something that got the feeling of scale I was looking for. This was a map of 1024x1024x1024 voxels, all same resolution. Also a lot of shader and lighting magic to hide the ugly alias you get by trying to render more voxels than the monitor has room for :), including fog and TAA.

Voxels

I love this screenshot, it gives a pixel art vibe but it’s actually voxels. Maybe an art style I will revisit.

Voxels

Next step was starting to look into streaming and LOD. Days of race conditions and invalid caches. One highlight is the LRU cache I setup for the GPU. I pre-allocate a big block of memory and allocate chunks into it using an allocator I wrote based on Sebastian Aaltonens OffsetAllocator. Using a linked-list I can easily track all allocations and evict least recently used.

Voxels

Initially I did LODs per chunk, which looks a bit funny as chunk boundaries are typically very clear, so I experimented a bit with discrete voxel-wise distances. Nothing concrete from this yet but it might allow for some cool effects in the future.

Voxels Voxels

Next natural step was of course to make voxels smaller. This sadly showed how inefficient my terrain generator is and how boring procedural terrain becomes without a lot of tweaking, so this is an area I will revisit in the future for sure.

Voxels

Now I feel a bit done with the terrain for now so I went back to basics. Perfect opportunity to play with some fun SDFs and I can really recommend Inigo Quilez articles. This feels like a great view while I continue making some improvements of the chunk handling for other aspects than just rendering.