Do you remember the boring dungeon? I've worked on that. But before that, there was some major voxel engine development.
Working on a voxel engine gives you a lot of hindrances in terms of memory and performance. Having a lot of voxels requires megabytes of memory and a lot of clever processing to handle millions of cubes efficiently and display them in real time.
But there are also perks. With voxel engines it is easier to create objects procedurally. You can build procedural environments that look nice. Well, voxel are like particles. They just don't move much. It's easier to interact with environment. AI elements. Easier to create art. Less textures, so smaller downloads. And probably more.
Handling huge voxel spaces requires a lot of preprocessing. Many things are precalculated, the most important being the 3D triangle meshes. Most of you probably know that, Minecraft (or Infiniminer before it) didn't draw voxel with many cubes. Meshes were constructed only with cube faces that were visible (i.e. next to air), sometimes batching neighboring faces together - instead of 2 squares, 1 rectangle. This way you could reach reasonable frame rates.
This optimization has it's downsides. As building meshes takes time, it is done only for groups of voxel (called chunks) and only when they are visible. Chunks outside of view frustrum and far away are de-meshed to save memory, and meshed again when they get back sufficiently close. While inside the view frustrum, they are not changed and so only rendered, which is faster. Unless you dig a hole in the chunk.
My recent work considered this aspect - dynamic changes in the voxel space. But before that, let's talk about lighting.
Lighting is important. If it is all black and white, or candy-colored, or something else, it creates mood. Sometimes the more constraint the colors are, the more interesting the mood. But that's for another time. For me, lighting is not only a way of adding mood or realism. It's about creating feelings.
When I think about voxel rendering, there are to types - one, that tries to hide voxels in a realistic rendering and smoothing, and another, which is proud of voxel heritage and creates a blocky feeling. For me it's like LEGO. I loved it as a child and creating this style visualisation creates a feeling of a child playing with his toys on a table. Things are small and under control. For that, you need decent lighting. When I mean decent, I mean Global Illumination.
In Minecraft you don't have much of a lighting. Sure, you have sun or torches, and although it serves it's purpose, it's nothing like illumination technics. In Perliner until know, I've used obscurance. For each vertex in a cube (there are 8;-) I have calculated among 3 adjecent cubes number of ones that are solid. For a cube it meant 3*8 checks.
It turned out it didn't do correct lighting for vertical faces, as you can see on the picture below.
Then I realised I needed to do it properly - each side needed to have individual lighting. I've corrected it with 3*4*6 checks (6 faces with 4 vertex with 3 checks). It looked correct, but it was always grayscale (I didn't consider color of blocks). What's more it didn't consider lights that I planned for the game. I prepared separate methods for applying lights from nearby sources. I called this method obscurance based.
And than it struck me - I needed correct shading and correct lighting. Maybe I can combine the two. For each air voxel I hold information about illumination (RGB), and for each of 6*4 vertices of a cube I sum illumination of 4 adjecent cubes. If a cube is occupied by a solid material, I take black for now - later color of material will be considered.
It's not Global Illumination, but with color lights and proper illumination propagation who knows...;-).
Dynamic changes in voxel space
I've mentioned earlier - changing voxel space is expensive.
Changing even one voxel requires recalculation of lighting and mesh for a whole chunk, and potentially for neighbor chunks too. It's a spike in amount of calculations. It's a jitter in fps.
First I've implemented update of color information. Currently I use it also for bleeding, leaving blood marks on the floor or anywhere. Brrr... ;-). The code is able to update only the color information in modified segments of a mesh, without touching the geometry. It is pretty fast for small area changes in color - character bleeding all over has no visible influence on fps.
Then I've worked on changes in geometry. The game will heavily depend on those - digging pits and building fortifications, and dynamic destruction. It's unfortunately slower, requiring rebuilding of a whole chunk, when even a single voxel is changed, but it's there and it doesn't spoil the game by it's performance. Placing a voxel or digging causes a short hickup. It is noticable, but barely.
Last but not least - new dungeon is there, as you could see on other images. More diverse. Different material. Greenish stains.
It was a lot of internal changes in the engine. And there are still more changes to come - color info for solid cubes and better chunk management. Plus multithreading. But still, game runs on my Samsung Galaxy S2 with 55fps (with no Unity's dynamic shadows).
And sorry for that long piece of news. Kind-of felt like sharing:).