您的位置:首页 > 其它

Away3D基础教程(三):三维世界的灯光

2013-02-03 21:53 429 查看
目前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();
}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: