David's Blog

Mostly Hobby Stuff

Texture Tools and Normal Maps

leave a comment »

A while ago I noticed that the memory consumption for my hobby game was getting out of hand. So I did some profiling using the CLR Profiler and PIX to find out where all the memory was going. Unsurprising the biggest memory hog was the unmanaged memory for texture maps, especially because I mostly use 2048×2048 colour and normal maps for models.

Anyway, I started by enabling texture compression for the colour maps by enabling texture compression in the XNA texture processor. This helped, but it left a couple of problems, the normals maps were not compressed and the quality wasnt as good as it could be.

First to solve the normal map issue I did a little investigating and found that DXT5 with a little cleverness could be used(note: xna is D3D9 so I couldn’t use the nice new normal map formats in D3D10+). Since we only require 2 components to reconstruct a normal, we want to store one of the components in the alpha channel and the other in the green channel to maximize the use of the available precision. This format is sometimes called DXT5n(m). Storing the normal in the colour channels doesn’t produce very good results, (see Real-Time Normal Map DXT Compression).

There is a nice trick for doing the decompression that allows the same code to handle DXT1 compressed normal maps as well(useful when quality is not such a large concern). See Christer Ericsons Blog post.

My normal decompression function:

float4 UncompressNormals(float4 input)
float x = input.r * input.a;
float y = input.g;
float z = sqrt(1.0f - x*x - y*y);

return float4(x, y, z, 1.0f);

With that done, I now faced some quality issues, in particular the normal maps looked very weak when viewed from a distance. This suggests that the mip maps for the normal maps are not being generated correctly, not surprising since the same filtering code is being used for both colour and normal maps. Normal maps should be re-normalized after each level of the mip map is generated and they should also be processed without any gamma correction.

To improve the situation I switched to NVidia Texture Tools for the texture processing. This had a number of additional benefits:

  • Explicit Support for DXT5n
  • More sophisticated controls for gamma, resizing, mip-map generation etc
  • Support for normal map generation from height maps
  • support for more sophisticated mip-map filtering

However there was no XNA texture processor or functional .NET wrapper, which meant writing one:-) The maintainer of nvidia-texture-tools was nice enough to allow me to commit the changes, so you can grab the processor and .NET wrapper from http://code.google.com/p/nvidia-texture-tools/source/checkout. (the changes are not included in a release yet).


Written by therealdblack

June 26, 2010 at 12:13 pm

Posted in Graphics, Hobby Game, XNA

Light Fade Volumes and Filter Overrides

leave a comment »

One problem with the system I mentioned in my last post was that the transition from outdoor to indoor lighting was rather harsh. So in order to improve this I added something I call light fade volumes, these are simply trigger volumes which cause the influence of a set of lights identified by a filter group to scaled based on the distance of the object through the volume. For example I can place light fade volumes in doorways to gradually reduce the influence of sky lights on the player as they move through the doorway.

In order to support this I needed to add an additional feature to triggers/collision geometry, i.e. a direction for the volume. This direction can be set and displayed in the editor(as shown below). A further motivation for a direction is to support things such as force fields, push volumes, gravity volumes, anisotropic friction etc.

Once I had this working, I noticed that I often wanted a bunch of lights to only affect the static geometry (e.g. steps) but not the dynamic object resting on them (player). To achieve this I added a property set which can be applied to collision geoms which specifies an alternative light filter for objects resting on them.


may12 may12_2 may12_3

Written by therealdblack

May 12, 2010 at 9:55 pm

Posted in Hobby Game, XNA

Occluder Fusion Cells and Light Filtering

leave a comment »

Today I added support for optionally setting the occluder fusion cell size for each model.

I should probably explain what the occluder fusion cell size is: When rendering multiple instances of an object, for example patches of grass, objects are grouped/fused into chunks. This allows everything in a fusion group to be drawn in a single draw call. In addition to reducing the number of draw calls this reduces the amount of overhead for lighting, material setup, occlusion culling etc.

Hence it becomes trivial to support large numbers of identical objects without the need for special case code. Which in turn simplifies other features such as editing, object painting, decals and particle mesh emitters(TODO).

Anyways, the reason I needed to set the cell size was that for most objects a default size suffices, but for distant/background objects, like buildings in the distance the cell size should be much larger. The cell size can also be tweaked to allow more detailed lighting, since light bindings are shared between all objects within a fused group.


Next I added a component which sets a models light filter group based on the object which it is standing on. The reason for this is that objects like the player move from outside to inside. When inside, the player should not have lights such as the directional light simulating diffuse light from the sky affecting them.

One pleasing thing about this feature was that it is a good example of the power of my component based architecture. The entire implementation is about 130 lines, with the ability to apply this component to any model and full editor configuration support:-)

Written by therealdblack

May 2, 2010 at 8:33 pm

Posted in Hobby Game, XNA

Lazy Lights

leave a comment »

Well I have added support for only evaluating lights when they move. This helps performance a lot when there are large numbers of lights. So now I can add lots of lights to improve the visual quality of my levels:-)

In addition I also added support for inheriting light filter settings. This is nice since I tend to work on models for each room of the indoor parts of the level. Each room in turn contains many other models for fixtures, trim etc.


apr28 apr28_2

Written by therealdblack

April 28, 2010 at 8:30 pm

Posted in Hobby Game, XNA

Higher Resolution Video

leave a comment »

I also have a better quality version of the water shader video on Vimeo, the reason I posted a YouTube version was that Vimeo took like 2 days to encode the video once I uploaded it…

Written by therealdblack

April 12, 2010 at 7:05 pm

Water Shader Video

leave a comment »

I figured out how to capture video and post to my blog, so I am posting a quick test video of my water shader. For anyone that is interested in the simulation of the water a great site to check out is: http://www.matthiasmueller.info/ (don’t be put off by the scary photo:-). What is shown here is the most basic shallow water simulation possible.

So here’s the water video:

Note: The artwork/settings are only preliminary, so things like the shadows, water colour, reflection image etc will look a lot better when I show proper artwork. Also ignore the misbehaving bit of cloth in the background, it is badly tuned and was put in the test scene a while ago to debug something.

Written by therealdblack

April 10, 2010 at 9:45 pm

Moving to wordpress

leave a comment »

Well I think I am going to move my blog to wordpress from spaces (http://davejohnblack.spaces.live.com/blog/).

Mainly because the spaces blog software seems rather limited. I originally started using it because live writer seemed rather handy.

Note, I used therealdblack for the user name, I wanted dblack.wordpress.com but it seems to be already taken. In fact I think it is probably me who registered it but I have forgotten the password and I think the email it is set to is dead. Never Mind.

Written by therealdblack

April 10, 2010 at 5:20 pm

Posted in Uncategorized