




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第四章 景深排序 Z-排序正确的排序场景中的3D对象,是能否正确的在屏幕上画出场景的关键。Away3D使用画家算法在屏幕上画出组成场景的元素,在大多数时间里,Away3D能以正确的排序画出这些元素显示场景,可能有些读者认为:这样的过程成是很容易的。然而在有些情形下,对在场景中3D对象的Away3D的排序作调整是必须的。这一章 展示了这样的情形,并介绍了能手工改正排序过程的方法。Away3D也包含了一些附加的渲染器,它能用于自动地调整3D对象在场景中的排序。展示出这些渲染器,并探索了它们可能的影响Away3D应用程序执行的性能。这一章涵盖以下的内容:l 画家算法l 如何排序场景l 如何影响或强迫
2、3D对象的排序次序l 一些附加的渲染器4-1 画家算法画家算法参考了被雇用的画家绘画技法,在这种技法里,场景里最远的部分首先画出来,而后场景中较近的部分,逐次地画在它先一幅的上面。下面的图像,来自维基有关文章,显示出绘画采用的一些步骤画出野外的景象。景象中最远的背景山,山首先画出,草地和灌木而后画出,最后,画出的树林覆盖在它们上面。4-1-1 Z-排序或景深排序Z-排序或景深排序是一种用于排序组成3D对象元素的技术,排序是根据在用照相机观察它们时,它们的远近情况而排列的。而后允许这些3D对象元素用画家算法,以这样的次序:从场景中最远的背景开始到最近的背景顺序描绘到屏幕上。在大多数情况下,这个算
3、法的工作是好的,并没有附加的必要步骤以改正后的顺序画出3D对象元素。然而有些情形下,这个算法是失败的,为理解画家算法失败的情形,首先我们看看组成一个3D对象的元素在场景里是如何排序的。4-2 场景排序 场景中每一个元素的距离用一单个数来表示,叫景深,或叫z深度,计算景深,使用组成该元素的每个顶点,沿照相机本地坐标系统z轴的位置的平均值表示。一个很容易的方式来想象照相机本地空间,这就是设想,照相机坐落在原点,并直接朝z轴的正方向,在下面的图中,阐明了这一情形。组成三角形的各顶点的坐标值,标记在图里面,这些坐标值是用于照相机的本地空间里的,为计算三角形的景深,z深度,我们取这些坐标值的z分量(即是
4、:110,100,和90),取其平均值取整最后是100。即使各顶点的深度范围是从90到110,以后用这单一的值100作为此三角形的景深z深度。既然单一的z深度的平均值不能精确的描绘场景内原始的相对位置,那么在排序3D对象元素时,根据它们的景深z深度就可导致与实际不一致的情形。为证实3D对象元素不能依景深正确的排序这一情况,让我们新建一个叫ZSorting的例子。在初始化场景函数intScene()中,我们将建立两个三角形,这两个三角形从照相机的视角来看,一重叠了另一个。 package Import away3d.primitives.Triangle; public class ZSorti
5、ng extends Away3DTemplate public function ZSorting() super(); protected override function initScene():void super.initScene(); camera.z=0; var triangleA:Triangle=new Triangle( x: -30, y: 0, z: 500, rotationY: -5, yUp: false, bothsides: true ); var triangleB:Triangle=new Triangle( x: 30, y: 0, z: 499,
6、 rotationY: 60, yUp: false, bothsides: true ); scene.addChild(triangleA); scene.addChild(triangleB); 下面的这图是从顶往下看的场景样子,三角形B景深z深度稍小于三角形A,并且它们之间并不相交。 下面的图像显示出,当程序运行的时候,画出的两个三角形的样子。从顶往下看场景,很清楚,右边的三角形(TriangleB)应该出现在左边的三角形(TriangleA)的后面这一事实,可是因为三角形B在计算时,有比三角形A稍小的景深(z深度),所以应用程序认为三角形B是在三角形A的前面,这就导致三角形B最后被画
7、出,覆盖在三角形A的上面的这种错误。这里提出的这个例子,证明单一的景深(z深度)的平均值并不能精确反映场景中3D对象的实际的景深情况。4-3 调整排序的顺序 在Away3D里面包含了很多用于调整排序次序,以这种调整后的排序次序画出原来的元素。在上面提供的例子中画出的排序次序可以修改,既可把三角形A带到场景的前面,或者强制三角形B带到场景的到后面。4-3-1 推前和推后属性推前pushfront属性强制画出排序的原来元素,以最靠近照相机的点为根据。对于三角形A,最最靠近照相机的点是Point 1。因为Point 1靠近照相机比起三角形B的景深近一些,所以设置三角形A的推前pushfront属性为
8、True,这将把它带到场景的前面,表示它将最后描绘出来。(在程序中要加入import away3d.core.base.Object3D;语句) var triangleA:Object3D=new Triangle( x: -30, y: 0, z: 500, rotationY: -5, yUp: false, bothsides: true, pushfront: true );推后pushback属性强制画出排序的原始元素,以离照相机最远的点为根据。对于三角形B,离照相机最远的点是Point 2。因为Point 2离相机比起三角形A的景深远些,所以设置三角形B的推后pushback属性
9、为True,这将把它带到场景的后面,表示它将最先描绘出来。 var triangleB:Object3D=new Triangle( x: 30, y: 0, z: 499, rotationY: 60, yUp: false, bothsides: true, pushback:true );4-3-2屏幕Z位移属性屏幕Z位移ScreenZOffset属性用于强制使一个三角形比其他的三角形离相机远一些,Away3D将把屏幕Z位移ScreenZOffset属性的值加到z深度,用这种方法你可调整3D对象在场景中的相对z深度。正的ScreenZOffset值增加z深度,强制使3D对象更朝向场景的背
10、后。负的ScreenZOffset值减少z深度,强制使3D对象更朝向场景的前面。请注意:设置ScreenZOffset值,并不改变3D对象在场景中的位置和实际景深,仅改变它们画出的次序。为了强制把三角形A画在三角形B上,我们给它能指定一负值的ScreenZOffset的参数。在下面的例子代码中,三角形A将有490的z深度,这就把画到了三角形B的前面,而三角形B的z深度是499. var triangleA:Object3D=new Triangle( x: -30, y: 0, x: 500, rotationY: -5, yUp: false, bothsides: true, screen
11、ZOffset:-10 );为了强制把三角形B画在三角形A的后面,我们给它指定一正值的ScreenZOffset的参数。在下面的例子代码中,三角形B将有509的z深度,这就把它画到了三角形A的背后,而三角形A的z深度是500. var triangleB:Object3D=new Triangle( x: 30, y: 0, x: 499, rotationY: 60, yUp: false, bothsides: true, screenZOffset: 10 );Away3D文档叙述,screenZOffset的值仅对于当3D对象的ownCanvas的属性设置为true时有效,在Away3
12、D 3.6里设置screenZOffset是不正确的,无论ownCanvas的属性设置为true或false,设置screenZOffset的属性均不认可。-4-3-3自己画布属性强制3D对象排序的最后一种方式,是把它们画在自己的画布上。为此,就要设置ownCanvas 属性为true,并强制设置canvas的z深度。一个canvas是一个层,3D对象就画在它上面。它们的工作方式与其它图像编辑软件photoshop里层的概念非常象似。3D对象能画到画布里,而后画布画在场景中任何其他3D对象的旁边。首先,我们设置ownCanvas 的属性为true。 var triangleB:Object3D
13、=new Triangle( x: 30, y: 0, x: 499, rotationY: 60, yUp: false, bothsides: true, ownCanvas: true );然后,我们通过设置ownSession screenZ的属性来指定canvas的屏幕深度。因为三角形A离照相机500单位,所以指定用来显示三角形B的画布canvas的z深度,稍大一点为510,这就表示三角形A离照相机近一些。 triangleB.ownSession.screenZ=510;在下面的图像里显示了画布的位置,通过给出画有三角形B的画布的screenZ值比三角形A的z深度大,我们已经强制把
14、画有三角形B的画布作为三角形A的背景。-请注意!当通过screenZ的属性,设置画布canvas屏幕深度的时候,不像其他修改3D对象z深度的方法,screenZ的属性是一个绝对的值,并不把照相机的相对位置考虑进去。如果照相机位于(0,0,-1000)的位置且这是默认值,那么,前述的代码将把画有三角形B的画布canvas画到三角形A的前面,这是因为三角形A相对照相机的z深度是1500,而画布canvas的z深度设置为绝对值510的原因。-如果没有指定screenZ的值,各画布在场景中的排序是根据各个3D对象的z深度来决定的。这表示在场景中画布的排序,能够通过画在它上面的3D对象的pushfron
15、t,pushback和screenZOffset的属性值的设置来修改。-4-4 有关Z-排序的说明以上所述的所有这些方法,都是通过修改一个3D对象相对于场景中其他3D对象的景深(z深度)来实现的。有一点是非常重要的,这就是,实现对这些3D对象更改到所希望的相对景深(z深度),要依据照相机的位置。考虑由上面ZSorting应用程序建立的同样的场景,而现在,从与原来相反的位置来看。在这样的情形下,如果我们设置三角形B的pushback属性为true,同照相机在左边时,我们修改它的绘画次序一样。这在实际上,我们将会引起一个不可修改z-排序的错误。这是因为从照相机的现在位置来看,三角形B应该画在三角形
16、A的前面,而不是在它后面。于是要记住,在指定pushback,pushfront,screenZOffset和screenZ的属性值的时候,可能必须修改场景中,相应于照相机位置已经发生改变了的3D对象的位置和朝向。-当一个3D对象相对于照相机的位置已经改变了的时候,必须修改它的screenZOffset属性值这样的例子。请看第十章 建立3D文本的 FrontExtrusionDemo的应用程序。-4-5 附加的渲染器本书中,介绍的所有的应用程序,全都使用默认的渲染器。Away3D包含了三种不同类型的渲染器,每个都是通过away3d.core.render包里的Render类中的静态static
17、属性返回的渲染器。默认的渲染器,是用BASIC属性建立的,其他两个渲染器是用CORRECT_Z_ORDER和INTERSECTING_OBJECTS属性建立的,这两个都是四叉树数据结构的渲染器,它们比用默认的BASIC属性建的渲染器更加先进。CORRECT_Z_ORDER渲染器对3D对象在场景中的排序,使用了更加复杂的算法,能解决一些(不是全部)默认渲染器在z排序出现的问题。由INTERSECTING_OBJECTS属性返回的渲染器,更深一步使用拆分交叉三角形的方法。使用这些渲染器是相当简单的,首先引入渲染器Renderer类。 import away3d.core.render.Render
18、er;然后,在初始化函数initEngine()中,我们把从渲染器CORRECT_Z_ORDER或INTERSECTING_OBJECTS属性返回的对象传递给View3D对象的结构函数。 protected function initEngine():void scene=new Scene3D(); camera=new Camera3D(); view=new View3D( renderer: Renderer.INTERSECTING_OBJECTS ); scene=view.scene; camera=view.camera; addChild(view); view.x=stag
19、e.stageWidth/2; view.y=stage.stage.Height/2; 通过修改View3D的renderer属性,也能改变在运行中的有效的渲染器。 view.renderer=Renderer.CORRECT_Z_ORDER;RenderersDemo应用程序,允许你在程序运行的时候,通过按下键盘上的1,2,和3数字键,在三种渲染器间切换,这提供了一个比较三种渲染器是如何处理交叉3D对象的方法。 package import away3d.cameras.Cammera3D; import away3d.containers.Scene3D; import away3d.c
20、ontainers.View3D; import away3d.core.render.Renderer; import away3d.materials.WireColorMaterial; import away3d.primitives.Cube; import away3d.primitives.Triangle; import flash.display.Sprite; import flash.events.Event; import flash.text.TextField; public class RenderersDemo extends Away3DTemplate pr
21、ivate var triangle; private var box:Cube; public function RenderersDemo():void super(); protected override function initScene():void super.initScene(); triangle=new Triangle( edge: 150, bothsides: true, yUp: false, material: new WireColorMaterial(0x224488), z: 500 ); scene.addChild(triangle); box=ne
22、w Cube( z: 500, width: 50, height: 75, depth: 50, material: new WireColorMaterial(0x228844) ); scene.addChild(box); protected override function initListeners():void super.initListeners(); stage.addEventListener(KeyboardEvent.KEY_UP,onKeyUp); protected override function initUI():void super.initUI();
23、var text:TextField=new TextField(); text.text=”Press 1 to enable the BASIC renderer. n”+” Press 2 to enable the CORRECT_Z_ORDER renderer. n”+” Press 3 to enable the INTERRECTING_OBJECT renderer. n”+” Press 4 to make the box transparent. n”+“Press 5 to make the box opaque.”;text.x=10;text.y=10;text.w
24、idth=300;this.addChild(text); protected override function onEnterFrame(evevt:Event):void super.onEnterFrame(event);triangle.rotationY += 3;box.rotationY= -= 1;protected function onKeyUp(event:KeyboardEvent):void switch (event.KeyCode) case 49: view.renderer=Renderer.BASIC; break; case 50: view.rende
25、rer=Renderer.CORRECT_Z_ORDER; break; case 51: view.renderer=Renderer.INTERSECTING_OBJECTS; break; case 52: (box.material as WireColorMaterial).alpha=0.5; break; case 53: (box.material as WireColorMaterial).alpha=1; break; 下面的图形,可看到INTERRECTING_OBJECTS渲染器和BASIC渲染器是不同的,左边的是默认的BASIC渲染器,尽管这两个3D对象实际上是交叉的
26、,但三角形显示在立方体的后面。右边的是INTERRECTING_OBJECTS渲染器,它把各个三角形表面劈开,用正确的顺序描绘场景。由以上RenderersDemo应用程序建立的场景是简单的,仅包含了一个立方体原始模型和一个三角形原始模型,在这样的情形下,在三种渲染器之间的切换,也许在程序运行时没有很明显的影响效果。但是在一个更加复杂的场景中,将会是怎样的呢?RenderersPerformanceDemo应用程序,建立了很多在无形的盒子里到处弹跳的球体。正像RenderersDemo应用程序一样,你可在程序运行时,在三种渲染器之间进行切换。 package import away3d.cor
27、e.render.Renderer; import away3d.primitives.Sphere; import flash.geom.Vector3D; import flash.events.Event; import flash.events.KeyboardEvent; import flash.text.TextField; public class RenderersPerformanceDemo extends Away3DTemplate protected static const SPEED: Number=0.5; protected static const BOX
28、SIZE: Number=20; protected static const NUMBERSPHERS: Number=10; protected var spheres:Vector.=new Vector.(); protected var directions:Vector.=new Vector.(); public function RenderersPerformanceDemo() super(); protected override function initScene():void super.initScene(); this.camera.z=50; for (var
29、 i:int=0; i NUMBERSPHERS; +i) var sphere:Sphere=new Sphere( x: Math.random() * BOXSIZE-BOXSIZE/2, y: Math.random() * BOXSIZE-BOXSIZE/2, z: Math.random() * BOXSIZE-BOXSIZE/2, radius: 2 ); spheres.push(sphere); this.scene.addChild(sphere); directions.push(new Vector3D( Math.random()-0.5, Math.random()
30、-0.5, Math.random()-0.5) ); directionsi=normalize(); directionsi=ScaleBy(SPEED);protected override function initListeners():void super.initListeners(); stage.addEventListener(Event.ENTER_FRAME,onEnterFrame);stage.addEventListener(KeyboardEvent.KEY_UP,onKeyUp);protected override function initUI():void super.initUI(); var text:TextField=new TextField();text.text=”Press 1 to enable the BASIC renderer. n”+” Press
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 安全施救培训课件
- 安全方面培训课题课件
- 安全新员工培训课件
- 农业碳汇项目可行性研究与市场潜力分析报告
- 电力检修工程方案费用(3篇)
- 安全文明施工培训感想课件
- 房屋改造工程安全方案(3篇)
- 猫咪眼类疾病知识培训课件
- 工程部方案编制(3篇)
- 安全教育培训需求频次课件
- 2025年中国建筑集团招聘面试宝典与模拟题答案
- CQB战术课件教学课件
- 汽车客运服务合同协议书
- 稽核培训课件
- 2025-2026年秋季学期一年级开笔礼校长致辞稿:执笔启智 向新而行
- 2025强制执行申请书(范文模板)
- 《法律基础知识》教案
- 2025年浙江省中考道德与法治试题答案详解讲评(课件)
- 2025年电梯安全总监职责培训考核试题及答案
- 2025年国家能源集团四川公司集团系统内招聘10人笔试参考题库附带答案详解(10套)
- 碧海BH6000-1000型无菌纸盒灌装机学习资料
评论
0/150
提交评论