Papervision 3D 学习之路(2)渲染过程

  •  如何显示物体

       1>  Add Viewport to Stage or Sprite.

       2>  Create 3D object (like Plane ...) with material and texture.

       3>  Add 3D object to Scene3D, ( 其实Scene3D 就是一个用来保存所有Object3D的列表)  

       4>  Set Camera

       5>  renderer = new BasicRenderEngine() ; renderer.renderScene( scene, camera, viewport ) 将scene中的Object 按照 camera 的视角绘制在viewport中。

 

  • PV3D优化CPU占用技巧

     我引用一篇Blog的内容 http://kevincao.com/2008/04/18/pv3d-issue-of-optimizing-cpu-usage/#more-534 我觉得写得很不错,对研究Papervision3D 如何渲染也是非常有帮助。

 

      按照常规的方法,先逐步减少透明元素等占用资源最大的“罪魁祸首”,如高光动画,阴影等。但是效果不大(只有5%~10%左右的降幅)。

      随后尝试将贴图的MC设置为位图缓存(cacheAsBitmap),但其实这步也是无效的。因为PV3D引擎本身就会把所有的元素做位图缓存再重绘。

      再尝试把StageQuality降下来,通常做法是运动的时候把质量设置为LOW,待到运动结束再恢复为HIGH。

      但是这种做法还需要一个前提才可能成立:那就是我们假设运动等同于屏幕重绘,也就是说运动时设置屏幕重绘,不运动的时候屏幕不重绘。所以我们必须处理 Event.ENTER_FRAME 事件,使其中的逻辑符合我们的假设,那么优化才可能有效。

 

      那么现在问题的症结已经清晰:PV3D引擎的每帧重绘是最占用资源的操作,我们应该减少不必要的重绘。特别是这种互动导航类型的应用,一旦状态固定,就必须移除重绘。

      于是我尝试加入状态判断的逻辑,当检测到运动结束后移除 Event.ENTER_FRAME 的侦听。但是产生了一个致命的问题:一旦renderer.renderScene()不执行,鼠标事件(InteractiveScene3DEvent)也侦听不到了。看来PV3D的互动支持必须依赖于每帧重绘或者是重绘方法其中的一些步骤。接下来就让我们把鼠标事件响应的功能找回来。

 

     仔细分析一下renderScene()的方法,发现当一个渲染流程结束后,渲染引擎会发出一个 RendererEvent.RENDER_DONE 事件。而通过Viewport3D的lastRenderer属性,如果场景允许互动,这一事件会被interactiveSceneManager对象侦听到。

     在PV3D引擎中,如果Viewport3D的interactive设为true,即场景是允许互动的,那么Viewport3D就拥有一个interactiveSceneManager对象(简称ism)。这个对象总管了所有互动事件的接收和发送。看来目标已经明晰,ism对象的updateRenderHitData()方法处理互动响应。而且这是一个公开方法,这意味着我们可以从外部手动执行它,而不用依赖于对 RendererEvent.RENDER_DONE 事件的监听。

     所以以下是优化过的 Event.ENTER_FRAME 事件处理函数:

  1. protected function update3D() : void {
  2.     if(cached) {
  3.         viewport.interactiveSceneManager.updateRenderHitData();
  4.     } else {
  5.         renderer.renderScene(scene, camera, viewport);
  6.     }
  7. }

   

        其中的cached变量用来表示场景是否运动。在鼠标事件触发的时候设置为false,意味着需要重绘整个3D场景。在运动结束后(我用Tweener来实现运动,所以对onComplete事件添加回调函数)改变cached为true。此时只需要更新交互数据就可以了。从而大大减少了CPU占用。

       在发现上述解决方法以前,我还研究出了另一种方法,虽然效果不如上述方法好,代码也不干净,但是一些思路还是有一定的参考意义。

        因为Viewport3D是Sprite的子类,所以它自身是可以响应鼠标事件(MouseEvent)的。如果我们对其进行侦听,当我们把鼠标移动到一块平面上的时候,就会发现如下的事件触发顺序:

  1. MouseEvent.ROLL_OVER
  2. InteractiveScene3DEvent.OBJECT_OVER
  3. MouseEvent.ROLL_OUT
  4. InteractiveScene3DEvent.OBJECT_OUT

      所以如果在 MouseEvent.ROLL_OVER 时重新注册 Event.ENTER_FRAME 侦听,那么 InteractiveScene3DEvent.OBJECT_OVER 事件就又会回来了。

     最后还有一点发现要和大家分享:动态改变StageQuality的值的时候,会重新触发一次 ROLL_OUT 和 ROLL_OVER 事件,不知道是不是以前就是这样了,要稍微留意一下。

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值