David's Blog

Mostly Hobby Stuff

Archive for the ‘Graphics’ 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

Shallow Water Simulator, OpenCL + Rigid Body Interaction

leave a comment »

Just a quick update to post a video of my current progress on my shallow water simulator.

Recently I converted the simulator to OpenCL(from plain C# code) and added rigid body to water and water to rigid body interaction. The conversion to run in parallel was very straightforward, for the rigid body interaction I subdivide the collision shapes into triangles when they first touch the waters bounding box, then just process each triangle separately using atomic operations to update the height and velocity fields. I need to investigate the performance in more detail and generally optimize things, but the initial conversion seems quite fast(the ducks scene runs at 45+fps when not recording video).

I have also added FFT wave simulation for small scale details and/or providing a nice water effect when interaction is not needed(although this is not shown in the video). You can find further details about this method at http://tessendorf.org/ .

Written by therealdblack

March 6, 2011 at 5:51 pm

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

Real-Time Simulation of Large Bodies of Water with Small Scale Details

leave a comment »

I should highlight this rather useful paper(pdf).

It discusses issues faced when building a 2D heightfield fluid simulator (see my former post about the bare bones simulator I added to my engine).  What is so useful is that it provides many references and nuggets of information needed to extend a basic simulator to increase stability and improve interaction with other systems.

Thankfully it contains only a minimum amount of GPU Compute marketing:-)

Written by therealdblack

July 8, 2010 at 7:22 pm

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

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

Light Attenuation

leave a comment »

Recently I have mostly been doing art stuff however one thing I found that needed improvement was the lighting system. I was using, the fairly awful standard method for computing light attenuation i.e.:

attenuation = 1.0f / (a + b*dist + c*dist*dist)

The reason this is bad is that it requires 3 rather unintuitive parameters, plus it may not fall off to zero at the edge of the lights range. There are a number of alternatives:

  • Use a texture (3D or 1D) to encode an arbitrary function. This would be a good way to go but it would increase the complexity of the material system and require more work to define the textures. In addition there is likely a performance cost. Since I am already heavily bandwidth bound I didn’t want to pay this cost.
  • Use smoothstep(), this produces nice looking results, but it provides little control.
  • Use something similar to the way spot light falloff is calculated. i.e. have a MinDistance parameter which specifies the range at which the light has full effect, then use a pow() to encode a falloff. The exponent gives a nice intuitive control for the rate of falloff. Hence I chose this solution.

For example:

float ComputeAttenuation(float3 position, float3 lightPosition, float4 attenuation)
{
	float dist = distance(position, lightPosition);
	float range = attenuation.w;

	if(dist < range)
	{
        float attenMinDist = attenuation.x * range;
        float attenExponent = attenuation.y;
        //attenuation.z is unused for now

        float attenIn = clamp((range - dist) / (range - attenMinDist), 0.0f, 1.0f);
        float result = pow(abs(attenIn), attenExponent);

        return result;
    }
	else
	{
		return 0;
	}
}

Which is nice and simple and saves a huge amount of time when tweaking light attenuation.

At the moment I am working on improving my lighting performance, which really suffers once I start having 10s or 100s of lights in a level. Of course only a few are visible at once, but searching for the lights, evaluating filtering, shadows, setting effect constants etc is not good. So what I am doing is evaluating light<=>material bindings only when lights or objects move.

This however does lead to not being able to make the light selection view dependant, hence in principle lights could be bound which are not visible. However this is perhaps not a bad thing, since it will eliminate lights going on and off as the player moves. In addition lazy evaluating light bindings will make it easier for me to add support for static shadow maps.

Written by therealdblack

April 10, 2010 at 5:12 pm

Posted in Graphics, Hobby Game, XNA

Water Shader

leave a comment »

Recently I have added support for rendering water(and other similar effects). The features I added:

  • Refraction texture coordinate generation, this is done in screen space with depth checks to ensure only geometry behind the refracting geometry is shown.
  • Support for distortion maps(i.e. a copy of the main render target is made before executing distortion shaders).
  • Reflection texture coordinate generation, the texture coordinates are generated in the texture space of planar reflectors and offsets added for normals which are not planar with the reflector.
  • Support for object space normal maps
  • Support for displacement mapping/texture sampling(in the vertex shader).
  • Support for applying a blur to reflection maps, this allows much lower resolution reflection maps without the reflection becoming pixelated. Plus it looks better too.
  • A Fresnel material node.
  • Support for dynamically binding values to material constants(e.g. the projection matrix for reflectors).

In addition I added a basic shallow water simulation module for dynamic models which allows the user to use vertex painting to specify the height of the ground and water. I will talk later about the water simulation after I have added a few more interesting features.

Below I have added a screen shot of the water shader, in the editor. I will have to get around to figuring out how to post a video in order to do an actual render of the water justice. However, the node based shader editor is beginning to prove its worth, it would have been much more tedious to tweak the water into something acceptable had I not had the ability to re-arrange nodes, tweak values etc etc:-)

In addition I made a few optimizations to improve the frame rate, especially at higher resolutions. In particular I disabled bilinear filtering for a bunch of screen space operations which didn’t need it(going from one render target to another of the same size). This provided a huge boost to the SSAO shader… Which went from being memory bandwidth limited to shader instruction limited. (it works in view space, so can probably be improved further).

mar17

Written by therealdblack

April 10, 2010 at 5:11 pm