Monday, October 3, 2011

57 – Catching up

I had two goals that I wanted to reach before today’s post: realize the basic DHCore integration and make the game less ugly!

DHCore integration was pretty straight forward and there is really not much to say: the 3D engine now uses the constants, data structures, API and terrain data provided by DHCore. The model that was designed for a 2D engine holds up surprisingly well in real 3D space and while the artificial distinction of floors and walls is… well… artificial yet again… it does makes things simpler to navigate. Memory consumption is under 100 MiBs but it is going to get higher.

The real hard part was the not ugly bit. I am not talking about direct things that are easy to fix: low res or inappropriate textures, low poly models, lack of shaders, etc. I am talking about things that transcend the notion of “this asset has been created with little artistic skill”. Basically, everything that can go wrong in a 3D engine going wrong: texture melding, texture bleeding, textures becoming muddy, texture stretching, Z buffer fighting and a whole bunch of other visual artifact. The best part about these artifacts is that they are not random: they form patterns that shift at the smallest camera movement so you are sure to pick them up. These get worse farther away from the camera and I’m sure you noticed a few, especially in the videos.

I need to fix these without sacrificing a lot of performance.

A lot of these artifacts are caused by my renderer. Rendering complex first person worlds is fairly easy. Rendering strategical views of maps that only have a surface to worry about is fairly easy. Rendering worlds where every single Z level is important and you can switch on the fly from strategic to first person view is a lot harder. For me at least. So each renderer is a compromise. It is near impossible to get one to do everything. So I’ll use more.

I created a new renderer for stone (and sand and soil) blocks. This one can be both faster and slower than the one used for grass, but it looks better:

Since it looks better I also must trade in something: this renderer gets progressively slower with every new texture it uses. The grass renderer handled 1 to 256 textures (that’s why my grass progression was as smooth) and only cared about poly count. The new one cares about poly count and number of textures. I am going to experiment and check out how far I can push it with a single texture. It is also optimized for layers where there is a predominant material. Here is the wireframe mesh:

The great thing is that it does not get muddy, stretch or cause artifacts at distance from the camera. Here is an entire level rendered:

Crystal clear! Bland, but clear! The performance is acceptable, but in the future I might add the possibility of dropping distant detail.

The grass renderer also got a small overhaul. For starters, I was using 256 levels of grass just because I could. Extremely smooth visual grass transition isn’t really the selling point of my game, so I reduced it to 16. I also wrote a new algorithm to approximate distant grass:

It still looks kind of forced, but it is a lot better, especially when compared to distant grass in my video “Experimental: Procedural Grass Progression”.

And finally, we have cell borders that can be toggled on or off:

The strength of the border is distance dependant and not quite perfect, but I do like the borders. They give a nostalgic 8bit feel to the world, especially on bright and colorful blocks.

Using these techniques, I put together this small little video:


  1. Why render only 3 z levels instead of say 64 z levels ?

  2. It is faster?

    This is just the default number I am using right now and can be changed with Page Up / Page Down.

    So you will be able to choose a number more to your liking.

  3. That looks pretty much playable from what I can tell!

    nice and stable fps too no matter how much detail you show.

    will you be introducing slopes on the land at some point too?

  4. To BrewStew:

    If you look at older posts, the engine used to handle ramps. I grew tired of managing these annoying ramps, but the code is still there, only deactivated.

    They might make a comeback, but for sure not in October.