The color and wireframe materials we explored in part 1 will usually look a bit dull and flat, but there's a better option. In this tutorial we look further into the Away3D materials by adding bitmap textures, some shading and reflections to produce more realistic results.
One thing to remember when we say "realistic" is that Flash can't compete with multimillion games that runs off a graphics card with dedicated 3D processors. What you create using Flash will be less ambiguous in scope, but it can look really good if done properly. For now, properly done textures is the best way to provide fidelity to your Flash 3D project.
This tutorial builds on our other Away3D Tutorials. If you are new to Flash 3D, you may want to read these first. For each example, there's a complete source file. Just click the link to the accompanying Actionscript file to see how something was achieved. All of these examples require the file Cover.as. This file is used with the tutorials to prevent your machine from locking up as it tries to display many Flash files at once. If you are uncertain about how to use the sample Class files provided, check out this tutorial.
To get an idea of what you can achieve with bitmap materials, click on the movie below to randomize the textures.
(Basic09_BitmapMaterialExplorer.as)
The bitmap material that is the easiest to get started with is the plain BitmapFileMaterial. It will load a bitmap from a URL and display the result once loaded. It will not display the result automatically though, so you will need to either set the view to render on EnterFrame or use an Event listener. Let's first look at how you'd do this with the EnterFrame option.
var earthMaterial:BitmapFileMaterial = new BitmapFileMaterial("http://www.flashmagazine.com/articlefiles/away3d/resources/earthmap1k.jpg");
var sphere:Sphere = new Sphere({material:earthMaterial});
view.scene.addChild(sphere);
this.addEventListener(Event.ENTER_FRAME,update);
We first create the material and then pass it as a parameter to our sphere. We could also set the material using the "sphere.material" property We then add the sphere to the stage and ask it to run the method "update" on every EnterFrame. The update method is really simple, it just renders the view when it receives the EnterFrame event:
private function update(e:Event):void
{
view.render();
}
You can view the complete example here (Basic09_BitmapFileMaterial.as). The drawback of this approach is of course that nothing shows until the material is loaded. You can get around this by listening for when the bitmap has loaded using the LoadSuccess event. First you just create the sphere with a light blue color material:
sphere = new Sphere({material:"lightblue"});
view.scene.addChild(sphere);
view.render();
Then you create the BitmapFileMaterial and listen for the LoadSuccess event:
earthMaterial = new BitmapFileMaterial("http://www.flashmagazine.com/articlefiles/away3d/resources/earthmap1k.jpg");
earthMaterial.addEventListener(LoaderEvent.LOAD_SUCCESS,setMaterial);
When the bitmap is loaded, the swf will now call the setMaterial method, so we'll need to create this as well:
private function setMaterial(e:Event):void
{
sphere.material = earthMaterial;
view.render();
}
You can view the complete file here (Basic09_BitmapFileMaterial2.as). The advantage of this approach is that there is no need to run the view.render() method on every frame.

The bitmap that the material consists of can easily be accessed using the bitmap property:
var myBitmap:BitmapData = earthMaterial.bitmap
This is handy if you need to manipulate the bitmap after the texture have been applied.
There's also a Bitmap material that you can use with an embedded texture. This requires that you know how to embed bitmaps in your favorite editor. The code samples provided below are written as Flex Actionscript Projects, so if you use Flash CS3, make sure you read this tutorial that explains how to comment the Flex-specific code and embed the bitmap files in CS3. If you are using Flex Builder/Flash CS4 you'll only need to download the accompanying bitmaps to each code sample and place them in a subfolder named "resources".
In Flex Builder, you'll embed the bitmap where you define your class variables, usually at the top of each class.
[Embed(source="resources/earthmap1k.jpg")]
private var earthBitmap:Class;
Flash CS4 can also read and use these Embed tags so the process is the same. In Flash CS3 you have to import "earthmap1k.jpg" to your library, right click the imported file and set it to "Export for Actionscript" with the class-field set to "earthBitmap". When this is done, you can pass the embedded bitmap to the automagical init-object when you create the sphere and Away3D will apply a new BitmapMaterial to it.
var sphere:Sphere = new Sphere({material:earthBitmap});
You can view the complete Flex Builder/CS4 example here (Basic09_BitmapMaterial.as) or the Flash CS3 FLA file here (Basic09_BitmapMaterial.fla). This FLA also serves as an example of how you'd create a basic 3D scene with only timeline clode (no external class files). It requires that the Away3D source is copied into the same folder as the FLA.
If you don't want to use the init-object, so to declare the same using the more declarative syntax. First you'll need to import one of the Away3D utility classes:
import away3d.core.utils.Cast;
When this is done, you'll use the imported Cast-class to instantiate your bitmaps like this:
var earthMaterial:BitmapMaterial = new BitmapMaterial( Cast.bitmap(earthBitmap) );
var sphere:Sphere = new Sphere();
sphere.material = earthMaterial;
view.scene.addChild(sphere);
view.render();
The extra import is a little cumbersome, but it makes it possible to use the same Actionscript code in both Flex and CS3. Actionscript Class (Basic09_BitmapMaterial2.as) and FLA (Basic09_BitmapMaterial2.fla)
Note: If you were only using Flex Builder, you would probably do this in a more standard way like this:
var earthBitmapData:BitmapData = Bitmap( new earthBitmap() ).bitmapData;
var earthMaterial:BitmapMaterial = new BitmapMaterial( earthBitmapData );
Away3D supports all the image formats that Flash does, so Away3D will respect the transparent areas of a PNG. This can be used to achieve interesting effects such as animating skies above the earth (see an example in our Earth and Heaven tutorial).
You can also use MovieClips as textures. In this example we'll use one of the Away3D demo files called "caustics.fla". This contains a movieclip called "caustics" that we'll use as an animated texture on our sphere. Once again, there's a difference as to how you do this in the various authoring tools. To import a MovieClip from a SWf using Flex Builder, you'll do like this:
[Embed(source="resources/caustics.swf", symbol="caustics")]
private var causticsMovie:Class;
In Flash CS3, you'll just right click the MovieClip and set it to "Export for Actionscript" with the class-field set to "causticsMovie". After this, you create and apply the texture the same way in both tools:
var materialMovie:MovieClip = new causticsMovie() as MovieClip;
var causticsMaterial:MovieMaterial = new MovieMaterial( materialMovie );
var sphere:Sphere = new Sphere({material:causticsMaterial});
view.scene.addChild(sphere);
Actionscript Class (Basic09_MovieMaterial.as) and FLA (Basic09_MovieMaterial.fla)
If the MovieClip has interactivity in it, you can use this on the 3D object as well. All you need to do is to set the material to be interactive
earthMaterial.interactive = true;
Note: If you are using Flex, you can also use Flex Components as textures, complete with interactivity. Look here for an example. You can also control the movieclips if you store a reference to it as we did above. Let's add a listener for mouse clicks on the sphere:
sphere.addEventListener(MouseEvent3D.MOUSE_DOWN,sphereClick);
What we want to do is to start/stop the MovieClip when the user clicks the sphere. Our sphereClick method looks like this:
private function sphereClick(e:MouseEvent3D):void
{
if(isMaterialPlaying){
materialMovie.stop();
isMaterialPlaying = false;
} else {
materialMovie.play();
isMaterialPlaying = true;
}
}
Actionscript Class (Basic09_MovieMaterial2.as) and FLA (Basic09_MovieMaterial2.fla). This is the finished movie:
Just as with the color materials, there is a Phong shader version of the bitmap material as well. You create a PhongBitmapMaterial just as you do for the ordinary BitmapMaterial.
var earthMaterial:PhongBitmapMaterial = new PhongBitmapMaterial( Cast.bitmap(earthBitmap) );
var sphere:Sphere = new Sphere({material:earthMaterial});
view.scene.addChild(sphere);
As with ColorMaterials, the PhongBitmapMaterial requires that you add a light source to your scene. If you don't add one, the material will render as an ordinary BitmapMaterial.
var light:DirectionalLight3D = new DirectionalLight3D();
view.scene.addChild(light);
// Move the light away from the default 0,0,0 position so we'll see some reflection
light.y = 500;
light.x = -300;
light.z = -200;
(Basic09_PhongBitmapMaterial.as)

To see how the ambient, diffuse and specular properties affect the texture, see our former tutorial on the PhongColorMaterial. There is also a Phong material that can use MovieClips as texture. PhongMovieMaterial works just as the former example and also needs a light source.
var causticsMaterial:PhongMovieMaterial = new PhongMovieMaterial( new causticsMovie() as MovieClip );
var sphere:Sphere = new Sphere({material:causticsMaterial});
A bitmap tile is an image that can be repeated without the seams showing. By using a small repeatable image of grass, you'll be able to portray an entire lawn without adding gigantic images to your application. To tile an image, you'll need to use a special material called the TransformBitmapMaterial. The following code will create a transform-material and set it to be repeated 5 times across the objects surface:
var transformedMaterial:TransformBitmapMaterial = new TransformBitmapMaterial( image.bitmapData );
transformedMaterial.repeat = true;
transformedMaterial.scaleX = 0.2;
transformedMaterial.scaleY = 0.2;
You can also set an offset position and rotate the material:
transformedMaterial.offsetX = 25;
transformedMaterial.offsetY = 25;
transformedMaterial.rotation = 5;
(Basic09_BitmapMaterialExplorer.as)
You can't combine this material with Phong shading directly, but if you use it with the advanced CompositeMaterial you can achieve similar effects. We'll get back to the CompositeMaterial in a later tutorial.
The last material type in this tutorial is the Environment materials. These will give an illusion of a surface that reflects light and the surrounding objects. Reflecting what is really around a 3D object would require a lot of computation, but we can cheat a little. By using an image that we pretend is the reflection, we can achieve reasonable speeds. Be aware that reflective materials come at a cost when compared to bitmap materials. There is a slight CPU overhead to adding a reflection and a big overhead for refraction using the reflective plane that we'll discuss later in this tutorial.
Away3D has two materials that offer environment reflection, the EnviroColorMaterial and the EnviroBitmapMaterial. As you may have guessed by now - the first will use a color and the other will use a bitmap for texture. In addition they'll take a second parameter, a bitmap that will be used for the reflection.
var reflectiveMaterial:EnviroBitmapMaterial = new EnviroBitmapMaterial( Cast.bitmap( textureBitmap ), Cast.bitmap( reflectionBitmap ) );
reflectiveMaterial.reflectiveness = 0.3;
The reflectiveness property adjusts how much the reflection will "shine through" on the main material. You can adjust this from 0 (no reflection) to 1 (only reflection). One thing to note about reflections is that you only really see them when an object or the camera is moving. Another thing to note is that reflections work best on curved surfaces (not planes). Click and drag in the example below to see this.
(Basic09_EnviroBitmapMaterial.as)
When you move your mouse above the movie, the torus will start to rotate. When you click it, the rotation will stop and you can drag it around as you please. If you look carefully, you'll see that this isn't exactly how real reflections work, but it's more than good enough for realtime 3D.
Flash 3D is only in it's infancy. In terms of performance and quality it is now where computer games were about 8 years ago. Based on that fact, it's a little unfair to compare Flash 3D to games on the Xbox360, PS3 or Wii. This is however what the end users will do, so what can you do to improve the look of your Flash 3D scene beyond the materials discussed here? There's several tricks and the key is most often in the materials.
Finding the right texture to use in your materials is the first step. If you Google "3d texture maps" you'll find hundreds of sites offering bitmap textures. The general rule is that you'll get what you pay for. Finding free textures that are high quality takes time, so for many it'll be cheaper to just buy them. Many sites offer pre made collections of textures for various purposes. Bricks, crates, wood, water, metal and all other possible materials are found in these packages so they can take you far.
There's also software out there that will let you generate textures for your models. In our initial example where you could click to change materials, we have used some really high quality textures created with a PC software called Genetica. This software will allow you to create an endless amount of very high quality textures that can be "tiled".
After finding the right texture, the next step is to add more depth to your scene. Think about this - if you move around in an outdoor scenery (as in a FPS game), the shadows will always be in the same place since the sun isn't moving noticeably. This makes it possible to "pre-bake" the textures - adding the shadows onto the texture itself. If done right, this will make your 3D environment look really rich. The process of baking textures cannot be done in the 3D engine itself, but must be done in a modeling application (3DS MAX, Maya, Blender and many others) that support "baking" textures.
There's also two more kinds of materials in Away3D; the powerful Dot3 material and the CompositeMaterial that allow you to combine several materials into one. Both of these offer a lot of possibilities and we'll get back to them in separate tutorials later. As a teaser, look what the Dot3 material can do to the simple torso model below.
By adding a Dot3 bitmap material with a Normal Map, this simple model looks like it's built of thousands of polygons! Away3D even has a class to generate these Normal maps and also supports bump mapped surfaces.
Background image for article header was based upon an image by Image Editor and used under a CC license. Look at how those stars shine :)
Jens has been working with Flash since version 3 came out. Since then, he's been an active member of the Flash community. He's created more than a hundred Flash games (thus the name of his blog) but he also creates web/standalone applications, does workshops and other consulting. He loves playing with new technology and he is convinced that the moment you stop learning you die (creatively speaking). Jens is also the Editor of this website.
Next tutorial:
Setting up Subversion with Adobe Flash Builder 4 (Beta)
Previous tutorial:
Away3D Basics 6 - The Color Materials
@zontaluma Away3D supports the use of models in 3DS, ASE, Collada, KMZ, Md2 and OBJ formats. Both Max and Cinema 4D supports multiple of these formats, so that shouldn’t be any issue.
J
Hello,
I’m trying have a object 3D with Away3D, but with not Embed material. Well, i’m doing this tutorial and apply what it says in the first part, before the Embed section.
I have this code:
var temp:BitmapFileMaterial = new BitmapFileMaterial("direction/image.jpg");
var myBitmap:BitmapData = temp.bitmap;
NormalMaterial = new Dot3BitmapMaterialF10(myBitmap, myBitmap2);
myBitmap2 is a normal map generated from full mesh. It’s charge in the same way of myBitmap.
The problem is that the model charge but all gray.
What could be happen?
@cesar I’m not sure I understand this. “direction/image.jpg” is a file on your computer, but “myBitmap” is the generated Normal map? If so, I would need too see that NormalMap map to be able to help you.
Please post a screenshot of the NormalMap to the Away3D Google Group and I’ll see if I can take it from there?
http://groups.google.com/group/away3d-dev
J
@Jens C Brynildsen I’m using the example Pedestal.as, all the image and model is the same, including the normal map. I’m trying of not used Embed sentence. The idea is charge the texture at the moment i run the example, not put inside the executable.
Thank for your quick answer.
@cesar Remember that a BitmapFileMaterial will not load right away. It takes a few milliseconds until it loads so in your example, you are probably creating the material without the texture.
Try using an event listener as explained initially in this article:
earthMaterial.addEventListener(LoaderEvent.LOAD_SUCCESS,setMaterial);
J
@Jens thank you very much. You are all right, i miss that part.
Sorry about my noob problem.
Hi,I am from china and I want to learn more about away3d for developing something,I have readed all the tutorials,and I want to learn more about the away3d, but the away3d website(http://www.away3d.com/) can’t open,who can recommend some tutorials resource website or pdf about away3d??thank you very much!!
this is my email:csliuxingtan (at] 163.com
@jackliu Away3d.com blocked from China? That’s really odd. Anyway - the best way to learn more is really to create projects, dig into the source code and ask questions on the DevList http://groups.google.com/group/away3d-dev/.
If you setup subversion (SVN) on your computer and download the away3d source, you’ll find the latest documentation there as well. Best of luck!
J
True Phong Shading in Flash 9.
http://blog.glowinteractive.com/index.php/2009/11/true-phong-shading-in-flash-9/
Everyone to their bases - Flash is under attack!
Flash on the beach 2009 - Day 1
Stay current on what's happening in Flash business. Sign up now for the Flashzine newsletter.
Hello. I’ve been working with these tutorials for two weeks and things are running smoothly…so far. I was wondering if Away3D supports Studio Max or Cinema 4D? Is it possible to import 3D models form either or both software packages?