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.
Digg this!
August 15th, 2005 at 7:42 pm
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.
August 15th, 2005 at 8:45 pm
Damn nice example. and once the bitmap cache kicks in its not to bad frame rate wise.
WEll done dude!
Cam
August 16th, 2005 at 2:18 am
Great example,
well done mate
August 17th, 2005 at 7:37 am
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.
September 13th, 2005 at 7:42 am
yup, when clicking on the last button crashes my browser. bit weird, but well..
January 5th, 2006 at 1:24 am
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
January 26th, 2006 at 1:59 pm
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?
February 4th, 2006 at 6:52 am
Unbelievable !
I’m very impressed.
Great job !
Garga.
April 25th, 2006 at 6:44 am
Any chance we can get to look at the source code?
July 10th, 2006 at 10:43 pm
This page is the tutorial, read it carefully.
February 16th, 2007 at 3:27 am
Thanks for a nice post such as this.
March 1st, 2007 at 6:38 pm
Hello, I am interested in making a sphere rotate just as this one does. can you send me the source code.
March 6th, 2007 at 3:39 am
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!!!!
April 25th, 2007 at 12:08 pm
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
April 25th, 2007 at 12:09 pm
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.
September 1st, 2007 at 3:34 am
exellent
November 13th, 2007 at 4:44 am
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…
January 1st, 2008 at 5:54 am
Hey,
This is very good Example,
i am proud of u.