用 ViewportLayerSortMode.ORIGIN_SORT给层排序
第二种算法是基于每个三D对象的原点进行的:当用默认的z-sorting(即:ViewportLayerSortMode.Z_SORT)排序无法满足精确的要求时。例如有一个模型,在某一面上有多个点(vertices),而在其他面上的点却很少。当按上述方法对它的深度(即距camera的距离)取平均值显然是不精确的 ,这将会导致失去平衡。为了解决这种情况,我们使用
ViewportLayerSortMode.ORIGIN_SORT 排序,它是按照3D对象的原点进行排序的。当一个层中包含很多3D对象时,他们的原点将会取平均值。
用ViewportLayerSortMode.INDEX_SORT给viewport 层(ViewportLayer)排序
这种算法是基于层的layerIndex属性来实现的。我们可以控制设定它:
var millLayer:ViewportLayer = viewport.getChildLayer(mill);
var floorLayer:ViewportLayer = viewport.getChildLayer(floor);
millLayer.layerIndex = 1;
floorLayer.layerIndex = 2;
viewport.containerSprite.sortMode = ViewportLayerSortMode.INDEX_SORT;
我们这样设置millLayer.layerIndex = 1; floorLayer.layerIndex = 2; ,将会导致scene里先创建millLayer(即离camera较远) 然后再创建floorLayer层(即离camera较近),由于floorLayer层较后创建,因而floorLayer层在的最上面。尽管这样做对floorLayer层意义不大,但是我们是借此来介绍怎样使用
layerIndex 属性 。
So far, we have seen some options to sort the viewport layers, but none resulted in correctly drawing the objects from all points of view in the demo application. An option for the floor is to make it one-sided, instead of double sided. This way, we will not draw the floor at all when we get beneath the floor surface. But for now, that's not what we want; we want to see the floor and mill correctly when the camera is above and below the surface. So, what if we were to use index sorting for the layers, and swap the layer index of the mill layer and floor layer once the camera is above or below the floor?
目前我们已经有了几种可供选择的方法来给viewport层(ViewportLayer)进行排序。但是这些方法在我们的demo(即演示例子)里的使用都不能达到正确的效果。一个可供选择的方法是将它设为只有一面可见 即:matrial.oneSide=true; 但是对于这个demo,这并不是我们想要的。
当cameral在floor的上表面和下表面时,我们需要正确(即符合实际)的观察floor和mill模型
如果我们用ViewportLayerSortMode.INDEX_SORT给层排序,当cameral在floor的上表面和者下表面之间进行变动时,使用layerIndex属性来交换viewport层(ViewportLayer)的深度
将会产生怎么的结果呢?
在 onRenderTick()方法里来设定这些属性
//注意:下面的代码是demo的代码的基础上进行的
//下面的代码是放在onRenderTick()里面的
if(camera.y<-410)
{
viewport.getChildLayer(mill).layerIndex = 1;
viewport.getChildLayer(floor).layerIndex = 2;
}
else
{
viewport.getChildLayer(mill).layerIndex = 2;
viewport.getChildLayer(floor).layerIndex = 1;
}
为了使layerIndex属性正常运行
我们还需要这样设置:
viewport.containerSprite.sortMode = ViewportLayerSortMode.INDEX_SORT;
这行代码放在modelLoaded()方法里
上述方法成功解决了demo里存在的问题但这个方法并不是在每个工程中都适用 。
Creating and sorting sublayers
不仅viewport支持viewport层(ViewportLayer),viewport 层他们自己也可以嵌套层(即层中再包含层),因而我们可以在同一个scene里使用多种排序方法。
下面我们按照图示写出相关代码:
//Create viewport layer 1 structure
var viewportLayer1:ViewportLayer = new ViewportLayer(viewport,null);
var viewportLayer1_1:ViewportLayer = new ViewportLayer(viewport, chair);
var viewportLayer1_2:ViewportLayer = new ViewportLayer(viewport, table);
viewportLayer1.addLayer(viewportLayer1_1);
viewportLayer1.addLayer(viewportLayer1_2);
viewportLayer1.sortMode = ViewportLayerSortMode.INDEX_SORT;
//Create a regular viewport layer 2
var viewportLayer2:ViewportLayer = new ViewportLayer(viewport,floor);
//Create viewport layer 3 structure
var viewportLayer3:ViewportLayer = new ViewportLayer(viewport,null);
var viewportLayer3_1:ViewportLayer = new ViewportLayer(viewport,wall);
var viewportLayer3_2:ViewportLayer = new ViewportLayer(viewport,door);
viewportLayer3.addLayer(viewportLayer3_1);
viewportLayer3.addLayer(viewportLayer3_2);
viewportLayer3.sortMode = ViewportLayerSortMode.ORIGIN_SORT;
//Add parent layers to the viewport
viewport.containerSprite.addLayer(viewportLayer1);
viewport.containerSprite.addLayer(viewportLayer2);
viewport.containerSprite.addLayer(viewportLayer3);
viewport.containerSprite.sortMode = ViewportLayerSortMode.Z_SORT;
从上面的代码中可以看出嵌套的层在处理深度排序时 和在viewport里一样 。
四叉树渲染引擎(Quadtree rendering)
四叉树渲染引擎(Quadtree rendering)可以代替我们现在默认使用的的BasicRenderEngine 引擎。我们对四叉树渲染引擎(Quadtree rendering)的算法不会深入讲解。 我们只需要知道它可以解决大部分的深度排序(Z-sorting)问题。但是四叉树渲染引擎(Quadtree rendering)非常耗CPU。尽管这样,由于它的使用非常简单,下面我们来使用它:
首先我们要新建一个工程,该工程是在ViewportLayersExample文档类(本章前面的模板,第一个代码)的基础上建立起来。
在该类的基础上,我们需要导入四叉树渲染引擎(Quadtree rendering)的包,
import org.papervision3d.render.QuadrantRenderEngine;
然后在init()方法里加上下面的代码:
renderer = new QuadrantRenderEngine();
上面的代码代替了我们默认的BasicRenderEngine引擎。BasicRenderEngine引擎是在我们继承BasicView类时自动创建的。
实例化QuadrantRenderEngine只需要一个参数 该参数指定你要选择哪种排序的方法。这些方法是QuadrantRenderEngine类的静态常量。
QuadrantRenderEngine.CORRECT_Z_FILTER: :为不交叉的平面进行正确的排序。
QuadrantRenderEngine.QUAD_SPLIT_FILTER: 为交叉的平面进行排序,引擎将会自动的分割交叉的平面,然后进行正确的排序。
QuadrantRenderEngine.ALL_FILTERS:这个是上面两种类型的组合。它是默认值(即不传参数时默认是它)
当我们测试代码,会发现出现的情况不令人满意。原因是我们用的模型是由少量的平面组成,这就限制了四叉树渲染引擎(Quadtree rendering)的正常发挥。
该问题得原因是因为每一个平面都被四叉树渲染引擎(Quadtree rendering)渲染了,但是并不是每个平面都需要用四叉树渲染引擎(Quadtree rendering)进行渲染,我们可以不让3D对象不被四叉树渲染引擎(Quadtree rendering)进行渲染,因而该3D对象将会被默认的BasicRenderEngine引擎进行渲染。 我们可以用设置3D对象的testQuad属性为false来实现。
我们例子的问题在于floor的深度排序问题。因而我们可以用四叉树渲染引擎(Quadtree rendering渲染floor对象,而对mill模型用默认的BasicRenderEngine引擎进行渲染。
mill.getChildByName("Blades",true).testQuad = false;
mill.getChildByName("Stand",true).testQuad = false;
mill.getChildByName("House",true).testQuad = false;
因为直接设置mill.testQuad = false;对子对对象不会产生任何影响.因而要像上述那样设置。
测试代码,排序问题解决。
Summary
Z-sorting is about sorting triangles and deciding in which order the triangles need to be drawn on the viewport. Drawing a render happens from furthest triangles to the closest triangles, based on their position in relation to the camera. This is known as the painter's algorithm.
There are several ways to affect the order in which objects are rendered.
We learned about viewport layers, which are similar to layers in Photoshop, for example. These layers can be ordered in three ways:
ViewportLayerSortMode.Z_SORT
ViewportLayerSortMode.ORIGIN_SORT
ViewportLayerSortMode.INDEX_SORT
The z-sorting issues we've seen with the mill and floor were solved by index sorting. Based on the position of the camera, we changed the layer index order. This is not the solution for all z-sorting problems. But for the example discussed in the chapter, it worked great.
Besides adding and sorting viewport layers as children of the viewport, we've also seen how we can nest viewport layers as children of other viewport layers. This way, you can even use several viewport sorting modes in one application.
At the end of the chapter, we had a look at quadtree rendering, which is an advanced algorithm that creates better renders in order to solve z-sorting issues. We learned how we can accomplish correct z-sorting for non-intersecting triangles using the QuadrantRenderEngine.CORRECT_Z_FILTER type. Sorting on intersecting triangles can be solved with QuadrantRenderEngine.QUAD_SPLIT_FILTER. Most of the time you also want to use the correct z-filter type together with the quad split filter. In those cases, you can set QuadrantRenderEngine.ALL_FILTERS.
As said earlier, beauty comes at a price. The price you pay is either a lower performance when using quadtree rendering, or more work and time on creative thinking when using viewport layers.
Adding objects to viewport layers can solve z-sorting problems. Another use of layers is when you want to apply effects. The next chapter will explain how you can add all kinds of effects to your scenes—from simple transparency, to glows, blurs, blend modes, and even fire.
上面Summary没有翻译,明天将会对整章的翻译的做一个整理,然后会整章的world文档或pdf格式的文档的下载地址贴出来 。
然后我会其他章节做个简单的陈述 。
其他翻译的结果可以在这个网址里找到:http://lushisang.com/?p=36