Wednesday, August 22, 2012

85 – Polishing & bumping

Since last time I did a ton of housekeeping tasks and implemented bump mapping. This will be a longer post with a ton of ugly pictures. These pictures were taken on an integrated Intel GPU so they are low res and the framerate is shit.

The first thing I did is separated the height map representation from the terrain representation. Now you have a separate height map you populate with data. An independent terrain object can now read from the height map data when needed. In the future this might open the gate towards Perlin noise and other height map types.

Then I chunked the terrain. Now any size height map (as long as it fits in RAM) can be used and the terrain can take a subset of that height map and create multiple chunks to cover it. Having chunks has a lot of advantages, like having different LOD levels on chunks, doing frustum culling on chunks and even making the game run on Reach profile since I made sure that an individual chunk has under 64k indices. It also has disadvantages: since frustum culling is not implemented yet, chunks are actually slower that one big terrain. Even after culling, the batch size will be larger so terrain will be slightly slower to render. Also physics is slower on many chunks by some margin.

Then I greatly fine-tuned physics parameters. Now things are considerably less wonky and movement is more realistic. Still not perfect, but a great improvement.

Than came a really ugly task. When I first added the barrel model and physics to it I had to create a new "dumpy" model that is centered on (0, 0, 0) and has a width, height and length of 1 in order to tightly bind the mesh to the physics object. This is not really desirable, so I went ahead to implement a better solution. This is easier said than done. Even the simple barrel mesh has bones. I never used bones and it took me over 3 hours to experimentally figure out how they work. I also had a major bug in the bounding box calculation algorithm: both a coding error and a failure to take bones into consideration yet again. Fuck bones! Why do barrels need bones? Anyway, eventually I managed to create a system that ignores model scale and translation and perfectly fits it into a physics object. This is enough for now, but the actual mesh position and scale can be important information, so in the future I'll need to make the system more flexible, by allowing you to choose between ignoring scale and translation, ignoring scale, ignoring translation or not ignoring anything.

Then I went ahead and tried to take control of the rendering pipeline. In XNA a lot of things happen behind an abstraction layer and while I am learning the ropes, I tried to get rid of model and mesh classes use, relying on Update and Draw methods and I tried to manually render a model. This was a lot easier, but I still had problems with bones that I needed to solve.

Then I took my manual system and hooked it up to physics objects mapping. Again had problems with bones, but now I have a good pipeline for matching meshes to physics objects and rendering them with minimal state changes.

The final step was to transition from the shaders provide by BasicEffect to custom shader for per-pixel lighting. BasicEffect has quite a deceptive name and is in fact a powerful and extremely flexible little shader, but I want custom lighting.

I managed to add Blinn-Phong lighting, probably the same that BasicEffect uses and as traditional for my efforts in the domain of lighting, things look like shit now. With BasicEffect things looked a lot better.

But onward!

Next step was to add normal mapping. Finally, picture time! Here is a barrel with a brick wall normal map, a.k.a. my first test:

Not a great match, but at least normal mapping works. I created my own normal map for this barrel:

Better, but not that great. How about if we make the bump effect more pronounced:

Yep, better. Wider and more pronounced:

Ohhh God, why! Extraordinarily ugly. In the end I settled for a somewhat rough normal map:

Normal mapping now works, but what about parallax mapping? Well:

It also works. Now if I understand correctly parallax mapping is prone to swirly artifacts and can't be used on some objects. The barrel does indeed present some artifacts. Let's see them on a brighter barrel:

I tried to fix the artifacts and I'm not sure what to think about parallax mapping yet:

Anyway, the barrel still looks wrong with either normal or parallax mapping. I created the normal map and I suck at such endeavors. But let's see what the shaders can output when feeding them some textured created by professionals. Back in the disco demo days with deferred rendering, BrewStew fine tuned the textures for the stone stool for a good bumpiness effect:

Now that looks a lot better. The textures are not quite as well tuned for this shader and under deferred rendering bump quality was a lot higher, but still, the system works if you feed it textures created by artists. The stool is a little bit shinny and this was the problem I had under the deferred rendering engine. I'll need to fix this somehow.

Now the strength of the bumps can be adjusted. Here is the same stool with a "higher" normal map:

And finally, let's take a look at the super artifact prone parallax mapped stool:

Finally, I physics enabled the stool. For now I am approximating the shape with a cylinder. Quite the poor approximation and will probably be replaced, but it works quite good. Here is the stool blasted off into the distance and landing on the floor somewhere, showing of parallax mapping artifacts:

The next step is to create a pipeline and convention for file locations to easily add any number of meshes and their associated textures. And do major clean-up on the code base.


  1. nice to see you having fun with my meshes and uv maps :P

    let me know if you need anything with your new frontier and i'll be happy to help.

    1. Thanks!

      I'll be sure to let you know. First I must finish the physics playground part of it.

  2. awesome cant wait to play it good work