This site is now just an archive over the rise and fall of Flash. The domain flashmagazine.com is available for sale
Login | Register
Away3D Basics 6 - Bitmap materials

Away3D Basics 6 - Bitmap materials

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.

Prerequisites

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. 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.

This content requires Flash Player 9 (or a more recent version). You need to upgrade your Flash Player

(ExBitmapMaterialExplorer.as)

Basic texturing with bitmaps

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 (ExBitmapFileMaterial.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 (ExBitmapFileMaterial2.as). The advantage of this approach is that there is no need to run the view.render() method on every frame.

image

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 (ExBitmapMaterial.as) or the Flash CS3 FLA file here (ExBitmapMaterial.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 (ExBitmapMaterial2.as) and FLA (ExBitmapMaterial2.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).

Using a MovieClip as a texture

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 (ExMovieMaterial.as) and FLA (ExMovieMaterial.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 (ExMovieMaterial2.as) and FLA (ExMovieMaterial2.fla). This is the finished movie:

This content requires Flash Player 9 (or a more recent version). You need to upgrade your Flash Player

Getting fancy with Phong shading

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;

(ExPhongBitmapMaterial.as)

image

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});

Tiling bitmaps

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;

(ExBitmapMaterialExplorer.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.

Adding reflections - The Enviro materials

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.

This content requires Flash Player 9 (or a more recent version). You need to upgrade your Flash Player

(ExEnviroBitmapMaterial.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.

Getting the best results

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.

This content requires Flash Player 9 (or a more recent version). You need to upgrade your Flash Player

(ExPedestal.as)

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 :)

 

About Jens C Brynildsen

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.

Get new stories first

Click to follow us on Twitter!

 

Comments


Posted by zontaluma on 06/10 at 04:50 PM

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?


Posted by Jens C Brynildsen on 06/15 at 01:45 PM

@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


Posted by cesar on 12/03 at 08:44 PM

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(myBitmapmyBitmap2); 

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?


Posted by Jens C Brynildsen on 12/03 at 09:22 PM

@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


Posted by cesar on 12/03 at 09:43 PM

@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.


Posted by Jens C Brynildsen on 12/03 at 11:12 PM

@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


Posted by cesar on 12/04 at 07:01 PM

@Jens thank you very much. You are all right, i miss that part.
Sorry about my noob problem.


Posted by jackliu on 01/03 at 04:14 AM

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


Posted by Jens C Brynildsen on 01/04 at 12:18 PM

@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


Posted by tKady on 01/29 at 01:32 PM

Posted by Binxalot on 07/21 at 06:21 PM

I can’t seem to use texture from a file that references a URL with the dot3 shader.  Here is my code, can anyone help me with this?  It works fine if I just assign the bitmap texture to the cube, but if I make the texture dot3 it will show a blank screen..

Code;
——-
var diffuseMaterial:BitmapFileMaterial = new BitmapFileMaterial(“http://www.mywebsite/somepicture.jpg”);
        var normalMaterial:BitmapFileMaterial = new BitmapFileMaterial(“http://www.mywebsite/somepicture.jpg”);
        var cubeNormalMaterial:Dot3BitmapMaterial = new Dot3BitmapMaterial(Cast.bitmap(diffuseMaterial), Cast.bitmap(normalMaterial));
       
               
        var cube1:Cube = new Cube({material:cubeNormalMaterial});
        view.scene.addChild(cube1);


Posted by Jens C Brynildsen on 08/15 at 10:52 AM

@Binxalot I’m guessing that you’ve probably solved this by now? Anyway, if you look a little further up the comments you should find what you need.

Please post questions like this on the DevList http://groups.google.com/group/away3d-dev/ and you’ll see much better response time :-)

J


Posted by jeanramirez on 04/30 at 07:12 PM

Hi i’m using movie clips as material but i want to know if it’s to possible to add some interaction to the movie clips that i’m using, i mean, if i put some clips as buttons inside the movie clip material it can work, cause i’m trying to using mouse3D with no results… i’m tryig using script like this…

cubo1.btnInside.addEventListener(MouseEvent3D.MOUSE_DOWN,bajar);

//cubo1 is the object 3D i tried this using the material name but doesn’t work neither…

function bajar(e:MouseEvent3D):void{
  TweenMax.to(cubo1.btnInside,1,{scaleX:3,scaleY:3});
  trace(“doing some”);
}


Posted by Jens C Brynildsen on 05/24 at 09:59 AM

@jeanremirez Just add an ordinary MouseEvent.CLICK listener on the MovieClip material and that should do the trick?


Posted by northmantif on 07/04 at 12:59 PM

what is :
earthMaterial.addEventListener(LoaderEvent.LOAD_SUCCESS,setMaterial);

what is “LoaderEvent” ? I do not have such Event in the Away3D 3.6 I use. Isn’t the tutorial created in older versions of Away3D?
Thanks in advance for clearing my doubts.


Posted by Jens C Brynildsen on 08/08 at 11:14 AM

@northmantif Good catch. I’ll have to fix that. It should be a MaterialEvent instead. Sorry about that one.

J


Posted by SuperPerfundo on 09/08 at 06:51 PM

Hi Jens I am a beginner using away3d 3.6 and flashbuilder 4.5.

I want to create an interactive material(with mouse events) in Flash CS5 and apply it to a custom 3d object (a mobius strip from Blender). I used Prefab3d to convert my collada dae to an AS3 class, and am able to apply colormaterial to it, but I haven’t been able to get embedded textures to work. How do I correctly load and map my material?

The object looks like this: http://mathworld.wolfram.com/images/eps-gif/MobiusStrip_1000.gif

I want to have 2 different texture on either side.

I am a true newbie when it comes to AS3 so be gentle.


Posted by SuperPerfundo on 09/08 at 06:55 PM

OH and btw, thanks so much for these tutorials. They have been immensely helpful in learning AS3 + Away3d.


Posted by Jens C Brynildsen on 11/25 at 10:05 AM

@SuperPerfundo Thanks for kind words. Questions like this is always easier to get rapid answers to if you go to the Away3D Forums (Given how long it’s been since I had time to update this site). Check out http://away3d.com/forum/. Lot’s of nice ppl there!

Submit a comment

Only registered members can comment. Click here to login or here to register