Adding Normal Maps in Away3D 4.0


Normal maps are used in order to add detail to objects without using more polygons and vertices. This technique is used quite often in video games because it allows for the objects to look very good

Loading a Model in Away3D 4.0


As of the time of this writing there seems to be a lack of tutorials on how to load 3d models in Away3D 4.0. With the release of Flash Player 11, Adobe has really stepped up its game in 3D graphics

3D Terrain Generation


In recent years computer graphics applications have become more realistic and what was once considered superfluous commodities (i.e. realistic lighting, reflections, and real-time behavior) have

Research Paper Accepted to CGI 2012

Posted on by Carlos Posted in Diary | Leave a comment

CGI 2012

Some days ago my professor Andres Navarro invited me to write and submit a short paper on my Matsumoto Castle project that I had created last semester. He told me that even though the chances of getting the paper accepted by the reviewing committee were slim it would serve me well as a learning experience.

For the following week I spent quite a few evenings writing and proof-reading the draft in an effort to make it as legible and concise as possible.

To my surprise, today I received an e-mail in the morning informing me that the short paper that I had written had been accepted for inclusion in this year’s conference!

To me this is quite an achievement because this paper is my first scientific publication and what makes me even more proud is the fact that I’m still an undergraduate student.

This is the e-mail I received from the conference committee:

Accepted Short Paper

Programando en Python – Parte 1

Posted on by Carlos Posted in Programming, Python, Tutorials | 1 Comment

Parte 1 de una serie de tutoriales diseñados para enseñar a programar en el lenguaje de programación Python.
En este video se muestra donde bajar el instalador y como hacer un programa básico.

 

Adding Normal Maps in Away3D 4.0

Posted on by Carlos Posted in Away3D | 2 Comments

Normal maps are used in order to add detail to objects without using more polygons and vertices. This technique is used quite often in video games because it allows for the objects to look very good without affecting performance.

With the release of Flash Player 11, the power of the GPU is finally within the reach of Flash developers. This means that optimization techniques such as applying normal maps to objects are finally a reality.

In the last post I showed how to load a 3D model in Away3D. In this post I will show you how to add a normal map to add realism to a low polygon mesh. These are the two versions, the one with the normal map applied and the other one without the normal map.

With Normal Map:

Get Adobe Flash player

Without Normal Map:

Get Adobe Flash player

Believe it or not the two versions have the same vertex count. Adding a normal map can increase the realism as it adds details to an otherwise “flat” object. In order for this technique to work you need to have a normal texture image which you can generate from a high polygon version of the object.

Download the source code here

This is the part where you add the normal map:

private function initMesh():void
{
	// Set the material for the mesh
	var crateMaterial:BitmapMaterial = new BitmapMaterial(Bitmap(new CrateSkin()).bitmapData);
        // Add the normal map
	crateMaterial.normalMap = Bitmap(new CrateMap()).bitmapData;
	crateMaterial.lights = [light0, light1];
	crateMaterial.specular = 0.4;
 
	Loader3D.enableParser(Max3DSParser);
	loader = new Loader3D();
	loader.parseData(CrateMesh, null, new AssetLoaderContext(false));
	for (var i:int = 0; i < loader.numChildren; i++)
	{
		var mesh:Mesh = Mesh(loader.getChildAt(i));
		mesh.scale(20);
		mesh.material = crateMaterial;
	}
 
			view.scene.addChild(loader);
}

This is the full code:

package
{
	import away3d.cameras.lenses.PerspectiveLens;
	import away3d.containers.ObjectContainer3D;
	import away3d.entities.Mesh;
	import away3d.events.AssetEvent;
	import away3d.library.AssetLibrary;
	import away3d.containers.View3D;
	import away3d.debug.AwayStats;
	import away3d.entities.SegmentSet;
	import away3d.lights.PointLight;
	import away3d.loaders.Loader3D;
	import away3d.loaders.misc.AssetLoaderContext;
	import away3d.loaders.parsers.OBJParser;
	import away3d.loaders.parsers.Parsers;
	import away3d.loaders.parsers.Max3DSParser;
	import away3d.materials.BitmapMaterial;
	import away3d.materials.methods.EnvMapMethod;
	import away3d.primitives.LineSegment;
	import away3d.events.LoaderEvent;
	import away3d.primitives.WireframeGrid;
	import flash.display.Bitmap;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Vector3D;
	import flash.net.URLRequest;
	import flash.display.Sprite;
	import flash.events.Event;
 
	/**
	 * ...
	 * @author Carlos Perea
	 */
	[Frame(factoryClass="Preloader")]
	public class Main extends Sprite
	{
		[Embed(source="crate.3ds", mimeType="application/octet-stream")]
		private var CrateMesh:Class;
 
		[Embed(source="crate.jpg")]
		private var CrateSkin:Class;
 
		[Embed(source="crateHeightMap.jpg")]
		private var CrateMap:Class;
 
		private var view:View3D;
		private var loader:Loader3D;
		private var grid:WireframeGrid;
		private var currentDelta:Number = 0.0;
		private var lengthAxis:Number = 250;
		private var light0:PointLight;
		private var light1:PointLight;
		private var circularMotion:Number = 0.0;
		private var viewDistance:Number = 60;
		private var viewRotationSpeed:Number = 0.005;
 
		public function Main():void
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		private function init(e:Event = null):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
 
			// entry point
 
			setUpView();
			setUpLights();
			initMesh();
 
			addEventListener(Event.ENTER_FRAME, update, false, 0, true);
			addEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelEvent, false, 0, true);
		}
 
		private function setUpView():void
		{
			view = new View3D();
			view.width = width;
			view.height = height;
			view.backgroundColor = 0x333333;
			view.antiAlias = 4;
			view.camera.lens.near = 0.2;
			addChild(view);
 
			addChild(new AwayStats(view));
 
			view.camera.position = new Vector3D( -viewDistance, viewDistance, viewDistance);
			view.camera.lookAt(new Vector3D(0, 0, 0));
			(view.camera.lens as PerspectiveLens).fieldOfView = 60;
 
			grid = new WireframeGrid(20, 500, 0.1, 0x666666);
			view.scene.addChild(grid);
		}
 
		private function setUpLights():void
		{
			light0 = new PointLight();
			light0.specular = 0.3;
			light0.color = 0xFFFFFFFF;
			light0.diffuse = 0xFFFFFF;
			light0.position = new Vector3D(0, 0, 100);
			view.scene.addChild(light0);
 
			light1 = new PointLight();
			light1.specular = 0.3;
			light1.color = 0xFFFFFF;
			light1.diffuse = 0xFFFFFF;
			light1.position = new Vector3D(0, viewDistance, -100);
			view.scene.addChild(light1);
		}
 
		private function update(event:Event):void
		{
			view.camera.x = Math.cos(circularMotion) * viewDistance;
			view.camera.z = Math.sin(circularMotion) * viewDistance;
			view.camera.y = viewDistance;
			light0.position = view.camera.position;
			view.camera.lookAt(new Vector3D(0, 0, 0));
			circularMotion += viewRotationSpeed;
			view.render();
		}
 
		private function initMesh():void
		{
			// Set the material for the mesh
			var crateMaterial:BitmapMaterial = new BitmapMaterial(Bitmap(new CrateSkin()).bitmapData);
			crateMaterial.normalMap = Bitmap(new CrateMap()).bitmapData;
			crateMaterial.lights = [light0, light1];
			crateMaterial.specular = 0.4;
 
			Loader3D.enableParser(Max3DSParser);
			loader = new Loader3D();
			loader.parseData(CrateMesh, null, new AssetLoaderContext(false));
			for (var i:int = 0; i < loader.numChildren; i++)
			{
				var mesh:Mesh = Mesh(loader.getChildAt(i));
				mesh.scale(20);
				mesh.material = crateMaterial;
			}
 
			view.scene.addChild(loader);
		}
 
		private function mouseWheelEvent(event:MouseEvent):void
		{
			currentDelta = event.delta;
			if (currentDelta < 0)
				viewDistance -= 2;
			else if (currentDelta > 0)
				viewDistance += 2;
		}
 
	}
 
}

Loading a Model in Away3D 4.0

Posted on by Carlos Posted in Away3D | 3 Comments

As of the time of this writing there seems to be a lack of tutorials on how to load 3d models in Away3D 4.0. With the release of Flash Player 11, Adobe has really stepped up its game in 3D graphics and the latest version of Away3D is geared to taking advantage of this fact.

In this tutorial I will show you how to load and display a 3D model complete with materials using Away3D 4.0. The model is from Left 4 Dead (Source)

This is the result (Flash Player 11 required):

Get Adobe Flash player

Read more

3D Terrain Generation

Posted on by Carlos Posted in 3D | 1 Comment

In recent years computer graphics applications have become more realistic and what was once considered superfluous commodities (i.e. realistic lighting, reflections, and real-time behavior) have become necessities that the end-users have grown accustomed to see.
Terrain generation is a very interesting topic within the realm of computer graphics due to its importance and pertinence to today’s graphical applications.
Examples of applications that heavily rely on detailed modeled terrains are: