Flex使用Away3D制作3D效果

本站原创  作者:nebula  阅读()  日期:2010-12-22 16:17:50

网站建设技术,Flex使用Away3D制作3D效果 第一步:下载软件 从Away 3D官方网站下载软件包http://away3d.com/downloads/。 第二步: 预备 如果你对Actionscript3不熟悉的话,这些代码可能对你有些陌生。我假定学习本教程的设计师们只有有限的AS3编程经验。 // import the required parts of Away3D import away3d.containers.*; import aw...

Flex使用Away3D制作3D效果

第一步:下载软件

从Away 3D官方网站下载软件包http://away3d.com/downloads/

第二步: 预备

如果你对Actionscript3不熟悉的话,这些代码可能对你有些陌生。我假定学习本教程的设计师们只有有限的AS3编程经验。

// import the required parts of Away3D
import away3d.containers.*;
import away3d.core.base.*;
import away3d.primitives.*;
import away3d.materials.*;
import away3d.core.utils.Cast;
import away3d.cameras.*;

// import some filters we'll use later
import flash.filters.BitmapFilter;
import flash.filters.BitmapFilterQuality;
import flash.filters.BitmapFilterType;
import flash.filters.GlowFilter;

定义一些变量来保存旋转,鼠标动作等信息。把下面这些代码也拷进Flash中,放在刚才的Import语句下面。

// variables
var move:Boolean = false;
var lastPanAngle:Number;
var lastTiltAngle:Number;
var lastMouseX:Number;
var lastMouseY:Number;
var skies:Sphere;


第三步: 设置3D环境

就象在Flash中一样,Away3D也有一个供你绘制场景的舞台。我们将其称为Scene3D。既然是3D立体场景,我们就可以浏览3D物体之间。所以我们需要一个摄像机来观看场景。Away3D中提供了3种摄像机:

Camera3D - 在3D空间内自由移动。

TargetCamera3D - 指向一个物体。

HoverCamera3D - 在一个物体上盘旋。


既然准备在地球上空盘旋,就用使用HoverCamera3D好了。这也是初学者试验时最容易掌握的模式。下面的代码中,用到了放大比例zoom和焦距focus来设定相机,就和设定真正的相机是一样的。

另外,我们还需要定义一个视点(View3D)。把下面这段代码粘贴到现有代码的下面。

// Set the scene
var scene:Scene3D = new Scene3D();
// Create and set up the camera
var camera:HoverCamera3D = new HoverCamera3D({zoom:2, focus:200, distance:400});
camera.targetpanangle = camera.panangle = -180;
camera.targettiltangle = camera.tiltangle = 15;
camera.yfactor = 1;
var view:View3D = new View3D({scene:scene, camera:camera});
// Add viewport to the Flash display list so it's visible
addChild(view);
// Adjust view
view.x = 230;
view.y = 200;

创建了场景、相机和视点之后,设置一些初始属性。除非你修改设定,HoverCamer会始终指向舞台的中心。我们用平移角度(panangle)和倾斜角度(tiltangle)两个属性来围绕这个中心点旋转。最后只剩下画出些东西,好让我们去看了。我们绘制一个基本的球体来做为起点。把下面的代码粘贴到后面。

var globe:Sphere = new Sphere({material:"blue#white",radius:150,segmentsH:18, segmentsW:26});
view.scene.addChild(globe);
view.render();


上面的代码中,我们通过几个参数控制新建球体的函数:材质、半径和三角型面数。后面我们还会用到更复杂的纹理贴图。这里暂时使用白线框的蓝色材质。半径的作用很明显了。segmentsH和segmentsW用于控制球体网格的精细度。

编了半天,现在可以大致看一下效果了。你可以用调整平移角度panangle, 和倾斜角度tiltangle, 放大倍数zoom, 焦距focus以及距离distance参数, 来试验HoverCamera3D的工作方式。

第四步: 互动操作

只是看着球体还不够酷,我们还要自己盘旋浏览。编写这个功能,我们需要读取当鼠标按下时的坐标位置。把下面的代码粘贴到Flash编程窗口。

function MouseDown(event:MouseEvent):void
{
    lastPanAngle = camera.targetpanangle;
    lastTiltAngle = camera.targettiltangle;
    lastMouseX = stage.mouseX;
    lastMouseY = stage.mouseY;
    move = true;
}

function MouseUp(event:MouseEvent):void
{
    move = false;
}

function onEnterFrame(e:Event):void
{
    // rerender viewport
    var cameraSpeed:Number = 0.3; // Approximately same speed as mouse movement.
    if (move) {
        camera.targetpanangle = cameraSpeed*(stage.mouseX - lastMouseX) + lastPanAngle;
        camera.targettiltangle = cameraSpeed*(stage.mouseY - lastMouseY) + lastTiltAngle;
    }
    camera.hover(); 
    view.render();
}

addEventListener(Event.ENTER_FRAME, onEnterFrame);
stage.addEventListener(MouseEvent.MOUSE_DOWN, MouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, MouseUp);

当使用者点击鼠标的时候,会执行第一个函数(function )。我们设置了接受鼠标点击函数(MouseEvent)来实现这个功能。代码最后用addEventListener把这个函数加入舞台。点击鼠标时,程序记录相机和鼠标的位置值。然后把move变量设为有效(true),允许旋转。第二个函数的原理相同,负责关掉move变量。

最后一个函数会在每一帧执行。当按下鼠标时(move变量为true),程序会基于当前鼠标位置和之前的鼠标位置来更新旋转。这一步是这个程序中最复杂的部分。后面的步骤都很有意思。ctrl+回车输出SWF,转转这个小球吧!

第五步: 加入纹理贴图

搜索合适的地球贴图的时候,我偶然进到JHT的Planetary Pixel Emporium。这里有地球和其他太阳系行星的高质量贴图。所有公用资源都可以免费使用。这个站点同时还提供超高分辨率贴图收费下载。我对一些贴图进行了修改,点击这里下载ZIP文件,然后解压到工作目录中。

回到Flash中,选择文件->导入->导入到库,然后选择"earthmap1k.jpg"。导入后打开文件库面板(窗口->文件库),右键点击图片从下拉菜单中选择"链接"(Linkage)。选中"导出到Actionscript”(Export for Actionscript)复选框。

这样就可以在Away3D中,就可以使用以下代码直接调用图片了。

globe.material = new BitmapMaterial(Cast.bitmap("earthmap1k.jpg"));

再次输出SWF,看看地球全貌。

第六步: 增加天空云层

地球看起来不错,但有些单调吧?看看下面怎么来改进。 地球周围有大气云层环绕,如果实现这点,就有深度的感觉了。Away3D可以用Flash支持的各种位图来作为纹理。用一张PNG透明图片来模拟云层,我们透过云层看到下面的大地。我们还可以通过单独控制天空旋转强化景深效果。

将"earthcloudmap.png"导入文件库。同样设置链接"Linkage",以备AS程序调用。这样图片是由两张JHR网站上下载的图片合成的。加入以下代码。

skies = new Sphere({material:"earthcloudmap.png",radius:153,segmentsH:18, segmentsW:26});
view.scene.addChild(skies);

输出后,有些问题?这是因为Away3D默认设置中,同时渲染两个球体时有问题。找到建立view的那行代码,将其改为以下语句:

var view:View3D = new View3D({scene:scene, camera:camera, renderer:Renderer.CORRECT_Z_ORDER});

最后的那个参数是使3D引擎以正确方式来处理Z轴排列(Z-sort)。要使用这个参数,我们还需要在代码开始处引入新的类库。

import away3d.core.render.*;

这行代码导入了必要的渲染器。现在效果好了,但速度也稍慢了些。

下面加入些云层飘动的效果如何?

在onEnterFrame 函数中加入两行代码:

function onEnterFrame(e:Event):void
{
    // rerender viewport
    var cameraSpeed:Number = 0.3; // Approximately same speed as mouse movement.
    if (move) {
        camera.targetpanangle = cameraSpeed*(stage.mouseX - lastMouseX) + lastPanAngle;
        camera.targettiltangle = cameraSpeed*(stage.mouseY - lastMouseY) + lastTiltAngle;
    }
    camera.hover(); 
    view.render();
    if(skies)
        skies.rotationY += .015;
}

只改了最后两行。涵义为,如何skies存在,就让他沿Y轴慢慢转(0.015 度每帧)。这样看起来更加真实。自己试一下吧!

(译者又注:Sonic在这里改了一下。首先修改旋转方向,观察云层形状,改为逆时针方向更为真实。其次以开始毫秒数除-1500来实现旋转。可以通过修改除数大小来控制速度。)

skies.rotationY = getTimer() / -1500; //rotating clouds

第七步: 加入星空

在太空中看到地球,应该是在星空的环绕之下。当我寻找星空的贴图的时候,我找到了这篇教程。虽然不是专门为创建星空贴图而写的,但生成的图片和我们需要的效果很类似。因为这篇带有演示草图的文章发布在教育资源中,我想我们使用"star_map_small.jpg"这张图片来做这个教程应该是合法的。(敬佩一下老外的版权意识,差距很大啊。)

相机放在距场景中心400units远的地方。所以建造一下比400 units大一些的球体,就可以把相机放在球体里面,展示球体的内部。我们来试一下:

var heavens:Sphere = new Sphere({material:"star_map_small.jpg",radius:1200,x:0,y:0,segmentsH:9, segmentsW:9});
view.scene.addChild(heavens);

当你把这段代码加进去的时候,你看不到星空。这是因为如果以双面方式来渲染3D网络,计算量会增加一倍。3D引擎会省掉一切可能的运算负担,来达到最佳的速度。当然你也可以打开双面渲染,同时你也需要翻转材质方向,就象这样:

heavens.invertFaces();

把这句代码加上后,星空就出现了。另外请注意因为星空用了很暗的贴图,基本看不到细节,所以我们用了一个精度很低的球体。(segmentsH:9, segmentsW:9) - 9x9 segments

第八步:加入太阳

导入"sunmap.jpg",在链接选项中打开“为Actionscript导出”。这和前面步骤中处理材质的方法一样。

var sun = new Sphere({material:"sunmap.jpg",radius:50,x:150,y:100,z:600,segmentsH:6, segmentsW:6});
view.scene.addChild(sun);

添加一个新的球体,并赋予太阳材质。这个球体很小,在地球的右(x轴)上(y轴)方。离地球有一段距离(深度,z轴)。再次测试场景,可以看到初始场景中,太阳在地球后面。移动场景时,太阳也会单独移动。

第九步: 优化

到这里开始出现问题了。即便太阳只有6x6 segments的精度,场景已经开始变慢了。想要顺畅运行动画,我们需要做些优化工作。减少场景中三角型的数量是目前的主要问题。为了表现云层,地球外面附加的球体多边型数量很多,而且需要修正Z轴(Z-sorting),占用了过多的资源。(译者注,是我的机器配置比较好吗?我没觉得慢,不过下面优化的办法还是很值得学习的。

另一个附加云层的办法是把地球贴图和天空结合在一起(有时称为“预烘烤贴图”)。在现实中,天空和地球表面是很接近的,所以这样做还能增加真实感(至少可以拿这个说法当借口)。先把创建天空的两行代码注释掉(在代码前加两个斜杠//)。

// skies = new Sphere({material:"earthcloudmap.png",radius:153,segmentsH:18, segmentsW:26});
// scene.addChild(skies);

下面导入"earthmap1k.png",我用Photoshop把两张图片结合在了一起。象前面一样设置为Actionscript导出图片。在后面加上这行代码:

globe.material = new BitmapMaterial(Cast.bitmap("earthmap1k.png"));

同时,把相机设置恢复成普通渲染模式,不再强制物体Z轴顺序。将设定View3D的代码替换为这样:

var view:View3D = new View3D({scene:scene, camera:camera, renderer:Renderer.BASIC});

这两招可以大大加快运行速度。

第十步: 夜景

烘培贴图的技巧还可以有别的用处。在Photoshop中处理一下,把夜景照片结合到贴图中。导入"earthmap1k_night_day.png",设定图片为Actionscript导出。加入下面的代码。

var newMaterial:BitmapMaterial = new BitmapMaterial(Cast.bitmap("earthmap1k_night_day.png"));
globe.material = newMaterial;

效果好多了,是吧?看到夜景中闪烁的灯光了吗?

第十一步: 大气层

设置"ownCanvas"属性。在Away3D中,所有的物体都可以使用标准Flash滤镜。加入以下代码,本篇教程到此结束。

var myFilter1:Array = new Array()
myFilter1.push(new GlowFilter(0xFFFFAA, 1, 25, 25, 3, 1, false, false));
sun.ownCanvas=true;
sun.filters=myFilter1;

var myFilter2:Array = new Array()
myFilter2.push(new GlowFilter(0xFFFFFF, 0.4, 15, 15, 2, 1, false, false));
globe.ownCanvas=true;
globe.filters=myFilter2;

最后: 下面是最终完成的效果

http://www.wuhanwangzhanjianshe.com/demo_3d/

很明显这个场景并不是完全精确,但是对于演示Flash 3D程序来说已经足够了。

标签: flex   来源目录:网站建设技术

网站建设中的虚拟主机 中小企业拓展业务网站建设是首选 营销型网站建设应该考虑哪些因素? 企业网站建设过程中的几点要素 网站建设中同客户交流常常涉及到的问题 政府官方网站建设方案 房地产网站建设方案特点 学校网站建设方案的要点,学校网站建设方案的目标 企业网站建设方案的要点,企业网站建设方案总结 行业门户网站建设的误区,错误的行业门户网站建设方向 门户网站建设的特点,门户网站建设的功能规划 门户网站建设方案,门户网站建设的总体方向 网站建设价格为什么相差很大原因 网站建设价格如何计算的? 网站建设,做一个网站包含了哪些工作? 网站建设完成后需要如何更新内容进行维护? 如何选择和判断一家好的网页设计公司做网站建设? 答疑客户对网站建设的疑虑 在武汉做一个网站多少钱?武汉网站建设的价格 网站建设、制作开发的具体流程是怎样的? 网站建设开发服务流程图解说明 网站建设域名基础知识,什么是域名、域名解析、域名转向 企业网站建设有什么用,有哪些好处 企业网站建设过程中的几点要素 企业网站建设中的注意事项 网站建设技术发展史,网站建设技术回顾