Zombie simulator: pixel shaders E-mail
Sunday, 31 January 2010 19:31

I started work on a second car, but It was looking very ordinary.

The first car worked well because it is so distinctive with the stripes, it's hard to mistake it for what it is, but the new car, which is loosely based on a Toyota/Lexus Soarer, looked nothing even remotely like the photos. The biggest issue was that with texture maps alone I could not get small details to look 3D-ish, like the side stiping. This was also a problem on the hatchback, but didn't show up as much.

I decided to look into using some of Irrlicht's fancier material types, ones that use normal mapping, so I could put some bump mapping on the cars for the little details like door handles.

The first step in this direction involved reworking the vehicle classes to create meshes with tangents, which are necessary for these more advanced materials.

Irrlicht's normal mapped materials

Next it was time to play with the new materials, and what a disappointment that was.

Sure, the bump mapping looked great - I used Irrlichts Earth bump map laid onto the cars which made them look heavily damaged, but unfortunately, there was one little problem.

The materials didn't support ambient light sources and they also didn't support directional light sources, which is the type of light source I have to use as the map is so huge.

I don't know why it's so limited, though I read something about it being as simple as possible to run on everyone's hardware - not much use when the shader will look out of place in anything except a night time scene in a small room!

So, that was then end of that, however, having seen how well the cars looked on their lit sides at least, I really wanted to get bump/normal mapping to work.

Investigating pixel shaders

I've not previously been involved with pixels shaders, so it was a steep learning curve.

I scoured the Irrlicht forums looking for information and I was inundated with new acronyms such as HLSL, GLSL, CG and CGfx.

There's also a number of different classes available for Irrlicht that make use of pixel shaders, including XEffects and IrrCG.

After reading for a while, I found out that GLSL was nVidia's pixel shader language for OpenGL, and as usual, Microsoft has their own called HLSL. Then nVidia released CG, which is a platform agnostic pixel shader language that's structurally very similar to HLSL. On top of that they later released CGfx which is a "package" containing different versions of a pixel shader for use in different situations, depending on the platform and hardware.

CG pixel shaders should theoretically be able to run on ATI and nVidia cards, and the structure was similar to HLSL, which meant that I should be able to find plenty of examples, so in the end, that was the one I selected.

As I mentioned previously, IrrCG provides that ability to load CG shaders, so that solved all my problems!

All I had to do then was install nVidia's CG toolkit, install IrrCG, figure out how it worked, integrate into my Zombie Simulator and finally, find a nice pixel shader to pretty up my cars.

Many hours later....

Ubuntu has nVidia's toolkit in the repo's it turns out. (nvidia-cg-toolkit) It is an older version, but it's more than enough for what I wanted

IrrCG turned out to be a bit of a pain for several different reasons:

  • Firstly, it wouldn't compile on my system because it was complaining about glXGetProcAddress not existing. I eventually tracked it down to the glx.h file, which I added to the IrrCG.cpp file thusly:
    #include "COpenGLDriver.h"
    #else
    #include <GL/glx.h>
    #include "glext.h"
    #endif
  • Next, I had all sorts of problems caused by my previous attempts to resolve the lack of ambient lighting in Irrlichts materials. I had upgraded to the latest SVN, and IrrCG wouldn't compile. After a while I found an entry in the forums which explained what to do.
  • Finally, the last problem I had was that there were almost no CG pixel shaders available! There was some talk on the forums of a Chernobyl shader pack for IrrCG, but it was never finished and only contains three shaders that aren't particularly useful.

Doh!

Where to get a shader?

The answer to that question is that I had to make it myself.

nVidia have a lot of freely downloadable HLSL and CGfx shaders avaialble, but unfortunately they're all in formats I can't use and the tools that can convert them either don't produce 100% complete code, or don't run on Linux. I can't run them in VMWare, and access to a proper Windows box with a modern video card, I had no way to use them.

That left me only the option of writing the shader myself.

My basic requirement was something that would provide phong shading which is superior to Irrlicht's Gourard, support for bump or normal mapping and directional and ambient light sources.

I set about dismantling a bunch of nVidia's example hlsl shaders, picked out the bits I wanted, combined that with various shaders and tutorials I'd found around the internet, all of which is far too long and boring to go into...

Anyway, here is the end result:

I've gone a little bit further than what I wanted - additionally, I've made it so that a base colour, passed to the shader, is used wherever there is a transparent pixel in the texture map. This resolved a problem I had initially with the cars in that I was having to build the colour of the car into the texture. Doing it this way means that I can have any car in any colour and use fewer textures, because the bump mapping will take care of the detail, shading the striping and handles to match colour passed in.

The latest car is looking pretty good and it uses quite a lot fewer polygons than the first... which means I'm going to have to go back and tweak the first one once this one is complete and I'm sure the system is working.

blog comments powered by Disqus