Howto:Use the normal map effect in aircraft

From FlightGear wiki
Revision as of 22:30, 8 April 2010 by Stuart (talk | contribs) (Add information about inverting Y axis for proper OpenGL normal maps)
Jump to navigation Jump to search

FlightGear 2.0.0 introduces Effects, a powerful way to use Shaders within FG without having to write C code. As of March 2010, FlightGear CVS has a Normal Map effect (Effects/bumpspec.eff), which provides both bump mapping and specular mapping. This Howto provides a tutorial on using this Effect for aircraft. Similar techniques can be used to use other Effects on aircraft.

If you don't know how a Normal Map works, have a look here.

Creating the Normal Map

To create the Normal Map, we need a plugin that can convert a texture representing height to a set of normals. There is a good normalmap plugin for GIMP available. Those on Ubuntu should be able to install it directly from the package manager.

Once you have it installed, create the normal map as follows.

  1. Identify an object that you intend to apply the normal map to using Blender AC3D etc.
  2. Find the part of the texture (the texture coordinates) that apply to the object. Given that most aircraft textures are sensibly organized, this should be straightforward. The same texture coordinates will be used for the normal map.
  3. Open the texture in GIMP and create a new layer with black as the background color. We'll use the existing texture as a guide to creating the normalmap.
  4. Adjust the opacity of the new layer so you can see the texture underneath. This layer will be a height map, with black representing low points, and white representing very raised points. So, at the moment the entire height map is at sea level.
  5. Now use whatever painting technique you wish to draw the height. If you want well-defined edges, draw using a sharp-edged tool.
Height Map with original texture

  1. Once you are satisfied with your height map, delete the background layer, increase the opacity back to 100% and save it as a new file.
  2. Now we need to convert the height map to a normal map. To do this, use Filters->Map->Normalmap. If this is not present, you haven't installed the normalmap plugin as described above.
  3. The default options will work fine, except that you should invert the Y axis (as OpenGL vectors origin is the bottom left rather than top left). However, the author of the plugin recommends the Prewitt 5x5 filter. Once you are happy with the options, press OK, and your image should turn generally blue, but with some strange colours around the areas that you coloured white. This is the normal map.
  4. Save off the normal map as a new png file in your aircraft directory, remembering the correct path.
Final normal map

Creating the Normal Map Effect

No we have our normal map, we need to apply it to the aircraft. To do this, we need to create a new effect, based on the existing Effect/bumpspec.eff, and then apply it to the correct object in the model.

  1. Open Effect/bumpspec.eff. You'll find some instructions at the top of the file.
  2. Copy the first set of XML (between the <PropertyList> and </PropertyList> tags into a new .eff file in your aircraft directory.
  3. Edit the new file so that it has an appropriate <name> entry and an <image> entry that matches the normal map you created above. For example, in this case we've createed the effect Aircraft/c172p/Models/Effects/bumpspec, and are using the normal map Aircraft/c172p/Models/Liveries/wing-normal.png.

     <texture n="2">

Now we have a new effect, which is based on the original Effects/bumpspec.eff, but which uses our own normalmap.

Applying the Effect to the model

Finally, we need to apply the Effect to the model. This is very straightforward. Simply add a section to the model .xml file indicating the Effect you want to use and the object it should apply to.

For example:


Now load your model and admire the Effect:

Cessna with normal map

Final Notes

  • The normal map uses the same texture coordinates as the original texture. However, the normal map does not need to be the same dimensions, so you can use a smaller or larger normal map if you need to.
  • You'll need to define a different Effect for each normal map you use. Effectively this means that if you have two objects using different textures, they will need separate effects.
  • The bumpspec.eff Effect uses the alpha (transparency) channel on the normal map to set specularity of the point (e.g. shininess). This can be used to make raised parts shiny.
  • If you find that the effect is too pronounced, try varying the scaling in the normalmap filter. 0.1 seems to work well for "rivet" effects.