Flash 8 Example 3: Textures on Spheres

The example below shows a progression of taking a texture map from a Bryce 3D texture page, and mapping it to a sphere using the various methods of the BitmapData class. I’ve been very excited about the ability to push around the pixels but hadn’t really taken it for a spin (har har).

The reason for doing this example is to have interesting spinning globes added to my thrust example for my eventual site redesign. I’ve been playing with this example for the last week, and while it isn’t completely done, I wanted to go ahead and quit obsessing and post it ;) Click the steps 1 through 5 to see the progression. There is a description of what is going on at each step below.

Step 1, Find the picture: I did a Yahoo! Image Search for “earth image” and found SnyderWeb (heh) which has excellent images of all of the planets and notable moons from our solar system. I took this enormous image and shrunk it down to 300 by 150 like you see in the example.

Step 2, Resize per line: The image starts as a rectangle, so the poles are really stretched. Each line of pixels needs to become two times the number of pixels needed (front and back of planet) to be displayed ob screen for that latitude. I do the calculations on how many pixels I need per line to make a circle, and use draw() to scale the big line down to the size of the line I need.

The picture above represents the final product of the full image with each line scaled as needed (left justified). In reality I am also using the copyPixels() method to duplicate each line (though not shown above). This will save calculation time when I need to be able to display the part of the globe where there would be a seam.

Step3, Give it a whirl: For my first attempt at making the globe spin, I go through each line of the warped image, and display the correct number of pixels to make a circle. To make the rotating effect, I am using a ratio that represents the amount to rotate out of one full rotation. I then find the pixel in the line that is at the same ratio and start displaying the pixels from there.

Each line then moves at different rates because the ratio is the same per line, but the line length is different. At .5 ratio, a line of 10 pixels would start copying from 5, but in a line of 50 pixels, it would start copying from pixel 25.

While this give an animating globe, you will notice that the continents don’t actually curve around the surface of the earth. It doesn’t look quite right (though I was still pretty excited when I got this far and Flash 8 was still running like a dream).

I’ve also added a couple of filter effects to make the planet have some nice lighting. Notice that the bright spot is not just a white alpha gradient. It is a blurred shape with a screen filter to actually add the channels together to change the overall lightness under the hot spot.

For my website purposes I really am going to stop here. My planets will be more like Saturn or Jupiter (amorphous banded things), so the curvature won’t be apparent. Also, as you’ll notice in the next step, the processor is going to be hit pretty hard.

Step 4, curving the X axis: Let the processor abuse begin! This new graphic warping of the X-axis can’t be done one time at the beginning like Step 2. This needs to be done every step of the rotation because when pixels are at the edges they will be crunched, and when in the middle they will be stretched. During a full revolution, every pixel of the base graphic will at some point be at the edge and also at the middle.

This being said, I can do one set of calculations once at the beginning of the animation. For each row of X pixels, I can calculate the distortion deltas. At each rotation step I can just apply this array of distortion values to the currently displayed pixels. for instance, the array may be something like [4,3,2.5,2, etc.] which means I should take the first four pixels of the line and draw them as one pixel (somehow). then for the next new pixel of the graphic I take the next three pixels and make them one. By the time you reach the middle of the graphic, the values are substantially below 1, because instead of multiple pixels becoming one, the pixels are being stretched/duplicated.

Once this is done we have a globe where the continents curve away at the sides. There are now just two problems. First, the processor is running very slowly. But the more serious problem is that my continents are too short now (well, they actually always were). To counteract the processing issue, I’m caching each calculated bitmap. After one rotation, if I call for an image that I have created once, I can pull it out of an array, rather than recalculating. You’ll notice a really big performance improvement after one rotation, but be aware that it comes at a cost. To cache the images, you have to store them in memory. For the 100 unique calculated states <eg> it takes about 8MB of memory.

Step 5, back to the initial Warp:
So the last image warp (Y axis to show curvature) can be done in the beginning since since pixels never move along the Y axis. To do this, I just repurposed my line warping function and applied it vertically instead of horizontally. Once this is done all of the continents are the right aspect ratio, and then I declare victory.

What is next? So I’m happy with where things are with this, but I do have some more work to do.

  • work on anti-aliasing better. Some of my warping scripts should be doing a better job of smoothing. You will notice that some of the coasts are a bit off where a pixel is sticking out here and there. The more warps that are applied, the more pronounced the effect is.
  • Optimize the code. I think I can squeeze out some more performance by re-examining some of the code.
  • Throw it away and do a poly-based 3D texture mapper. This works fine for X-axis rotation, but If I wanted to play god and roll the earth like a pool ball, this script just won’t cut it.

18 thoughts on “Flash 8 Example 3: Textures on Spheres

  1. Have you seen how Andre Michelle is tackling this very issue in his earth demo?

    A wacky workaround to get it to work, but I think he is using the displacement map filter to do let the compiled plugin code do the heavy-lifting rather than letting AS2 handle it. Not sure if this is applicable to your example since he mentions his technique is limited to 127px. square displacement maps.

  2. Hi. This is a great example. I am impressed other you examples. I must ask my company to buy the version 8 ASAP:)
    P.S. I am a reader of your great book, FlashMX 2004 Game Programming and I love your book.

  3. Hi,
    I am a student and would like to implement this on my project website. Can you tell me how to do this. I am fairly new to Flash and am basically reading through my books on how to work in Flash. If possible, can you also send me the step by step ways of making that globe. I got the jpg file that you talked about and want to get started on this. Thank you

  4. Hey, I’ve been trying to get that “spinning” 3D effect in Flash for months and I can’t figure out how! Would you mind putting a link to the FLA or a tut up here?

  5. I’m very interested on this!!!! :O :O :O

    i need to do a Earth globe with 1 interactive button for each Country…

    I tried to do it with a lot of frames and duplicating information (it’s a huge horror) for achieving the 3d aspect.

    Could u guide me or give me some examples of how could i make it with a plane 2d world movieclip (with the buttons inside) and converting it to a 3d world globe like in your example? Thank u so much!!!!

  6. Hi, this is very interesting. I saw a lot of people who want to learn more about it, but not see an answer. Is it personal? And

  7. Hi, this is very interesting. I saw a lot of people who want to learn more about it, but not see an answer. Is it personal? And if there is a way to learn, please give me an answer.

  8. wow, im just about to start a dissertation based upon a space theme for e-learning, this would be perfect, dont have a clue how to do it after reading tho :S
    cool tho…

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>