PagedGeometry编程讲解(二)

出处 http://hi.baidu.com/jxw167/blog/item/4687b109e228ac9c0a7b82a5.html

 

通过第一节的讲解,一旦你掌握了怎样建立PagedGeometry,增加树到你的世界是同TreeLoader3D::addTree()这样容易的。本节在你已经知道的基础上进行了扩展,并且解释了用最快的方式增加树和草丛的到你的场景中。

 

(一)层次细节

    如果你想增加树木,草丛,岩石,任何你喜欢的任何东西利用在第一节讲的PagedGeometry可以加到场景里面。但是在某种程度上你可能即使你使用PagedGeometry的batching和impostoring的优化,这个帧率可能没有同你喜欢的一样高。

    草丛,岩石,和地面的细节和在一定距离的树木是一样重要的。如果你减少了可视范围的“ground clutter”,你讲得到一个相对不错的可视质量。举例说明,如果你的树木是达到半里的范围是可见的,你的草丛,岩石可能仅需要被渲染到一或二百米的尺寸。用这种方式,你可能得到一个高层次的细节在你的场景里面并且没有浪费太多的时间渲染在远处的物体。

 

(二)多重可视范围(Multiple View Ranges)

    在这里,你可能思考你将怎么对于不同类型的实体安排多重可视范围,幸运的是,有一个很容易的方式处理这个:创建PagedGeometry的实例---一个是建立你想渲染的树,另一个是建立你想渲染的草丛。

   这是树木建立的代码:

        PagedGeometry* trees=new PagedGeometry(camera,50);

        trees->addDetailLeveL<BatchPage>(150,30);

        trees->addDetailLeveL<ImpostorPage>(400,50);

这些代码同上一节讲的教程一基本很相似,做了一些变化:相机和页尺寸数据是指定在构造器中,而不是通过函数设定。而且,trees->setInfinite()被移除从默认的无限模式移除。

   正如你看到的,代码的建立是分成150单元和Impostors达到400单元。以上这个对于树木的建立工作的很好,草丛不需要渲染的这么远。因此另一个PagedGeometry对象将被单独的创建渲染,草丛的渲染:

       PagedGeometry* bushes= new PagedGemetry(camera,40);

       bushes->addDetailLevel<BatchPage>(80,20);

       bushes->addDetailLevel<ImpostorPage>(160,40);

注意:由于这新的PagedGeometry对象(“草丛”)是独立于树木的,你可能完全建立不同的LODs如果你喜欢的。在这种情况下,BatchPage和ImpostorPage是仍然被用的,但是这个范围 是你用到树木的一半时被改变。

   现在,应该是安排PageLoader‘s到PagedGeometry对象的时候了。显然,每一个PagedGeometry对象仍然需要它自己的PageLoader对象,因此你能增加树木和草丛:

       TreeLoader3D *treeLoader = new TreeLoader3D(trees, TBounds(0, 0, 1500, 1500));
       trees->setPageLoader(treeLoader);
       TreeLoader3D *bushLoader = new TreeLoader3D(bushes, TBounds(0, 0, 1500, 1500));
       bushes->setPageLoader(bushLoader);

 

 

 

(三)增加树木和草丛

在这里你可以增加所有的树木到treeLoader,所有的草丛到bushLoader,并且你的场景应该准备运行了。下面的代码是随意的放置树木和草丛,但是当然是对于示范的目的:

     Entity *myTree = sceneMgr->createEntity("MyTree", "tree.mesh");

     Entity *myBush = sceneMgr->createEntity("MyBush", "bush.mesh");
     //Add trees
    float x = 0, y = 0, z = 0, yaw, scale;
    for (int i = 0; i < 10000; i++){
       yaw = Math::RangeRandom(0, 360);
       if (Math::RangeRandom(0, 1) <= 0.8f){
          //Clump trees together occasionally
          x += Math::RangeRandom(-10.0f, 10.0f);
          z += Math::RangeRandom(-10.0f, 10.0f);
         if (x < 0) x = 0; else if (x > 1500) x = 1500;
         if (z < 0) z = 0; else if (z > 1500) z = 1500;
        } else {
              x = Math::RangeRandom(0, 1500);
               z = Math::RangeRandom(0, 1500);
        }

 

       y = getTerrainHeight(x, z);
       scale = Math::RangeRandom(0.9f, 1.1f);
       treeLoader->addTree(myTree, Vector3(x, y, z), Degree(yaw), scale);
}

    //Add bushes

float x = 0, y = 0, z = 0, yaw, scale;
for (int i = 0; i < 20000; i++){
yaw = Math::RangeRandom(0, 360);
if (Math::RangeRandom(0, 1) <= 0.3f){
//Clump bushes together occasionally
x += Math::RangeRandom(-10.0f, 10.0f);
z += Math::RangeRandom(-10.0f, 10.0f);
if (x < 0) x = 0; else if (x > 1500) x = 1500;
if (z < 0) z = 0; else if (z > 1500) z = 1500;
} else {
x = Math::RangeRandom(0, 1500);
z = Math::RangeRandom(0, 1500);
}

y = getTerrainHeight(x, z);
scale = Math::RangeRandom(0.9f, 1.1f);
bushLoader->addTree(myBush, Vector3(x, y, z), Degree(yaw), scale);
}

(四)更新PagedGeometry

完成时,记住返回trees->update()和bushes->update()每一帧:

{
trees->update();
bushes->update();
}

(五)优化

现在你应该使你的树木和草丛在一个相对优化的进行了渲染。它通常有助于帮助你围绕页的尺寸和Batching/impostoring的可视范围。尽力找到一个适当的值从而不降低渲染质量。

在屏幕上比较大尺寸渲染比较有效,而且可以是比较多的可视范围外的实体被渲染。依靠着树木和草丛的可视范围,减少或者增加页的尺寸可以得到比较好的效果。

通常,你应该调整batching范围尽可能同没有做impostors一样低。然而,过分低的batching可能实际上运行的很慢,由于当impostors靠近摄像机附近渲染可能比较多的需要重画。

一旦你有可优化的FPS,试着围绕你的游戏移动摄像机。如果高速移动摄像机导致帧率的震动,那么你的页的尺寸可能太大。在这种情况下,减少页的尺寸直到震动不在是一个问题。它可能也有助于设置边界模式(PagedGeometry::setBounds()).

(六)TreeLoader2D

在上面的代码你可能注意到放置树木和草丛的代码GetTerrainHeight()被称为在任意的x/z坐标获得的高度值。显然,这个高度需要将用这种方式计算防止把树加到地的下面。

如果所有你的树用“Y=getTerrainHeight(X,Z)”计算这个高度,你就能节省大量的内存用于转换。TreeLoader3D只是接收X和Z坐标,并且用于计算Y值利用你提供的函数。举例说明:

TreeLoader2D *treeLoader = new TreeLoader2D(trees, TBounds(0, 0, 1500, 1500));
trees->setPageLoader(treeLoader);
treeLoader->setHeightFunction(&getTerrainHeight);
treeLoader->addTree(myEntity, Vector2(x, z), yaw, scale);

TreeLoader2D与TreeLoader3D基本上是相同的,除了setHeightFunction()函数用于提供TreeLoader2D来计算每棵树的Y坐标,addTree()接收一个二维的向量代替三维向量坐标。

结论:

增加树木,草丛,岩石和许多其他细节到你的游戏里面是很容易的,但是要取得好的帧率需要费一点时间调整,幸运的是,PagedGeometry对于配置LODs和可视范围在几乎任何方式变得容易了,可以渲染茂密的森林,稠密的草丛

可以在Trees and Bushes项目里面。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值