Away3D基础教程(三):三维世界的灯光
目前Away3D 4.0中提供两种光源
DirectionalLight(平行投射光源):这货可以用来模拟探照灯,或是月光透过窗户的效果
PointLight(点光源):这是最常用到的,我们可以用它来模拟太阳,月亮,或是台灯的灯炮
平行投射光的创建方法为
var _directionalLight:DirectionalLight=new DirectionalLight();
_directionalLight的构造函数里三个值 用来描述平行光的方向 x y z 其范围都为 -1 到1,这里参数留空用的是默认值。
PointLight经常用来模拟我们生活中的 蜡烛 灯泡这样的小型光源。
var _pointLight:PointLight=new PointLight();
点光源不存在方向问题。
在3D世界里 我们通常不会只用一盏灯去模拟所有的光源。Away3d这里为我们提供了一个StaticLightPicker方法。我们可以将所有灯光放置于这个灯光容器里。代码:
var _light:StaticLightPicker=new StaticLightPicker([_directionalLight,_pointLight]);
然后我们需要将灯光运用在这个世界里,模型的贴图可以受到光的影响 不管是TextureMaterial还是ColorMaterial都有lightPicker属性。我们只需要将StaticLightPicker类型对象赋予给它即可例如 :
_planeMesh.material.lightPicker = _light;
_cubeMesh.material.lightPicker = _light;
这样我们的模型就可以受到光照的影响了
我们可以建立个plane做地面来打开阴影 这样感觉就更酷了。阴影的添加方式是
_planeMaterial.shadowMethod = new FilteredShadowMapMethod(_directionalLight);
此例在Away3D基础教程(一)的基础上添加了Cube模型、灯光和影子效果:效果演示如下:
完整代码:
package { import away3d.containers.View3D; import away3d.entities.Mesh; import away3d.events.MouseEvent3D; import away3d.lights.DirectionalLight; import away3d.lights.PointLight; import away3d.materials.ColorMaterial; import away3d.materials.lightpickers.StaticLightPicker; import away3d.materials.methods.FilteredShadowMapMethod; import away3d.materials.TextureMaterial; import away3d.primitives.CubeGeometry; import away3d.primitives.PlaneGeometry; import away3d.primitives.SphereGeometry; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Vector3D; import flash.display.*; import away3d.utils.Cast; /** * ... * @author yl */ [SWF(width='800',height='600',frameRate="60", backgroundColor="0x000000")] public class MyAway3d_1 extends Sprite { //floor的贴图图片 [Embed(source = "../embeds/myAway3d_1.jpg")] private static var FloorMaterial:Class; //声明视口 private var _view:View3D; //声明平面几何对象 private var _planeGeometry:PlaneGeometry; //声明平面对象的贴图 private var _planeMaterial:TextureMaterial; //声明平面几何对象的容器 private var _planeMesh:Mesh; //控制旋转方向的变量 private var _direction:Boolean; //声明cube对象 private var _cubeGeometry:CubeGeometry; //声明cube对象容器 private var _cubeMesh:Mesh; //灯光 private var _directionalLight:DirectionalLight; private var _pointLight:PointLight; //灯光容器 private var _light:StaticLightPicker; public function MyAway3d_1() { //侦听舞台初始化完毕 if (stage) { init(); }else { this.addEventListener(Event.ADDED_TO_STAGE, init); } }
private function init(e:Event=null):void { //trace("舞台初始化完成!"); //设置舞台缩放模式和对齐方式 stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; this.removeEventListener(Event.ADDED_TO_STAGE, init); //实例化视口 _view = new View3D(); addChild(_view); //设置抗锯齿参数 _view.antiAlias = 6; //实例化一个长宽都是300的平面对象 _planeGeometry = new PlaneGeometry(300, 300); //实例化贴图对象 _planeMaterial = new TextureMaterial(Cast.bitmapTexture(FloorMaterial)); //实例化平面几何对象的容器,第一个参数是平面几何对象,第二个参数是贴图数据 _planeMesh = new Mesh(_planeGeometry, _planeMaterial); //设置容器可交互 _planeMesh.mouseEnabled = true; //容器侦听鼠标点击事件 _planeMesh.addEventListener(MouseEvent3D.CLICK, clickHandler); //将容器添加到视口的场景中 _view.scene.addChild(_planeMesh); _cubeGeometry = new CubeGeometry(); _cubeMesh = new Mesh(_cubeGeometry, new ColorMaterial(0xcccccc)); _cubeMesh.mouseEnabled = true; _cubeMesh.y = 150; _cubeMesh.z = -40; _view.scene.addChild(_cubeMesh); //添加平行光源 _directionalLight = new DirectionalLight(); _directionalLight.diffuse = .8; _directionalLight.ambient = .3; _directionalLight.castsShadows = true; //添加点光源 _pointLight = new PointLight(); _pointLight.ambient = 0.4; //_pointLight.diffuse = 10; //实例化灯光容器 _light = new StaticLightPicker([_directionalLight,_pointLight]); //给地面添加阴影效果 _planeMaterial.shadowMethod = new FilteredShadowMapMethod(_directionalLight); //给两个模型的材质添加灯光 _planeMesh.material.lightPicker = _light; _cubeMesh.material.lightPicker = _light; //将灯光添加到场景 _view.scene.addChild(_directionalLight); //设置摄像机的位置 _view.camera.z = -400; _view.camera.y = 260; //可以把这个值改成1试试看,这样可以有更加直观的感受 //_view.camera.x = 90; //设置摄像机始终指向平面 _view.camera.lookAt(_planeMesh.position); //_view.camera.lookAt(new Vector3D()); this.addEventListener(Event.ENTER_FRAME, onEnterFrame); stage.addEventListener(Event.RESIZE, onResize); onResize(); } private function clickHandler(e:MouseEvent3D):void { //鼠标点击变换运动方向 _direction = !_direction; } private function onResize(e:Event = null):void { //调整视口尺寸以适应新的窗口大小 _view.width = stage.stageWidth; _view.height = stage.stageHeight; } private function onEnterFrame(e:Event):void { //判断方向旋转 _cubeMesh.rotationX += 1; _cubeMesh.rotationY += 1; if (!_direction) { _planeMesh.rotationY += 1; }else { _planeMesh.rotationY -= 1; } //渲染3D世界 _view.render(); } } }