-->

I’m currently looking at the normal mapping materials that are available in Away3D and became aware that to do a decent test it’d be nice to be able create normal maps myself. Previously, when looking at lighting effects in Papervision3D, I created my own bump map from random data very easily. I’ve tried doing the same for a normal map but haven’t found a decent utility to help me do that… so, I decided to write one myself.

Assuming that the displacement map image is applied to a single surface, the normal to the surface can be calculated quite easily by taking the gradients in the x and y directions and calculating the cross product of the two (see this description from Wolfram MathWorld on surface normals for example).

Using the bitmap data (assuming it is greyscale), we can calculate the gradients using finite difference calculations using the pixel data as a height (displacement) and the pixel position as the x and y coordinates (again, Wolfram MathWorld on finite differences provides a useful source of information). The normals can then be calculated at each individual pixel and converted into red, green and blue data.

The Flex application shown below reads displacement map data, calculates the normals, and creates normal map data. You can check it out by clicking on the image below or visiting http://www.tartiflop.com/disp2norm/.

Note that this requires Flash Player 10 because it uses some of the new features available: namely reading and writing to the local file system and the use of the Vector3D class.

If you’re interested you can check out the source as well.

Two additional features are available:

  • Selection of the displacement direction. For example if you have a displacement on a xz surface, for the lighting to be correct you need to specify that the displacement is in the y direction.
  • Amplitude selection. You can modify the coarseness of the displacements by adjusting the amplitude factor - low is a smooth surface, high is a very rough surface.

Update !

The converter can now create normal maps for spherical objects too!

Simply select the Spherical radio button and the normal map will be produced for a sphere. It assumes that the displacement map data has also been created for a sphere. The axis from which phi is calculated can be chosen using the combo. For example, in Away3D, this is the y axis for the Sphere primitive.

For info, the normal is calculated differently (and more simply): from the pixel indices, equivalent to spherical positions, we can calculate Cartesian positions. These can be converted into vectors and hence the cross product of vectors running across the pixel (in latitude and longitude directions), taking into account the displacement map data, gives us directly the normal to the sphere… hope that makes some kind of sense!

If you have any comments or questions then please let me know!

3 Responses to “Displacement map to normal map converter”

Fabrice Closier said...

This is a very usefull addition Stuart! Keep it up!

makc said...

It would be far better, if away supported local maps. Then you wouldnt have to think about what shape it is going to be applied to.

RaiulBaztepo said...

Hello!
Very Interesting post! Thank you for such interesting resource!
PS: Sorry for my bad english, I’v just started to learn this language ;)
See you!
Your, Raiul Baztepo

-->