3D基础知识.docx
《3D基础知识.docx》由会员分享,可在线阅读,更多相关《3D基础知识.docx(22页珍藏版)》请在冰豆网上搜索。
3D基础知识
3D基础知识
ActionScript中的3D简介
二维(2D)对象和投影在二维屏幕上的三维(3D)对象之间的区别在于,三维对象增加了第三维。
第三维使对象能够靠近或远离用户的视点。
若是将某个显示对象的z属性显式设置为数值,那么该对象会自动创建一个3D转换矩阵。
您能够通过更改此矩阵来修改该对象的3D转换设置。
另外,3D旋转与2D旋转也有所不同。
在2D中,旋转轴始终垂直于x/y平面,即位于z轴上。
在3D中,旋转轴能够位于x、y或z轴中的任一轴上。
通过设置显示对象的旋转属性和缩放属性,能够让该对象在3D空间中移动。
常见3D任务
本章讨论以下与3D相关的常见任务:
创建3D对象
在3D空间中移动对象
在3D空间中旋转对象
利用透视投影表示深度
从头排序显示列表使之与相对z轴对应,从而让对象以正确的层叠顺序出此刻用户眼前
利用3D矩阵转换3D对象
在3D空间顶用矢量操作对象
利用()方式创建透视
利用UV映射向3D对象添加位图纹理
通过设置()方式的剔除参数可加速呈现速度,还可隐藏3D对象中背离当前视点的部份。
重要术语和概念
以下参考列表包括将会在本章中碰到的重要术语:
透视:
在2D平面上将平行线表示成聚合于一个消失点,从而取得深度和距离的视觉成效
投影:
为多维对象生成2D图像;3D投影将3D点映射到2D平面
旋转:
通过按圆周运动的方向移动对象内的每一个点来更改对象的方向(通常也会更改其位置)
转换:
通过平移、旋转、缩放、倾斜或这些操作的组合来更改3D点或点集
平移:
通过将对象内的每一个点往同一方向移动相同的距离来更改对象的位置
消失点:
在用线性透视法表示时,慢慢远离的平行线看似相交的点
矢量:
3D矢量利用笛卡尔坐标x、y和z表示三维空间中的点或位置
极点:
转角点
纹理式网格:
在3D空间顶用于概念对象的任意点
UV映射:
将纹理或位图应用于3D表面的一种方式。
UV映射将值分派给图像上的坐标,以水平(U)轴和垂直(V)轴的百分比值形式表示。
T值:
当对象靠近或远离当前视点时用于确信3D对象大小的缩放系数
剔除:
呈现或不呈现具有特定缠绕方式的表面。
通过利用剔除,您能够隐藏对当前视点不可见的表面。
了解FlashPlayer和AIR运行时的3D功能
在FlashPlayer10之前的FlashPlayer版本和AdobeAIR之前的AdobeAIR版本中,显示对象有x和y两个属性,用于在2D平面上放置显示对象。
从FlashPlayer10和AdobeAIR开始,每一个ActionScript显示对象都有一个z属性,通过该属性能够沿z轴放置显示对象,z轴一样用于表示深度或距离。
FlashPlayer10和AdobeAIR引入了对3D成效的支持。
可是显示对象本质上仍是平面的。
每一个显示对象(例如MovieClip对象或Sprite对象)最终会呈现于二维的单一平面上。
通过3D功能,可在三个维中放置、移动、旋转和按其它方式转换这些平面对象,还可治理3D点和将这些点转换为2Dx、y坐标,如此您就能够将3D对象投影到2D视图上。
通过这些功能,能够模拟出丰硕的3D成效。
ActionScript利用的3D坐标系与其它坐标系不同。
在ActionScript中利用2D坐标系时,沿x轴向右移动进程中,x的值增大,而沿y轴向下移动进程中,y的值增大。
3D坐标系仍遵从这一老例,但另外添加了z轴,该轴的值随着远离视点而增大。
ActionScript3D坐标系中x、y和z三条轴的正向。
A.
+Z轴
B.
原点
C.
+X轴
D.
+Y轴
注:
请注意,FlashPlayer和AIR始终在图层中表示3D。
也确实是说,若是对象A在显示列表中位于对象B的前面,那么不管这两个对象的z轴值为多少,FlashPlayer或AIR都始终将A呈此刻B的前面。
假设要解决显示列表顺序与z轴顺序之间的冲突,请利用()方式进行保留,然后从头排序3D显示对象的图层。
有关详细信息,请参阅。
以下ActionScript类支持与3D相关的新功能:
1.类包括z属性和新的旋转和缩放属性,这些属性用于操作3D空间中的显示对象。
()方式提供了一种将3D几何图形投影到2D平面的简单方式。
2.类可用作治理3D点的数据结构。
该类还支持矢量数学运算。
3.类支持复杂的3D几何转换,例如旋转、缩放和平移。
4.类操纵着将3D几何图形映射到2D视图的相关参数。
在ActionScript中,有两种不同的模拟3D图像的方式:
1.在3D空间中排列平面对象并进行动画处置。
这种方式需要利用显示对象的x、y和z属性来对显示对象进行动画处置,或利用DisplayObject类设置旋转和缩放属性。
利用对象能够实现更为复杂的运动。
对象可自概念显示对象在3D透视中的绘制方式。
若是需要对要紧包括平面的3D对象进行动画处置,能够利用这种方式。
这种方式的例子包括3D图库或3D空间中排列的2D动画对象。
2.从3D几何图形生成2D三角形,然后用纹理呈现这些三角形。
要利用这种方式,必需第一概念和治理有关3D对象的数据,然后将这些数据转换成要呈现的2D三角形。
能够将位图纹理映射到这些三角形,然后利用()方式将三角形绘制为图形对象。
这种方式的例子包括从文件中加载3D模型数据并将模型呈现到屏幕上,或以三角形网格形式生成和绘制3D图形。
创建和移动3D对象
目录[]
▪
▪
假设要将2D显示对象转换为3D显示对象,能够将其z属性显式设置为一个数值。
若是为z属性指定一个值,那么会为显示对象创建一个新的Transform对象。
通过设置或属性,也能够创建新的Transform对象。
Transform对象包括Matrix3D属性,该属性操纵显示对象在3D空间中的表示方式。
下面的代码设置名为“leaf”的显示对象的坐标:
=100;=50;=-30;
在leaf的Transform对象的matrix3D属性中,能够查看这些值,和从这些值派生出的属性:
varleafMatrix:
Matrix3D=
trace
trace
trace
trace
trace有关Transform对象的属性的信息,请参阅类。
有关Matrix3D对象的属性的信息,请参阅类。
在3D空间中移动对象
通过更改对象的x、y或z属性的值,能够在3D空间中移动对象。
若是更改z属性的值,对象看起来就会靠近或远离观看者。
下面的代码在响应事件时,通过更改两个椭圆的z属性的值,沿着各自的z轴前后移动这两个椭圆。
ellipse2的移动速度比ellipse1快:
其z属性针对每一个Frame事件增加20倍,而ellipse1的z属性增加10倍:
vardepth:
int=1000;
functionellipse1FrameHandler(e:
Event):
void
{
ellipse1Back=setDepth(e,ellipse1Back);
+=ellipse1Back*10;
}
functionellipse2FrameHandler(e:
Event):
void
{
ellipse2Back=setDepth(e,ellipse1Back);
+=ellipse1Back*20;
}
functionsetDepth(e:
Event,d:
int):
int
{
if>depth)
{
=depth;
d=-1;
}
elseif<0)
{
=0;
d=1;
}
}
在3D空间中旋转对象
能够通过三种方式旋转对象,具体取决于如何设置对象的旋转属性:
rotationX、rotationY和rotationZ。
以下图显示两个未旋转的正方形:
下一个图显示两个正方形,它们通过增加正方形容器的rotationY属性在y轴上旋转。
通过旋转这两个正方形的容器或父显示对象,能够旋转这两个正方形:
+=10;
下一个图显示当设置正方形容器的rotationX属性时会发生的转变。
此操作会在x轴上旋转正方形。
下一个图显示当增大正方形容器的rotationZ属性时发生的转变。
此操作会在z轴上旋转正方形。
显示对象能够在3D空间中同时移动和旋转。
将3D对象投影到2D视图上
目录[]
▪
▪
▪
▪
包中的类提供了一种在3D空间中移动显示对象时应用大体透视的简单方式。
若是未显式创建3D空间的透视投影,3D引擎将利用默许的PerspectiveProjection对象,该对象存在于根上并会传播到其所有子项上。
用于概念PerspectiveProjection对象如何显示3D空间的三个属性是:
fieldOfView
projectionCenter
focalLength
修改fieldOfView的值将自动修改focalLength的值,反之亦然,因为这两个属性彼此依托。
在给出fieldOfView值的情形下,用于计算focalLength属性的公式为:
focalLength=stageWidth/2*(cos(fieldOfView/2)/sin(fieldOfView/2)
通常,您需要显式修改fieldOfView属性。
视野
通过操作PerspectiveProjection类的fieldOfView属性,能够使慢慢靠近观看者的3D显示对象变大,而使慢慢远离观看者的对象变小。
fieldOfView属性指定一个介于0到180度的角度,该角度确信透视投影的强度。
该值越大,沿z轴移动的显示对象的扭曲程度就越强。
若是fieldOfView值较小,那么缩放程度较低,从而使对象在空间中只稍稍后移。
若是fieldOfView值较大,那么会致使较大的扭曲,并显现较大的移动。
若是达到最大值180度,那么会显现极端的鱼眼照相机镜头成效。
投影中心
projectionCenter属性表示透视投影的消失点。
该属性作为相关于舞台左上角默许注册点(0,0)的偏移量。
当对象慢慢远离观看者时,该对象将朝消失点倾斜直到最终消失。
想象一下无穷长的走廊。
当朝走廊远处看时,两边的墙壁将聚合到走廊远处的消失点。
若是消失点位于舞台的中心,那么走廊将消失于该中心点。
projectionCenter属性的默许值是舞台的中心。
例如,若是希望元素出此刻舞台的左侧,而3D区域出此刻右边,请将projectionCenter设置为舞台右边的点,使之成为3D查看区域的消失点。
焦距
focalLength属性表示视点原点(0,0,0)与显示点在z轴上的位置之间的距离。
较长的焦距相当于视野较窄、对象间距离通过紧缩的摄远镜头。
较短的焦距相当于广角镜头,可取得较宽的视野和较大的扭曲。
中等的焦距相当于肉眼所见的成效。
通常,当显示对象移动时,focalLength属性会在透视转换进程中动态地从头进行计算,只是您能够显式设置该属性。
默许透视投影值
在根上创建的默许PerspectiveProjection对象具有以下值:
fieldOfView:
55
perspectiveCenter:
stagewidth/2,stageHeight/2
focalLength:
stageWidth/2*(cos(fieldOfView/2)/sin(fieldOfView/2))
若是您没有创建自己的PerspectiveProjection对象,那么会默许利用这些值。
若是要自行修改projectionCenter和fieldOfView属性,那么能够实例化您自己的PerspectiveProjection对象。
在这种情形下,新建对象的默许值如下(假设默许舞台大小为500x500):
fieldOfView:
55
perspectiveCenter:
250,250
focalLength:
例如:
透视投影
下面的例如演示如何利用透视投影来创建3D空间。
该例如演示如何通过projectionCenter属性来修改消失点和更改空间的透视投影。
进行这种修改后,将强制从头计算focalLength和fieldOfView(及其相关的3D空间扭曲)。
此例如:
1.创建一个名为center的sprite,作为包括十字准线的圆
2.将centersprite的坐标分派给根的transform属性的perspectiveProjection属性的projectionCenter属性
3.为鼠标事件添加事件侦听器,用于挪用修改projectionCenter的事件处置函数,以便跟踪center对象的位置
4.创建四个折叠样式的框,这四个框将形成透视空间的墙壁
在测试此例如时,将圆拖动到不同的位置。
消失点将跟从圆移动,直到释放圆时才固定下来。
在移动投影中心使其远离舞台中心时,观看包围空间的框所发生的拉伸和显现的扭曲。
假设要获取此范例的应用程序文件,请参阅。
在Samples/ProjectionDragger文件夹中能够找到ProjectionDragger应用程序文件。
package
{
import
import
import
import.*;
publicclassProjectionDraggerextendsSprite
{
privatevarcenter:
Sprite;
privatevarboxPanel:
Shape;
privatevarinDrag:
Boolean=false;
publicfunctionProjectionDragger():
void
{
createBoxes();
createCenter();
}
publicfunctioncreateCenter():
void
{
varcenterRadius:
int=20;
center=newSprite();
Shape>=newVector.(numLayers);
for(vari:
int=0;i{
(createBox(150,50,(numLayers-i)*depthPerLayer,boxWidth,boxHeight,0xCCCCFF));
(createBox(50,150,(numLayers-i)*depthPerLayer,boxWidth,boxHeight,0xFFCCCC));
(createBox(250,150,(numLayers-i)*depthPerLayer,boxWidth,boxHeight,0xCCFFCC));
(createBox(150,250,(numLayers-i)*depthPerLayer,boxWidth,boxHeight,0xDDDDDD));
}
}
publicfunctioncreateBox(xPos:
int=0,yPos:
int=0,zPos:
int=100,w:
int=50,h:
int=50,color:
int=0xDDDDDD):
Shape
{
varbox:
Shape=newShape();
0x666666);
;
0,w,h);
=xPos;
=yPos;
=zPos;
returnbox;
}
publicfunctionstartDragProjectionCenter(e:
Event)
{
();
inDrag=true;
}
publicfunctiondoDragProjectionCenter(e:
Event)
{
if(inDrag)
{
=newPoint,;
}
}
publicfunctionstopDragProjectionCenter(e:
Event)
{
();
=newPoint,;
inDrag=false;
}
}
}
关于加倍复杂的透视投影,请利用Matrix3D类。
执行复杂的3D转换
利用Matrix3D类能够转换坐标空间内的3D点,也能够将3D点从一个坐标空间映射到另一个坐标空间。
不需要明白得矩阵运算就能够够利用Matrix3D类。
大多数常见的转换操作都能够通过该类的方式进行处置。
您没必要担忧如何显式设置或计算矩阵中每一个元素的值。
将显示对象的z属性设置为数值后,能够利用该显示对象的Transform对象的Matrix3D属性来检索显示对象的转换矩阵:
varleafMatrix:
Matrix3D=您能够用Matrix3D对象的方式对显示对象执行平移、旋转、缩放和透视投影。
利用Vector3D类及其x、y和z属性可治理3D点。
该类还能够表示具有方向和大小的物理空间矢量。
通过Vector3D类的方式,能够执行有关空间矢量的常见计算,例如加法、点积和叉积计算。
注:
Vector3D类与ActionScriptVector类无关。
Vector3D类包括的属性和方式用于概念和操作3D点,而Vector类那么支持类型对象数组。
创建Matrix3D对象
有三种创建或检索Matrix3D对象的要紧方式:
1.利用Matrix3D()构造函数实例化新的矩阵。
Matrix3D()构造函数需要利用包括16个数值的Vector对象,并将每一个值放入一个矩阵单元中。
例如:
varrotateMatrix:
Matrix3D=newMatrix3D(1,0,0,1,0,1,0,1,0,0,1,1,0,0,0,1);
2.设置显示对象的z属性的值。
然后从该对象的属性检索转换矩阵。
3.通过获取根显示对象的属性的值,检索用于操纵舞台上3D对象显示方式的Matrix3D对象。
应用多种3D转换
通过Matrix3D对象,能够一次应用多种3D转换。
例如,若是要旋转、缩放然后移动立方体,能够对立方体的每一个点别离应用这三种转换。
可是,还有一种高效得多的方式,即在一个Matrix3D对象中预先计算多种转换,然后对每一个点执行一次矩阵转换。
注:
矩阵转换的应用顺序超级重要。
矩阵运算的顺序是不能互换的。
例如,先应用旋转再应用平移与先应用平移再应用旋转,二者的结果是不同的。
下面的例如演示执行多种3D转换的两种方式。
package{
import
import
import
import.*;
publicclassMatrix3DTransformsExampleextendsSprite
{
privatevarrect1:
Shape;
privatevarrect2:
Shape;
publicfunctionMatrix3DTransformsExample():
void
{
varpp:
PerspectiveProjection=
=newPoint(275,200);
=pp;
rect1=newShape();
=-70;
=-40;
=0;
addChild(rect1);
rect2=newShape();
=20;
=-40;
=0;
addChild(rect2);
doTransforms();
}
privatefunctiondoTransforms():
void
{
=15;
=;
+=100;
+=50;
=10;
varmatrix:
Matrix3D=
(15,;
1,1);
(100,50,0);
(10,;
=matrix;
}
}
}
在doTransforms()方式中,第一个代码块利用DisplayObject属性更改矩形形状的旋转、缩放和位置。
第二个代码块利用Matrix3D类的方式执行相同的转换。
利用Matrix3D方式的要紧优势在于,所有的计算都是在矩阵中提早执行的。
然后,只要设置了显示对象的属性,就只需对显示对象应用一次矩阵转换。
通过设置DisplayObject属性可使源代码更易于阅读。
可是,每次设置旋转和缩放属性后,会致使进行大量计算并更改显示对象的多个属性。
若是您的代码要多次对显示对象应用相同的复杂转换,应将Matrix3D对象保留为变量,然后反复应用该变量。
利用Matrix3D对象从头排序显示
如前所述,显示列表中显示对象的层叠顺序确信了对象的显示顺序,这些对象的相对z轴值对显示顺序没有阻碍。
若是您的动画将显示对象的属性转换为一种与显示列表中的顺序不同的顺序,那么观看者看到的显示对象层叠顺序与z轴层叠顺序不一致。
因此,在视觉上应当远离观看者的对象可能反而会靠近观看者。
为确保3D显示对象的层叠顺序对应于对象的相对深度,请利用如下方式:
1.利用Transform对象的getRelativeMatrix3D()方式获取3D子显示对象的相对z轴值。
2.利用removeChild()方式从显示列表中删除对象。
3.依照显示对象的相对z轴值对显示对象进行排序。
4.利用addChild()方式以相反顺序将子对象添加到显示列表中。
这种从头排序方式可确保您的对象依照各自的相对z轴值进行显示。
下面的代码将