David's Blog

Mostly Hobby Stuff

Archive for the ‘XNA’ Category

Fluid Integration and Smoke

with 2 comments

Over the last few days I have been adding support for PhysX fluids to my particle engine, in addition to a few enhancement+fixes to the particle engine itself. The big advantage of the fluid integration is not that it provides SPH(which is nice), but that it provides fast and robust collision detection and interaction with physical objects.

Anyway below I show a couple of screen shots of a small demo level I made, the first is the demo running(it runs at 60 to 30fps depending on resolution) and the second shows the editor with my node based particle editor. With respect to performance, it is mostly fill rate limited(unsurprisingly), I really should investigate using a low resolution render target for low frequency objects.

Some things I added to improve the quality of the results:

  • I rotate the billboard normals away from the centre of the particle, to create a fake volumetric effect. This vastly improves the quality of the lighting for particles. (not sure where this idea came from, I think I read about it somewhere, I just can’t remember where…:-(
  • I added particle sorting, surprisingly, most of the time this is not even needed for many smoke like effects(partly due to the implicit sorting due to emission order perhaps).
  • I used the relative screen space depth to fade the edges of the particles near intersection. This is done with a bunch of shader nodes, I really should combine these into one node since it is quite a common operation.
  • I use my own emitter, not the one built into PhysX, this allows detailed control of the emission parameters(eg distribution of particles within the emission cone etc)
  • I expose more or less all of the fluid settings, however I havent gotten around to sorting them and allowing distributions to be assigned to appropriate parameters.


Written by therealdblack

March 20, 2011 at 11:00 pm

Posted in Graphics, Hobby Game, XNA

Game Engine Progress

leave a comment »

Well its been a while since I posted here, apart from Job Hunting I have had time to do a few things on my game engine. Nothing particularly exciting, mostly stabilization, bug fixing and features which are not terribly exciting, but still important. A quick list:

  • Linear space lighting, ie I adjust the gamma of textures when reading(in the shader, due to XNA/portability concerns) and convert to 2.2 gamma at the end of tone mapping. While quite a simple change this made a huge difference to the lighting quality.
  • Colour correction + screen fades etc. A simple change, I added a matrix transform after tone mapping. In addition I added logic nodes to control this.
  • Limited deferred lighting. The motivation for this was that since I didn’t want to add GI or lightmapping I needed a way to add many fill/fake GI lights to indoor scenes to give a convincing level of lighting complexity.
    I say deferred, but all I do is draw the light volumes to a texture and read the normal/depth map to compute the lighting. I don’t have any sophisticated attribute buffer/shadow mapping etc, the deferred lighting is controlled with parameters from just the lights. Later this is combined with key lights, textures etc during the forward rendering pass. My deferred lighting texture consists of diffuse + ambient in RGB and a single channel of specular in alpha.
  • More animation blending nodes, including nodes for inverse kinematics, converting absolute to relative animation(eg converting a climb animation relative to a fixed point to take into account player movement), fading between animations etc. Plus I added lazy animation updates(ie only re-blending animations when something relevant to the nodes changes).
  • A GUI editor and rendering/interaction system for menus, player HUD etc. This allows plugable GUI controls, each of which can be assigned another plugin node which manages the action of the node. For example loading another GUI page, changing resolution, input bindings etc.
  • Load/Save support, this just consists of a function to gather marked properties and user-generated save data into a data structure from entities and components. I then use my versioned serializer to write this to a file.
  • A proper input system which allows arbitrary mapping of keyboard/mouse and game pad input to linear and binary actions. This includes thread communication and UI integration components.
  • Basic cube map reflectors(ie runtime generated reflection maps). Nice to create mirrored balls, environment maps etc.
  • Texel snapping and fixed frustras for CSM shadow maps. More or less eliminates the very annoying shadow flickering when moving around.
  • A particle history node for particle systems, this combined with a couple of other nodes and features allows my particle system to produce beam effects.
  • Async level loading.
  • Depth of Field post processing effect.

Not sure if I mentioned some of these changes already… Also hopefully I will find time to add some screenshots of some of these things soon.

Written by therealdblack

January 17, 2011 at 7:35 pm

Posted in Graphics, Hobby Game, XNA

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