A personal take on voxel art to create a little scene in a quiet valley…
This article is also available on Medium.
Lately, I’ve dived into CG again. So far, I’ve explored to pretty extreme opposites: on the one hand, I worked on photorealistic rendering through my projects with Cali Rezo (first a short 1′-film, then painting showcases and even a virtual gallery!); on the other hand, I’ve modelled various objects in a low-poly style.
But there’s another kind of design I’ve been intrigued by for a while: voxel art. So I decided to have a go at it… but in a somewhat “personal” way.
Here is the short sequence I made to kick off my new “Voxelish” series! Make sure to watch until the end 😉
What is voxel art?
Voxel art is like pixel art, but for 3d. In 2d, the “unit” of your image is the pixel: images are made of little tiny squares, each with one colour, and all those squares juxtaposed next to each other form complex pictures. By stepping back and looking at the pixels from afar, the human eye naturally “blends” the discrete pixels into gradients and continuous shades to create the illusion of smoothness. This can be further helped by having the pixel colours progress gradually, and by essentially “smoothing out” harsh discontinuities. This is called anti-aliasing.
However, pixel art is about leaving those discontinuities be and even cherishing them to recover some of the early graphics aesthetics. Remember the old video games with flashy colour palettes and sharp edges? Well, that’s the sort of visual vibe pixel art wants to revive.
And you have a similar trend, in 3d, with voxel art. The goal with voxel art is to use “voxels“, i.e. 3d cubes, as the “unit” of your 3d scene… and so to build all of your models just by assembling cubes! This idea was especially popularised by the famous game Minecraft, in the 2010s, a sandbox/adventure game where the world is made only of cubes:
There are several well-known voxel artists nowadays: Ex Machina, Sir Carma, Ingen… and plenty more (check out the first link for a longer list)! All of them get their kicks abstracting reality through this particular design style and they make pretty amazing stuff 😉
“Voxelish”: inspired by… but not completely in-style! 🙂
Although I really like voxel art, I felt like I wanted to twist it to get something a bit more original. Also, I was really keen on sticking with the tool I know and love, Blender, rather than going for the usual soft for voxel art afficionados: Magicavoxel.
That’s why I decided to go for an in-between: I drew inspiration from the voxel art references I’d found, and in particular I looked at the colours they were using, but I eventually only “approximated” voxels. Basically, you can see in the renders above that the ground is made of cubes but that they may collide (so those cubes aren’t real “3d units”); the buildings and trees are made of groups of stretched cubes, but they are rotated so I don’t follow the voxel art rule where all “height layers” in your scene are aligned with one another; and finally: my little plane and boat are low-poly but not made out of voxels!
Note that the water and the smoke coming out of the boat’s chimney are more in the cartoon style.
All in all, my goal was to find my own style. I wanted something uplifting and quiet, a way to create a small scene that is born and grows in a tiny chunk of time. My project was indeed heavily inspired (and motivated) by the things I’d seen in voxel art, but I still preferred to be liberated from some of its constraints – that’s “voxelish”! 😉
About this render…
To create this scene, I used Blender’s EEVEE engine that allows for incredible real-time lighting and node-based shading. My process can be cut down in four big steps: modelling the landscape and “voxelising” it, adding the buildings and the trees, making the vehicles and the smoke for the boat, and finally animating those vehicles for the end of the sequence.
Modelling the landscape (+”voxelisation”)
Before actually diving into my pseudo-voxels, I first made a landscape with fairly basic 3d tools: namely, a simple plane and some displacement based on a texture.
This is very common practice: to create a terrain with some mountains and valleys, you can start off from a plane, subdivide it and then apply some displacement on it. The point is to have all the white areas be considered as “high altitude” and all the black areas be considered as “low altitude”:
Oftentimes, the black and white image we use can be generally by the computer using mathematical noise functions.
Note: for more info on this, you can check out a previous article I made on the well-known Perlin noise 😉
Here, I used Blender’s built-in “musgrave texture” that gives smooth large random areas:
This gave me a plane with bumps and cracks that I then edited a bit (with proportional editing turned on!) to have some mountains, hills or valleys:
Finally: the “voxelisation” step! For this, I took advantage of one of Blender’s latest features: geometry nodes. This new tool lets you create geometry (i.e. meshes) thanks to a node-based graph editor. There are countless applications (and Youtube tutorials) for this amazing tool, among which: specific styling (like here, the “voxel style”), procedural generation, deformation animations…
In my case, it was really great for swiftly placing cubes on my plane that automatically followed the geometry, and for which I could control both the size of each cube and the density of instances on the plane:
In terms of modelling, the water is just a basic cube that gets stretched during the sequence to feel as if it was “filling” up the scene. The real difficulty for this object was creating (and animating) the cartoonish shader – I actually followed this tutorial by SouthernShotty and just changed it a bit at the end to add some transparency.
Adding buildings and trees
The buildings and the trees were also created using geometry nodes. In addition to the random instantiation (like with the “voxels” of the terrain), I also added some nodes to randomise the rotation and the scale of each instance.
Note that a really cool feature of geometry nodes is the possibility to expose some parameters inside your graph. You can create your own customisable inputs and therefore easily tweak some options from one object to another, even if they use the same geometry nodes graph. This is especially useful whenever you have a seed for your randoms.
Making the vehicles (plane and boat) and the smoke
The plane and the boat aren’t very complex models. I basically looked for some low-poly references on the net and then added some diffuse materials to get a “toy-like” style:
For the smoke, I wanted to go back to a cartoon style (the idea being that all fluids are cartoon, while all the solids are low-poly/”voxelish”). So I found this neat tutorial by Kristof Dedene and focused on his explaining of how to make the small puff of smoke. Overall, it relies on apply a displacement modifier on an icosphere. For animating this cloud, the trick is to have this displacement’s origin be not the object’s local coordinates but instead an external object – then, by moving this object, you essentially change the origin of the displacement and thus feel like the smoke is moving:
Animating the vehicles
Both my plane and boat are animated using bezier curves. Rather than creating a keyframe animation and computing by hand the right translations/rotations to get nice curves, I used Blender’s follow path object constraint. This constraint allows you to have an object “ride” a curve in a given timespan, and you can even play around with the frames offset and stretching to refine the speed (see how the plane slows down at the top of its looping?).
Bonus: colouring the terrain
I just wanted to write a final note on the end of the sequence and how the terrain gradually gets from a plain white to a coloured ground. You can see how the areas near the water are “sandy” while the mountains are brown, grey and white.
To do this, I used a ColorRamp node in my shader that uses the object’s geometry as input factor and then applies a simple colour gradient to get the different “layers”:
I also made sure only the Z-axis has an impact by first separating the input layer; and I added some multiplier to better control the placement of the colour “layers”. You also see that my ColorRamp uses a B-Spline interpolation method, so that’s once again bending some rules of the pixel/voxel art – since it’s effectively reproducing some anti-aliasing…
This new project is yet another great opportunity at widening my CG skills and learning more about 3d. For this sole first scene, I already learnt about cartoon shaders, displacement custom origin points and follow path constraints!
I’ll definitely be continuing this series as well as the photorealistic rendering and the low-poly models… so if you want to keep up-to-date with my CGI projects, make sure to follow me on my socials and in particular on my 3d-dedicated Instagram 😉