Tony Polinelli
Tarwin Stroh-Spijer

contact [at]
touchmypixel.com

6/25 Easey Street
Collingwood, 3066
Vic, Australia

+61 3 8060 5321

Flash: Normal Mapping for Physics

Almost a year ago I was reading about how normal mapping works (on Wikipedia I think) and it struck me that this would be a great way to define a useful height map for games, maybe a mini golf game as an example.

My understanding is that normal maps work by encoding the X and Y angle difference from a flat surface (generally a polygon). That is the difference between a larger polygon from a low count polygon model, and the multiple polygons that made up a high count polygon model. This is normally saved as red and green channels. The blue channel (from what I could work out) was used in some way for height (or Z).

So, if I know the red and green pixel value at any point I can tell the angle, or at least amount of slope in X and Y, between -128 and 128 (256 colors for each channel of a 24 bit image). And the blue channel can tell me Z (or height). But how to make a normal map? I found a program (can't remember what it's called now, dam, I'll post when I find) which let me convert height maps (greyscale) to normal maps, and preview what they'd look like on a box or sphere. This was great, except that the blue channel was never quite a representation of the height info, I'm still not sure what it was exactly, any have any idea? Not to worry, I just loaded the file back in Photoshop and replaced the blue channel with my original height map data! I also copied (took a screen shot) of my normal map with lights on the face of a square.

I had thought about trying to make the normal map in Flash, directly from a height map, but really couldn't be bothered trying to do all the processing, maybe next time! I could even use Flash to create a "rendered view" using a displacement map I think.

[Side note: I guess you could use a 32bit image and use the Alpha for some extra info, maybe extra height, or amount of friction or something]

Here's some of my original examples. Use the keys to move the ball around (click to view).

Exeriments

Example 1 Example 2 Example 3 Example 4

After doing these examples I had intended on making some kind of minigolf game, but it never happened. A few days ago I was thinking back to those experiments and thought "wouldn't it be great to use the normal maps for some kind of driving game thingy". Why not use my new-gotten PV3D skilsl for a new experiment ... so here it is!

PV3D Normal Mapping experiment

Example 5

In this example I used Papervision3D to create a box that drives over the landscape I've created, and it's rotation and height is affected by this terrain.

Example displacement maps

And here are some of the displacement maps if you want to play around!

Dis 1

Dis 2

The Code

Here's the main part of the code, the bit that does all the "normal mapping" stuff at least.

Actionscript:
  1. // let the user move the ball around by adding velocities to it
  2. if (Keys.isDown(Keys.UP)) ball.velocity.y -= -.1;
  3. if (Keys.isDown(Keys.DOWN)) ball.velocity.y += -.1;
  4. if (Keys.isDown(Keys.LEFT)) ball.velocity.x -= -.1;
  5. if (Keys.isDown(Keys.RIGHT)) ball.velocity.x += -.1;
  6.  
  7. // get the RG&B values for the pixel under which our ball is
  8. var pixelValue:uint = dis.getPixel32(ball.x, ball.y);
  9. var alphaValue:uint = pixelValue>> 24 & 0xFF;
  10. var red:uint = pixelValue>> 16 & 0xFF;
  11. var green:uint = pixelValue>> 8 & 0xFF;
  12. var blue:uint = pixelValue & 0xFF;
  13.  
  14. // get our angle X and Y
  15. // the green is flipped so it can be worked with the same way as the red
  16. var ax = red;
  17. var ay = 255-green;
  18.  
  19. // set our velocity depending on the color values, or angles, normalizing the 0 -> 255 to -128 -> 128
  20. // this makes it seem as if the ball is on a hill, and being pushed towards the screen by gravity
  21. ball.velocity.x += ( -128 + ax) / 100;
  22. ball.velocity.y += ( -128 + ay) / 100;
  23.  
  24. // using the blue channel, change the height of the tank
  25. var pz = (blue / 255);
  26. ball.scaleX = pz;
  27. ball.scaleY = pz;
  28.  
  29. // add friction to our ball
  30. ball.velocity.x *= 0.97;
  31. ball.velocity.y *= 0.97;

Easey huh?! Have fun! If you do anything with this, please let us know so we can tell the world how awesome we are!

8 comments


  1. This is absolutely brilliant! One thing - you need to reedit this post to get rid of the & and > Strings.


  2. Yeah sorry, I can't seem to work WordPress out! If anyone can tell me how not to make crap then I'd love to hear it.

  3. Nail

    Do you have the complete code that we can download? I am interested to see the whole thing. Great idea and use of the technology btw!


  4. Thanks. Alas, the code for the 3D one is a hodgepodge of crap, mostly involving me not knowing how to use Papervision3D. The most interesting part of the code, and most of it really, is above. Make sure you download and use the Keys class posted about later in the blog.

  5. RaiulBaztepo

    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


  6. Thank you for this interesting post!


  7. really interesting, thanks.

 

Leave a Reply

Our Friends:

Powered by haXe / poko cms | Copyright 2008-09 TouchMyPixel