热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PagedGeometry编程讲解(二)

通过第一节的讲解,一旦你掌握了怎样建立PagedGeometry,增加树到你的世界是同TreeLoader3D::addTree()这样容易的。本节在你

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

(一)层次细节

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

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

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

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

   这是树木建立的代码:

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

trees->addDetailLeveL(150,30);

trees->addDetailLeveL(400,50);

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

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

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

bushes->addDetailLevel(80,20);

bushes->addDetailLevel(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 &#61; 0; i <10000; i&#43;&#43;){
yaw &#61; Math::RangeRandom(0, 360);
if (Math::RangeRandom(0, 1) <&#61; 0.8f){
//Clump trees together occasionally
x &#43;&#61; Math::RangeRandom(-10.0f, 10.0f);
z &#43;&#61; Math::RangeRandom(-10.0f, 10.0f);
if (x <0) x &#61; 0; else if (x > 1500) x &#61; 1500;
if (z <0) z &#61; 0; else if (z > 1500) z &#61; 1500;
} else {
x &#61; Math::RangeRandom(0, 1500);
z &#61; Math::RangeRandom(0, 1500);
}
y &#61; getTerrainHeight(x, z);
scale &#61; Math::RangeRandom(0.9f, 1.1f);
treeLoader->addTree(myTree, Vector3(x, y, z), Degree(yaw), scale);
}
//Add bushes
float x &#61; 0, y &#61; 0, z &#61; 0, yaw, scale;
for (int i &#61; 0; i <20000; i&#43;&#43;){
yaw &#61; Math::RangeRandom(0, 360);
if (Math::RangeRandom(0, 1) <&#61; 0.3f){
//Clump bushes together occasionally
x &#43;&#61; Math::RangeRandom(-10.0f, 10.0f);
z &#43;&#61; Math::RangeRandom(-10.0f, 10.0f);
if (x <0) x &#61; 0; else if (x > 1500) x &#61; 1500;
if (z <0) z &#61; 0; else if (z > 1500) z &#61; 1500;
} else {
x &#61; Math::RangeRandom(0, 1500);
z &#61; Math::RangeRandom(0, 1500);
}

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

&#xff08;四&#xff09;更新PagedGeometry

完成时&#xff0c;记住返回trees->update()和bushes->update()每一帧&#xff1a;

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

&#xff08;五&#xff09;优化

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

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

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

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

(六)TreeLoader2D

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

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

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

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

结论&#xff1a;

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

可以在Trees and Bushes项目里面。



推荐阅读
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • OpenMap教程4 – 图层概述
    本文介绍了OpenMap教程4中关于地图图层的内容,包括将ShapeLayer添加到MapBean中的方法,OpenMap支持的图层类型以及使用BufferedLayer创建图像的MapBean。此外,还介绍了Layer背景标志的作用和OMGraphicHandlerLayer的基础层类。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
author-avatar
陈柏佩66057
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有