Posts Tagged ‘tip’

Papervision 3D + 3D/Post Software Workflow

在使用Flash 3D的实际工作中,我们经常会需要在3D空间中摆放物体,或者是去匹配平面Layout。但是由于可视环境的缺乏,我们常常要:调参数——看效果——再调参数……周而复始,费时费力。能不能有更好的方法呢?本文就介绍一下使用常见的后期或三维软件来做Layout,再完美转换回Papervision 3D中的方法。

首先我们来看看After Effects(AE),AE的三维层功能用来摆平面那是相当方便快捷。下图中我建立了一个985×600的合成,然后随便摆放了两个平面。

viewport

想象一下左边平面贴一张图片,右边平面贴文字,是不是就是一个常见的3D场景呢?接下来,就跟我一起把这个Layout还原到Papervision 3D中去吧。

第一步是相机参数的匹配,在AE中打开相机参数设置窗口:
More...

Interacting with Papervision 3D

本文讨论Papervision 3D中与鼠标互动相关的进阶问题:

  1. 3D物体的hit检测
  2. InteractiveSceneManager
  3. VirtualMouse
  4. Mouse3D

我们知道要让Papervision 3D的互动机制开始运作,必须满足以下两个条件:

  1. viewport.interactive = true;
  2. do3d.material.interactive = true;

然后我们就可以监听do3d发出的事件(InteractiveSceneEvent)。

那么Papervision 3D是怎样实现3D物体与鼠标的hit检测呢?

来看看Viewport类提供的以下实例方法:

  1. hitTestPoint2D()
  2. hitTestMouse()
  3. hitTestPointObject()


More...

New Pixel Aspect Ratios in AE CS4

image

是否发现After Effects CS4中的像素比设置有些许不同呢?这里有AdobeLynda.com上的解释。不过我还是看的一知半解,不知有达人能点拨一下否。

原来我们一直用的Pal制1.07的像素比是个错误的数值,但是这个数值却通用在所有的软件中,所以CS4的这个改动可能会带来一些兼容性问题。如果你像我一样希望能够在新旧两种设置中自行选择,那到这里向Adobe提出建议吧。

update 2009.03.21:这里已经有自定义的方法了

Papervision3D旋转和矩阵

想要深入学习Papervision3D,就要对DisplayObject3D(简称do3d)类非常熟悉。这个类是所有3D显示对象的基类,是Papervision3D系统的核心部分。本文分享一些do3d在变换操作方面的知识。

首先要了解一点:3D系统通常都用一个矩阵来表示自身的变换属性。对比Maya系统来看。一个几何体具有对应的变换节点和形状节点。do3d.transform属性就是pv3d中表现变换的节点。这是一个4X4的矩阵,要想了解矩阵是如何作用于物体的变换,可以看看pv3d.org给出的Matrix3D演示

矩阵用于内部计算非常方便,但是对一般用户而言非常不直观。所以一般3D系统还要提供x,y,z,rotationX,scaleZ等等我们所熟知的变换属性。这些变换属性仅仅是提供了直观的属性接口,但是它们不参与内部计算,在系统内部的机制实现都是直接计算矩阵的。

(一)如果我们改变了某个变换属性,那么系统就需要更新矩阵。出于算法的优化考虑,这种更新不是马上就计算的。而是用do3d._transformDirty属性做一个标记,到需要的时候才进行计算。

那么什么时候才进行真正的计算呢?最通常的情况是在一个渲染流程开始的时候,场景中所有do3d的变换矩阵都会被更新(参看project()函数)。另外还有一些方法会触发矩阵的更新,如:translate(),copyTransform()等,请参看下面的图。

papervision

如果需要在一个渲染流程开始以前更新矩阵,可以调用do3d的公开方法updateTransform()。

(二)相反的,如果我们改动了矩阵,那么就需要保证变换值被更新。do3d类提供了一些很实用的方法如yaw(),pitch(),lookAt()等。它们的共性就是直接操作矩阵。执行过这些方法后,do3d._rotationDirty就被设置了标记,表示着旋转值和缩放值需要更新。

与上一情况不同的是,除非我们直接访问这些属性,否则这些更新都不会被计算。而且更新这些变换值的操作:updateRotation()是一个私有方法,不允许我们直接调用。这里就必须特别注意,如果我们使用Matrix3D或Quaternion之类的方法直接更改矩阵,是无法让变换值得到更新的。不正确的rotation值在渲染流程中不会引起问题,但是必须小心,不要让别的程序访问这些错误的值。对此,我想过一个解决办法:就是在矩阵操作以后,调用一次yaw(0)产生一次空旋转。这样就可以触发do3d._rotationDirty的更改,从而可以计算正确的变换值。但这仅是一种变通的办法,最佳的做法应该是避免程序同时依赖于矩阵和变换属性。

最后还要注意一点。updateRotation()方法执行了一个变换矩阵转欧拉角的算法。这种操作在数学中是建议尽量避免的。原因是会产生万向节死锁的问题,计算出的一个轴的旋转角不是我们所希望的0~360连续范围。所以如果调用过上图中标识为“直接改矩阵”的方法后,再使用do3d的旋转值的时候,要特别的注意。

Barcinski & Jeanjean Website (Part3)

view Barcinski & Jeanjean Website (Part1)
view Barcinski & Jeanjean Website (Part2)

另一个让人头疼的问题来了:文件量。搞一个高端的用户体验,在精度上总不能太寒碜,但是又怕用户等不了,怎么办?一开始加载的时候,他们为大家准备了一个 3D 弹球游戏,在一定程度上减弱了用户等待的焦虑感。但是网站内里太大太慢也是不行的,真功夫还是要拿出来的。

问题是背景,该用图片序列还是视频?一般经验告诉我们,像这种全景的东西,顺放倒放的,肯定都是用序列:flv倒放会卡。比如经典的IKEA网站用的就是图片序列。但是,这是过去的经验了。Barcinski & Jeanjean 告诉我们:jpg效率低,用 flv 才是高效,而且文件量小。How could it be?

OK,不知道大家是否有注意,在编码 flv 的时候可以设置关键帧距离。下图是AE里截的,Flash自带的编码器也可以设置。

SNAG-000[2]

一般我们都用自动方式,所以没太注意。但是如果将这个值设为1,那么就等于每一帧都编码为关键帧。由于播放器在解码非关键帧的时候需要在这一帧之前的关键帧数据,所以顺放和倒放的区别就在于:当前帧依赖的关键帧是否已经读取到内存中。那么如果每一帧都是关键帧,那顺放和倒放并没有区别!这样的设置无疑会增加 flv 的大小,但是还是比 jpg 序列小很多。而且在执行效率上,解码 flv 比 解码 jpg 速度快!感谢技术的进步,我们终于可以和臃肿的 jpg 序列说拜拜了!

过去还有个经验是:先载小图,再载大图盖上去。但是在这个网站里并没有这种做法,对此他们的解释是:无法忍受freeze。因为大图片的解码过程会让 Flash Player卡住,通常情况下,用户不会注意到这瞬间的停顿。但是这里场景中结合了Papervision3D制作的纸,具有动态的物理效果,这样的停顿 就会很明显。因此他们采用直接加载最终精度的flv的办法。

还记得IKEA网站中独特的加载方式吗?那是一种将序列重新组织的方法。可以让用户边下载边体验,没加载到的部分是过不去的。Barcinski & Jeanjean 面临同样的难题:即便用了flv压缩,主文件还是有16m之大。他们想了个天才的解决方法,在这篇文章里他们画了一个圆饼图表述了他们的思路。我总结一下:首先是在这个网站里达到平滑顺畅的全景体验需要144帧,如果我们隔一帧就抽掉一帧,就能省掉一半的文件量。此时播放的原始帧序号为“1,3,5,7,9,11,...”。如果我们再重复一次上一步的抽帧操作,那就只剩1/4的文件量了,已经降到的3M左右可以接受的范围。经过两次抽帧的文件只剩下36帧,此时播放的原始帧序号为“1,5,9,13,...”。抽帧后的视频仍然是一个完整的全景循环,只是不够平滑而已。

方法出来了:我们先提供经过抽帧两次的视频,用户加载完这个文件已经可以正常的浏览网站。然后在后台继续加载第二次操作中抽去的那部分,当这个文件加载结束后,就已经还原了1/2的帧数。最后再把剩下的1/2——也就是所有的偶数帧组成的视频文件加载进来。
More...

Page 1 of 41234»