Pv3D-4.材质.doc_第1页
Pv3D-4.材质.doc_第2页
Pv3D-4.材质.doc_第3页
Pv3D-4.材质.doc_第4页
Pv3D-4.材质.doc_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

4 Materials 材质(让一个不懂英语的人来翻译这部好书,真费神啊,此书的作者英语写作功底何等了得,到处都是从句,oh my god!终于结束了)。这一章中我们学习材质以及材质是怎么贴到3D物体上去的。有大量的可用的材质类型。从简单的图像到可以与鼠标交互的影片剪辑(MovieClip)和视频流都可以用做素材。每个类型都有些“偏门”,所以都饱受褒贬。所以多所有的材质深入了解才能让你选择材质时做出更好的选择。这章主要论述以下主题:l 介绍材质l 相框材质和颜色材质(简单材质)l 装载位图作为材质的方法l 使用影片剪辑材质的方法l 视屏流材质l 混合材质l 物体和材质的交互性l 使用材质的注意点和技巧l 例子:创建一个旋转木马效果介绍材质材质就是物体的纹理。如果物体上不填上材质,在场景中就看不到这个物体。给物体选择合适的材质可以让简单的物体看上去很真实和有趣。纹理和材质的区别在于纹理是被用作材质的图像源。材质可以修改属性从而影响纹理贴到物体上的效果,你也可以这样理解材质,就是扩充了的纹理。在我们介绍每一种材质前,我们将先来检查下材质是如何产生效果的。在PV3D中,材质有些争议。,了解了他们的如何产生效果可以帮助我们解决对他们的争议。基本属性:所有的材质继承自一个特殊的基础材质类叫做MaterialObject3D。这个基础类有一些所有子材质类通用的属性,但是某些属性只对某些特殊材质类型起作用。比如可以控制材质平铺的属性就不能用于简单颜色材质,材质平铺是指用一副图在纵向或者横向重复放置的效果。在介绍每一种材质前我们先来介绍对于所有材质都有用的三个属性:l 双面和单面贴图l 反面贴图l 光滑度当我们设置材质对象的doubleSided属性为true时,我们将对构成物体的三角面两面都可见。什么意思呢?比如对于一个plane对象,就是正面和反面也能看到贴图材质;如果对于一个球体或者长方体就是里面和外面都能看到贴图材质,设置方法如下,用哪种无所谓。material.doubleSided = true;或者material.oneSide = false;默认的一个3D物体的面会被实现定义为前面和后面(正面和反面),而材质也默认贴在物体的前面(正面)。但是有时候我们只需要贴在后面(反面),这怎么办呢?比如对球体贴图,默认的是贴在外面,如果我们只要要在球体的内侧贴图呢?贴两面肯定会多增加cpu负担,这时候我们就可以将opposite属性设置成true就ok了。material.opposite = true; opposite:相反由于3D透视算法对材质的变形和缩放,材质会变得像素化。改变材质的光滑度属性可以解决这个问题。material.smooth = true; smooth:光滑遗憾的是,光滑处理会影响到性能。所以在启用这个属性的时候请斟酌下。再接下来的章节中我们会介绍到位图材质(BitmapMaterial)的光滑度属性。第13章,我们来谈谈优化性能的技巧。基础材质有两种类型的基础材质:l 线框材质l 颜色材质我们把他们归于基础材质是因为他们在实际项目中很少使用。其他的材质提供了更多的功能,并且在做一些模拟现实世界的项目中更加有用。讨论完了这两种材质我们就来介绍他们。线框材质到目前为止出现在例子中的物体我们用的都是线框材质,这是PV3D的默认材质。它在3D物体的所有的三角面之间都画上线条,形成一个看上去由三角形网格连起来的物体。在调试时期用的比较多因为它可以实时展示三角面是如何画出来的。虽然听起来它像一个轻量级的材质,实际上渲染起来还是很吃力的。因为它是用flash内置的画线方法来绘制的,而这个过程是比较费时的。线框材质默认的被使用在PV3D内置3D模型上(如飞机 球等)的创建过程中,然而,我们仍然可以手工创建线框材质。让我们创建一个叫WireframeMaterialExample的项目,手工定义材质。我们先导入相框材质类。像大多数材质一样线框材质放在org.papervision3d.materials包中。在类的顶部加入以下两行:import org.papervision3d.materials.WireframeMaterial;import org.papervision3d.objects.primitives.Cone;在你的项目中,内嵌一个材质类型的局部变量来代替类属性可能会出一些问题,所以将它定义成类属性。当一个材质被定义成内嵌的,你将它指向一个对象,那么以后再也不会用到它了(译者注:因为指向这个材质的变量你无法访问,所以建议你将材质类型的变量申明成类属性,以提高材质的复用性)。如果定义成了类属性,你以后还想想调用这个材质,你就可以使用对象的material属性,并且转变成材质类型。比如:var material:WireframeMaterial = do3D.material as WireframeMaterial;创建一个相框材质对象时,可以使用三个参数:参数数据类型默认值Description1Color颜色Number0xFF00FF一个24位的颜色值,画线框时线条的颜色2Alpha 透明度Number1透明度值(0-1),线条的3Thickness粗细Number00-2550 表示极细线,也是默认值Flash使用24位和32位两种颜色值,24位包括红绿蓝(RGB)三个颜色通道每个通道可以表示256种颜色。256x256x256=224种颜色。所以叫做24位色。而32位色其实就是增加了个透明度通道为A,32位色就是RGBA, 透明度也分成了256个值。0表示完全透明,256(0xFF)表示完全不透明。32位色和24位色都可以用16进制表示。24位色:0x00FF00,00-红色值 FF-绿色值 00-蓝色值32位色:0x00FF00FF,00-红色值 FF-绿色值 00-蓝色值 FF-透明度。大多数情况我们使用24位色,另外在提供一个透明度参数来。但是在某些场合,你得使用32位色来替代24位色。线框材质使用24位颜色值和另外提供一个透明度值。如果没有使用参数,就都会采用默认值。下面我们创建一个圆柱体使用50%的透明度的相框填充,线条粗细设为2.private function init():void var material:WireframeMaterial = new WireframeMaterial(0x000000,0.5,2); var cone:Cone = new Cone(material,500,500); scene.addChild(cone);源文件见:WireframeMaterialExample.现在我们知道如何创建一个相框材质,接下来介绍如何使用颜色材质。颜色材质第二个基础材质是颜色材质。一看名字就知道它是将颜色作为材质,使用起来就像线框材质那样简单,在前面的介绍内建模型的章节中,我们已经学洗了如何在一个立方体上使用材质。ColorMaterial实例化时有以下参数可供使用:ParameterData typeDefault valueDescription1Color颜色Number0xFF00FF(品红色)24位的填充色2Alpha透明度Number1 (不透明)透明度:0到1。3Interactive交互性BooleanFalse(不支持)设置材质是否支持交互:如鼠标单击除了Interactive参数,其余参数跟线框材质的参数是一样的。(对原书省略两节,无关紧要)private function init():void var material:ColorMaterial = new ColorMaterial(0x00FF00,0.5); var cone:Cone = new Cone(material,500,500); scene.addChild(cone);别忘了导入org.papervision3d.materials.ColorMaterial类。源文件见:ColorMaterialExample。以上可见,这两种材质使用起来比较简单。三种使用位图材质的方法虽然定义相框材质和颜色材质比较简单但是效果不好。大多数程序都想使用位图材质来增添真实感,如果能灵巧的使用位图材质,即使简单的3D物体看上去也会逼真不少。(这段内容的原文比较难理解,我把我的理解整理如下: )创建位图纹理这类事情可以交给photoshop和paintshop por等软件。这是它们的强项。让物体不丢失性能且能增加一些额外的细节的技巧叫做烘焙纹理。在大多数的3D软件中都支持实时的给物体亮化或者暗化,再或者映射周围的环境。PV3D也支持这些。但是这些操作很费系统资源(比如CPU计算)。所以我们可以将某些实时效果用图像处理软件预先做在位图中,再导入到PV3D中,这样就省略了实时处理所需要的系统资源。使用位图材质就像定义线框和颜色材质一样的简单。根据你的需要你可以使用规则的Bitmap对象、外部的位图或者库元件作为材质。BitmapMaterial 位图材质可能你已经猜到,位图材质就是由位图做成的材质类型。位图对象可以通过代码绘制出来,或者调入外部图像文件,或者库中的一个图像元件。对于要使用外部图像和图像元件作为材质,我们可以将它们申明成BitmapMaterial类型的子类型。举个例子,我们可以用代码画个圆用作位图材质。我们来了解下如何手动的加载一个外部的文件。实例化一个BitmapMaterial对象有以下两个参数:参数数据类型默认值描述1asset元件BitmapData位图数据nullThe object that holds BitmapData. 持有BitmapData的对象2precise精细度Booleanfalse当设置为true时,就会动态的创建额外的三角面用更精细的方式来绘制材质接下来两个例子演示了如何使用位图材质。Using a bitmap shape as material that is generated by code用代码生成的位图形状作为材质BitmapMaterialShapeExample是我们介绍的第一个例子。我们将用flash图像接口直接绘制一个圆,然后转换成BitmapData类型。然后用在一个三维的平面上。首先我们要导入到要使用的类:import flash.display.BitmapData;import flash.display.Shape;import org.papervision3d.materials.BitmapMaterial;import org.papervision3d.objects.primitives.Plane;在init()方法中我们定义了一个Shape类型的对象,在这个Shape对象上画个圆。在(100,100)位置绘制一个半径200的圆。private function init():void var circle:Shape = new Shape(); circle.graphics.beginFill(0xFF0000); circle.graphics.drawCircle(100,100,100);创建一个位图材质(BitmapMaterial)的实例,位图材质的第一个参数是BitmapData类型的,所以我们需要将我们创建的Shape对象做转换。(不要和Bitmap对象混淆我们要的是一个BitmapData对象),让我们了解下如何创建一个BitmapData对象,前面的两个参数定义了宽和高,第三个参数为透明度。最后一个参数是原始填充色(BitmapData可以理解为一个画板,上面的每一个点都记录着当前位置的颜色信息)。为了能在Shape对象上看到一个圆,我们将最后一个参数设为0x0,。在创建好了BitmapData对象后,我们在BitmapData对象(画板)上画上圆。(这里解释一下 为什么我们不直接在画板上画圆,因为BitmapData并没有这个API,也就是不支持drawCircle()方法,当然方法还是有的,具体可以看Adobe官方帮助文档的BitmapData类的说明)。var bmp:BitmapData = new BitmapData(200,200,true,0x0); bmp.draw(circle);然后我们创建一个位图材质对象,用bitmapData作为参数。var material:BitmapMaterial = new BitmapMaterial(bmp);然后以这个位图材质对象为参数,在场景中添加一个平面。var plane:Plane = new Plane(material); scene.addChild(plane);编译发布后你回返现这个平面上的圆边上有毛刺现象(不圆整)。这时候我们就要用到前面提到的材质的三个公共属性中的Smooth属性(光滑度)。只要在创建material变量的下面添加一行代码就可以解决这个毛刺现象了,注意这也是会消耗一点CPU资源的。material.smooth = true;源文件看:BitmapMaterialShapeExampleManually loading and assigning an external bitmap as material手动装在外部位图文件作为材质。先看下面的代码package import flash.display.Bitmap; import flash.display.Loader; import flash.events.Event; import .URLRequest; import org.papervision3d.materials.BitmapMaterial; import org.papervision3d.objects.primitives.Plane; import org.papervision3d.view.BasicView; public class BitmapMaterialImageExample extends BasicView public function BitmapMaterialImageExample() stage.frameRate = 40; init(); startRendering(); private function init():void /Start loading the image and define an on complete event listener var imgLoader:Loader = new Loader(); imgLoader.contentLoaderInfo.addEventListener (Event.COMPLETE,loadComplete); imgLoader.load(new URLRequest(assets/mill.jpg); private function loadComplete(e:Event):void /Loading complete. Cast target content as a Bitmap /and use its bitmapData for creating a BitmapMaterial var bitmap:Bitmap = e.target.content as Bitmap; var material:BitmapMaterial = new BitmapMaterial(bitmap.bitmapData); var plane:Plane = new Plane(material); scene.addChild(plane); override protected function onRenderTick(e:Event=null):void super.onRenderTick(); 请注意转载的图片文件的目录。这个图片在在下载的代码文件中有,当然你也可以用其他图片文件来代替它。这些代码执行效果是在屏幕显示一幅图片,我们如何让这幅图片旋转呢?注意 创建一个旋转地平面在当前的例子中会有一些问题。上面的类中plane对象我们没有申明位类属性,所以我们不能在render方法中控制它,因此也不能改变他的旋转度。另外注意我们在plane创建之前就开始渲染了。在下一节中我们会掩饰如何在平面被初始化后才开始材质的渲染。改变上面的例子,沿着轴旋转这个平面。确保你创建的平面有足够多的片段。并且设置成双面。你会看到类似下面的结果BitmapFileMaterial 位图文件材质我们已经知道如何创建一个位图材质,并且应用到一个平面上,我们也可以加载一个外部文件并且用文件中包含位图数据来创建一个位图材质。但是有一种更为方便的方法从外部加载图片作为材质。这就是BitmapFileMatreial类。它继承自BitmapMaterial类。并且帮你把装在过程中的麻烦都代劳了。创建一个BitmapFileMaterial对象很简单,它有两个参数。参数数据类型默认值描述1url路径String指向外部文件的路径2Precise精度Booleanfalse定义是否使用材质的精度第一个参数是必要的。第二个参数可以省略,默认值为false。当材质还未加载好之前纹理将显示为黑色。让我们来看看在上一个例子上我们如何来加载一幅图。源代码如下:package import org.papervision3d.materials.BitmapFileMaterial;import org.papervision3d.objects.primitives.Plane;import org.papervision3d.view.BasicView;public class BitmapMaterialImageExample extends BasicViewpublic function BitmapMaterialImageExample()stage.frameRate = 40;init();startRendering();private function init():voidvar material:BitmapFileMaterial = new BitmapFileMaterial(assets/mill.jpg);var plane:Plane = new Plane(material ,500,375,2,2);scene.addChild(plane);代码精简了不少了吧。当使用BitmapFileMaterial时,请设置Plane对象的宽和高。当将一个平面对象和文件材质结合时。你应该总是设置好宽和高。否则程序会自动的将位图的大小设置为平面的大小。在图片加载好之前,程序是不知道图片的大小的,这样在你在看到平面之前它的大小会被先设为0x0。 当你编译发布时,一开始平面呈现一会的黑色,然后才显示图片纹理,若要防止这种事情,就必须在纹理加载好后在开始渲染工作。但是我们怎么知道纹理文件加载好了呢?我们并不知道BitmapFileMaterial类中有关加载图片文件的Loader对象。幸好PV3D为我们想到了。在文件加载好时,BitmapFileMaterial对象会发出一个FileLoadEvent.LOAD_COMPLETE事件。FileLoadEvent事件对象时PV3D定义的事件类型。还有另外一些类也使用这个事件。与BitmapFileMaterial对象有关的有四种类型的事件:l FileLoadEvent.LOAD_COMPLETE: 外部位图加载完成时,发出该事件。l FileLoadEvent.LOAD_PROGRESS: 外部位图加载过程中,发出该事件。l FileLoadEvent.LOAD_ERROR: 外部位图找不到时,发出该事件。l FileLoadEvent.SECURITY_LOAD_ERROR: 安全错误发生时,发出该事件。要使用这个事件,必须先导入该类:import org.papervision3d.events.FileLoadEvent;我们可以直接在创建的BitmapFileMaterial对象添加一个时间侦听器,监听它发出的LOAD_COMPLETE事件:material.addEventListener(FileLoadEvent.LOAD_COMPLETE,loadComplete);接着我们还要定义一个方法。下免得代码比较有用,他可以让多个BitmapFileMaterial对象在加载完文件后调用。private function loadComplete(e:FileLoadEvent):void trace(Completed loading file: + e.file); startRendering();在这个方法中我们才开始渲染。When you publish this code, you should see the following output:Completed loading file: assets/mill.jpgBitmapAssetMaterial 位图元件材质位图元件材质也是继承自bitmapMaterial,是另一个很方便的定义位图位材质的类。BitmapAssetMaterial把图形元件中的位图数据(BitmapData)取出用作材质,因为FlexBulidler和flashBuilder都没有像flash那样的库,所以这个是给Flash IDE专用的。这个类有两个参数:参数数据类型默认值描述1linkageIDStringFlash库文件的中元件的连接标示符2Precise精度Booleanfalse定义是否使用材质的精度让我们看看如何在Flash中定义一个库元件,以便我们能将它和BitmapAssetMaterial结合起来使用。1. 先导入一个图想到你的库中。(不是舞台)2. 在库中右击图像选择“属性property”3. 一个名叫“Bitmap Property”的窗口弹了出来4. 如果高级面板未打开则打开它5. 勾选为ActionScript导出复选框6. 勾选在第一帧导出复选框7. 类和基类在上面的勾选后自动填充,你也可以自定义命名。但是请别改基类名。并且记住类名,一会我们要将这个名作为参数来创建BitmapAssetMaterial对象8. 单击OK 这样我们就设置好了一个库元件了。下面我们来使用它。先导入这两个类文件:import org.papervision3d.materials.BitmapAssetMaterial;import org.papervision3d.objects.primitives.Plane;接着我们创建一个 BitmapAssetMaterial对象。将元件的类名作为第一个参数。 private function init():void var material:BitmapAssetMaterial = new BitmapAssetMaterial(mill);var plane:Plane = new Plane(material,500,375,2,2); scene.addChild(plane);可以查看BitmapAssetMaterialExample源代码。在Flex Builder and Flash Builder中使用元件是将元件转换成BitmapAsset对象 ,然后用BitmapAsset的bitmapData属性然创建一个常规的BitmapMaterial.对象。嵌入也可以实现。使用元数据标签Embed:如下面的代码所示:Embed (source=assets/mill.jpg) public var mill:Class;我们将mill.jpg文件导入为元件。命名为mill类,下面这行代码将创建mill对象并将它转换成BitmapAsset格式。var millAsset:BitmapAsset = new mill() as BitmapAsset; 然后创建位图材质,就像我们前面的做法一样。var material:BitmapMaterial = new BitmapMaterial(millAsset.bitmapData);注意 这种方法只能在flex Builder 和Flash Builder 中使用。并且没有用到BitmapAssetMaterial类。现在我们已经知道如何使用位图材质了,接下来我们介绍另一类材质-MovieClips。Two ways of using a movie clip as material两种使用影片剪辑作为材质的方法在很多场合中使用位图材质已经相当不错了。这类材质很想其他3D建模软件。但是我们用的不是3D建模软件,而是Flash。Flashplayer如此盛行的理由是因为它能创作出色的,轻量级的动画。并且到了如今,Flash已经发展成了开发RIA(客户端应用)最有力的工具了。我们在创建PV3D场景时能使用Flash的优势将是多么好呢。换句话说就是能将动画作为材质,或者将RIA作为材质。你可以使用MovieClip来创建MovieMaterial对象作为材质类型了。本质上这个是跟bitmapMaterial是类似的,然而影片材质仅有两种类型。l MovieMaterial l MovieAssetMaterial也许你期待这与BitmapFileMaterial材质有些相似点,但是要令你失望了。接下来学习两种影片材质的使用方法。MovieMaterial 影片材质A movie clip-based material works with every type of object that inherits from a DisplayObject. This is usually a sprite or a movie clip. The MovieMaterial class works with any display object that is accessible by code. Instantiation of a MovieMaterial takes a few new parameters. Lets have a look at each in the following table:一个基于影片剪辑的材质对继承自DisplayObject(Flash的任何可视对象的基类)的对象都有效。可能是一个Sprite对象,亦或者是MovieClip对象,只要是DisplayObject类型的对象都是可以的。创建MovieMaterial对象时有如下几个参数:参数数据类型默认值描述1movieAssetDisplayObjectnullDisplayObject对象的引用2transparentBooleanfalse材质是否支持透明度3animatedBooleanfalse如果设置为True,将对影片元件的每一帧都建立快照然后绘制在材质上。这时相当耗费CPU资源的。默认没有开启4preciseBooleanfalse精度5rectRectanglenull一个可选参数定义了材质的边界如果你的影片剪辑在play过程,大小会变,那么这个参数是不错的如果没有定义就将影片元件的当前帧的大小设为材质的边界值为了解释这种材质是如何使用的,我们创建一个Sprite对象,在上面画一个矩形,添加上文本字段。然后用这个Sprite来创建一个影片材质。然后应用到一个旋转平面上。源代码如下:package import flash.display.Sprite;import flash.events.Event;import flash.geom.Rectangle;import flash.text.TextField;import flash.text.TextFieldAutoSize;import flash.text.TextFormat;import org.papervision3d.materials.MovieMaterial;import org.papervision3d.objects.primitives.Plane;import org.papervision3d.view.BasicView;public class MovieMaterialExample extends BasicViewprivate var plane:Plane;public function MovieMaterialExample()stage.frameRate = 40;init();startRendering();private function init():voidvar materialSprite:Sprite = new Sprite();materialSprite.graphics.beginFill(0x333333);materialSprite.graphics.drawRect(0,0,200,200);var textfield:TextField = new TextField();textfield.text = Hello 3D world!;textfield.autoSize = TextFieldAutoSize.LEFT; textfield.setTextFormat(new TextFormat(Arial,25);textfield.x = (materialSprite.width - textfield.width) / 2;textfield.y = (materialSprite.height - textfield.height) / 2;materialSprite.addChild(textfield);addChild(materialSprite);/关键看这里var material:MovieMaterial = new MovieMaterial(materialSprite);material.smooth = true;material.doubleSided = true;plane = new Plane(material);scene.addChild(plane);override protected function onRenderTick(e:Event=null):voidplane.localRotationY+;super.onRenderTick();MovieAssetMaterial 影片元件材质这个类的作用类似于BitmapAssetMaterial类。也仅仅能在flash IDE中使用。创建MovieAssetMaterial对象时有如下参数:参数数据类型默认值描述1linkageIDString库中影片剪辑的连接标示符2transparentBooleanfalse透明3animatedBooleanfalse见上个表格4createUniqueBooleanfalse是否创建一个副本5preciseBooleanfalse精度将影片作为材质就赋予了材质表现动画的能力。可以用代码结合MovieMaterial类来实现。或者基于时间轴结合MovieAssetMaterial类来实现。让我们先在Flash里实现。创建一个MovieClip影片剪辑,做一些动画效果在里面,为了理解影片元件如何材质化,我们在影片元件中加入一些补间。在下载的例子中,我们在影片剪辑中添加了一个背景图形,两个移动的的文本字段,一条粗线从左至右。在编译发布后,这条线将会提示我们在普通情况下会出现的一系列问题。在你创建好你的动画后,你需要给你的原件定义好连接标示符属性。这个上面我们设置位图元件的连接标示符很相似。1. 在元件上右击,选择“属性”2. 一个名为“Symbol Property”的窗口弹出来了3. 如果高级面板未打开则打开它4. 选择为ActionScript导出。5. 勾选在第一帧导出6. 定义一个类名。类名用于创建MoiveAssetMaterial对象时作为参数(连接标示符)来传递7. 基类不用修改仍然为flash.display.MovieClip8. 点击OK完成当元件定义好后,你就为创建MovieAssetMaterial对象做好了准备。这里我们让平面转动起来以暴露出某些问题,然后我们讨论如何解决这些问题。导入需要用到的类:import flash.events.Event;import org.papervision3d.materials.MovieAssetMaterial;import org.papervision3d.objects.primitives.Plane;import org.papervision3d.view.BasicView;将plane对象定义为类属性:private var plane:Plane;在init()方法中。我们创建一个MovieAssetMaterial对象,第一个参数是字符串“material”,它是我们前面在Flash库中为影片剪辑定义的连接标示符。第二个透明度参数设为false,第三个动画参数设为true,剩下的参数我们忽略。private function init():void var material:MovieAssetMaterial = new MovieAssetMaterial(material,false,true); material.doubleSided = true; plane = new Plane(material,500,500); scene.addChild(plane);编译发布后你会立刻注意到有些异样,如下图所示:下表罗列了出现的问题和问题的成因:问题原因纹理漂移Caused by the movie that changes size during animation文本闪烁和像素化Caused by skewed bitmaps纹理弯曲了Caused by using a low number of segments纹理从左至右漂移时因为他影片剪辑在play的时候尺寸在改变。能看到黑色背景是因为设置了透明属性为true,所以要设为false。漂移也有一种简单的办法。你必须为纹理定义一个矩形对象,在讲解MovieMaterial类时,构造函数的第五个参数就是一个矩形对象。MovieAssetMaterial类略微有些不同。它将这个参数内化为一个属性,MovieMaterial类也有这个属性。所以只要加入以下代码:material.rect = new Rectangle(0,0,200,200);再次编译发布,纹理漂移的问题解决了。第二个问题是闪烁和文本像素化了。当我们使用位图作为材质之前我们见过像素化。解决方法是开启光滑属性。这里解决的方法是一样的。material.smooth = true;重新编译发布后,效果就更好了。如果平面上的文字高度曲解你就不能阅读它了,这正是pv3d得软肋。PV3d 将材质成2D方式扭曲,造成透视的假象。变形、扭曲后的图片贴在3D物体上看上去就很逼真了,这种PV3D的贴图方式我们叫做仿射贴图。我们没有给Plane对象提供纵向和横向分段,那么Plane对象在横向纵向都只有一个分段。那么由于平面材质上有了文本和线条,就很容易看出这个Plane对象是有两个扭曲的三角形面构成。在下面的图中,你可以看到有一条虚线隔开的三角形面。设置precision属性为True,可以解决这个问题。我们在位图和影片材质的构造函数中都看到了这个参数。有两种方法可以操纵precision函数。l 创建MovieAssetMaterial对象时,将第五个参数设为True:var material:MovieAssetMaterial = new MovieAssetMaterial(material,false,true,false,true);l 直接设置precision属性为True:material.precise = true;当precise属性设置为True时,PV3D将自动的将三角形面细分以创建更多的新的三角形面这样就更精确了。这种效果是立竿见影的。但是也产生了一个新的问题。当涉及到照相机的角度的每一次改变,PV3D都要唱建一些新的三角形面,这个前面的有很大的区别。这会引起文本晃动和闪烁。我们有下面两种方法可以控制这种行为。u 增加更多的三角形面u 定义精度模式我们创建的平面横向纵向都只有一个分段,那么我们就在创建时使用多个分段来产生多个三角形面。再与precision属性设置为True结合使用摇晃闪烁效果就不易察觉了。另一种方式就是定义精度模式来避免摇晃闪烁效果。精度模式默认为:PrecisionMode.NORMAL,我们将它设置为:PrecisionMode.STABLE。先导入这个类。import org.papervision3d.materials.utils.PrecisionMode;然后将材质的precisionMode设置如下:material.precisionMode = PrecisionMode.STABLE;这种方法可以将我们的问题降低到可以接受的程度。但是,记住哦,这些都是以消耗CPU资源为代价的,所以在实际使用的时候还是多琢磨琢磨,如何取舍才能得到一个性能和效果的平衡。源代码看MovieAssetMaterialExampleVideoStreamMaterial 视频流材质虽然我们可以利用MovieMaterial,手动的将视频作为材质使用,但是VideoStreamMaterial可以自动的为我们做这些。VideoStreamMaterial类继承自MovieMaterial,构造函数有五个参数:ParameterData typeDefault valueDescription1Video视频Video用做抓拍源的视频实例对象2Stream流NetStream操作视频的NetStream对象3Precise精度Booleanfalse材质的精度4Transparent透明度Booleanfalse创建的材质是否支持透明度这个类可以展示渐进式视频或者流视频,甚至可以使用摄像头的输出流。接下来我们就以视频摄像头输出为例来制作一个例子。这个例子使用了一些不同的类:import flash.events.Event;import flash.media.Camera;import flash.media.Video;import .NetConnection;import .NetStream;import org.papervision3d.materials.VideoStreamMaterial;import org.papervision3d.objects.primitives.Plane;import org.papervision3d.view.BasicView;创建VideoStreamMaterial对象的第一个参数是一个Video对象。我们先定义一个视频对象。创建一个视频对象,让它捕捉摄像头。如下所示:private function init():void var video:Video = new Video(); video.attachCamera(Camera.getCamera();一旦你使用摄像头作为视频流输入。你既不不能用NetStream对象也不能用NetConnection对象将视频流输出到流媒体服务器了。但是当你要使用流式或者渐进式视频时,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论