Away3D实例教程 - 贴图(Dot3BitmapMaterial)

本例包含的内容有:

  • normal map
  • Dot3BitmapMaterial

转载请注明出处:nooon.cnblogs.com

本例子将讲解如何使用normap map 和Dot3BitmapMaterial做一堵涂鸦墙。

本例会用到的图片:

normalmap

normalmap.png ,记录墙面每点的法线信息(稍后解释)

doodle

doodle.jpg 用作墙体上的涂鸦内容。

看最终效果:点此观看(拖动鼠标,旋转摄像机;不同角度看看Dot3BitmapMaterial对光反射的变化。同时看墙后方的PhongBitmapMaterial类位图材质)。

先看看什么是normal map

normal map ,可以帮助低面模型(面数少的模型)生成更为现实的效果。比如在本例中,涂鸦墙墙体只是一个矩形,矩形每个面都是平整的。不会有砖体,这里我们就是借助上面的normalmap.png这张图片做normal map生成墙表面凹凸不平的效果!如果不用Normal Map 的话,我们当然也可以用3D软件做出一个有凹凸不平的效果的墙体(高面模型),然后用BitmapMaterial对模型贴图。但很显然这样的模型面数多,渲染时会拖垮电脑。现在3D游戏都会用normal map 让3D让模型更贴近真实。

normal map之所以有此之能是因为normal map能记录物体表面各点的位置信息。normal map实质是一张没什么特别的RGB图像,但这样的RGB图片的每点的R、G、B值是用来记录该点的空间位置信息的(分别对应X、Y、Z)。这样3D引擎就可以根据RGB值 计算使用Normalmap的模型的表面每个小曲面的垂线方向即法线,从而计算出模型表面各点对光的反射方向。所以normal map 称之法线图。

 

normal_map_example

更多内容看:http://www.blacksmith-studios.dk/projects/downloads/bumpmapping_using_cg.php

如何的到normal map 呢?

可以到网上找。

dadfa

当然可以自个做,3D软件大多可以,不过这里介绍一个很有趣的方法,看http://zarria.net/nrmphoto/nrmphoto.html

最后按惯例加上本例子的源代码:

   1:  package
   2:  {
   3:      import away3d.cameras.HoverCamera3D;
   4:      import away3d.containers.View3D;
   5:      import away3d.core.utils.Cast;
   6:      import away3d.lights.DirectionalLight3D;
   7:      import away3d.materials.PhongBitmapMaterial;
   8:      import away3d.materials.Dot3BitmapMaterial;
   9:      import away3d.primitives.Cube;
  10:      
  11:      import flash.display.Sprite;
  12:      import flash.events.Event;
  13:      import flash.events.MouseEvent;
  14:      [SWF(width="500",height="500",frameRate="30", backgroundColor="#000000")]
  15:      public class normalMapping extends Sprite
  16:      {
  17:          private var view:View3D;
  18:          private var cam:HoverCamera3D;
  19:          private var cube:Cube;
  20:          private var doodle:Dot3BitmapMaterial;
  21:          private var originalmap:PhongBitmapMaterial;
  22:          private var light:DirectionalLight3D;
  23:          
  24:          private var mouseDown:Boolean;
  25:          private var lastMouseX:Number;
  26:          private var lastMouseY:Number;
  27:          private var lastPanangle:Number;
  28:          private var lastTiltangle:Number;
  29:          private var cameraSpeed:Number;
  30:   
  31:          [Embed(source="resources/doodle.jpg")] private var doodleImage:Class;
  32:          [Embed(source="resources/normalmap.png")] private var normalmapImage:Class;
  33:          public function normalMapping()
  34:          {
  35:              //初始3D世界(摄像机、视口。。)
  36:              init3D();
  37:              //创建场景里的3D模型(建一立方体用作涂鸦的墙体)
  38:              createSce();
  39:              //添加侦听器(监测鼠标拖动,如拖动则旋转摄像机;并且每帧渲染)
  40:              addEventListener(Event.ENTER_FRAME,update);    
  41:              stage.addEventListener(MouseEvent.MOUSE_DOWN,m_down_h);    
  42:              stage.addEventListener(MouseEvent.MOUSE_UP,m_up_h);
  43:          }
  44:          private function init3D():void
  45:          {
  46:              cam=new HoverCamera3D();
  47:              cam.distance=1200;
  48:              cam.panangle=cam.targetpanangle=30;
  49:              cam.tiltangle=cam.targettiltangle=0;
  50:              cam.mintiltangle=-90;
  51:              view=new View3D({camera:cam,x:250,y:250});
  52:              addChild(view); 
  53:          };
  54:          private function createSce():void
  55:          {
  56:              //控制摄像机旋转速度
  57:              cameraSpeed=.3;
  58:              // 创建直线光源,Dot3BitmapMaterial需要光源。没有光源与普通的BitmapMaterial无异
  59:              var light:DirectionalLight3D = new DirectionalLight3D({brightness:1,ambient:0.25, diffuse:0.75, specular:0.9});
  60:              light.x = 5000;
  61:              light.z = -50000;
  62:              light.y = 1000;
  63:              view.scene.addChild(light);
  64:              //新建originalmap,是PhongBitmapMaterial类型,用作墙后方贴图
  65:              originalmap=new PhongBitmapMaterial(Cast.bitmap(new doodleImage()));
  66:              //新建doodle,是Dot3BitmapMaterial类型,用作墙前方贴图
  67:              doodle=new Dot3BitmapMaterial(Cast.bitmap(new doodleImage()),Cast.bitmap(new normalmapImage()),{smooth:true, precision:6});
  68:              //新建一立方体,用作墙体
  69:              cube=new Cube({width:600,height:300,depth:20,segmentsW:2,segmentsH:2});
  70:              //分别为墙体前后方贴图            
  71:              cube.cubeMaterials.front=doodle;
  72:              cube.cubeMaterials.back=originalmap;
  73:                              
  74:              view.scene.addChild(cube);
  75:          };
  76:          private function update(e:Event):void
  77:          {
  78:              if(mouseDown)
  79:              {
  80:                  cam.targetpanangle=cameraSpeed*(stage.mouseX-lastMouseX)+lastPanangle;
  81:                  cam.targettiltangle=cameraSpeed*(stage.mouseY-lastMouseY)+lastTiltangle;
  82:              };
  83:              cam.hover();
  84:              view.render();
  85:          };
  86:          private function m_down_h(e:MouseEvent):void
  87:          {
  88:              mouseDown=true;
  89:              lastMouseX=stage.mouseX;
  90:              lastMouseY=stage.mouseY;
  91:              lastPanangle=cam.targetpanangle;
  92:              lastTiltangle=cam.targettiltangle;
  93:          };
  94:          private function m_up_h(e:MouseEvent):void
  95:          {
  96:              mouseDown=false;
  97:          };
  98:      }
  99:  }

 

posted @ 2009-06-04 18:43  nooon  阅读(3191)  评论(0编辑  收藏  举报