转自:http://www.xuebuyuan.com/1482609.html

一.世界地图

将整个世界切分成多个Tile,每个Tile大小相同,用二维坐标形式索引起来,如图:

中心点(0,0)位置的Tile为世界地图的中心点,例如坐标可以定位为(0,0,0),由于Tile大小相等,世界坐标与Tile就可以进行转换,可以根据玩家所在的坐标快速的定位Tile。例如,当tile长度为12000时,玩家坐标为(13000,13000) 那么可以知道玩家在索引为(1,1)的Tile上。

二.Tile实现

从顶点组织和材质两个主要方面做说明

顶点组织

Tile可以设置用多少个顶点来表达真实世界的多大单位,如用513*513个顶点来渲染出游戏世界的12000*12000面积的地表。

由于要支持LOD,既根据相机到地表的距离,提交渲染的三角形要相应的减少。我们采用顶点数目不变,通过提交不同的索引来达到减少三角形的目的。

现在的问题是,如果规划这些索引来满足这个需求。用四叉树进行分割是比较好的方式。

由于是基于Ogre实现,就可以把顶点交由Rendable对象管理,这样材质的处理和到相机的距离判断都很方便。四叉树从根节点开始每一个节点都是一个Readable对象。树的根结点用最粗糙的索引,越向下越精细。这样当玩家站在这个大Tile上时,通过相机去查看有哪些节点可以被玩家看到,然后再根据距离和节点的高度(delta值)计算lod来决定是当前节点被渲染还是它的子节点应该被渲染。被渲染的节点被加入到渲染队列,渲染时回调Rendable对象的getRenderOption函数来要求提供顶点和索引,这时节点可以在这里提供自己的索引和顶点。

注意顶点的组织有一些特殊。以下以2049*2049个顶点来表示一块Tile为例做说明

LOD 0: 2049 vertices, 32 x 65 vertex tiles (tree depth 5)vdata 0-15 [129x16]

LOD 1: 1025 vertices, 32 x 33 vertex tiles (tree depth 5)vdata 0-15 [129x16]

LOD 2: 513 vertices, 16 x 33 vertex tiles (tree depth 4)vdata 0-15 [129x16]

LOD 3: 257 vertices, 8 x 33 vertex tiles (tree depth 3)vdata 16-17 [129x2]

LOD 4: 129 vertices, 4 x 33 vertex tiles (tree depth 2)vdata 16-17 [129x2]

LOD 5: 65 vertices, 2 x 33 vertex tiles (tree depth 1)vdata 16-17 [129x2]

LOD 6: 33 vertices, 1 x 33 vertex tiles (tree depth 0) vdata 18 [33]

LOD 0 为最清晰的级别定点数最多,根结点(tree depth 0)为做粗糙的级别,顶点数最少

树的级别还有LOD的计算公式见Terrain::determineLodLevels()函数。

LOD0 行的信息表明这个LOD级别有2049*2049个顶点,节点数有32*32个,每个节点有65*65个顶点。

LOD1行的信息表明这个LOD级别是与LOD0位于同一个树深度上,只不过是以不同的索引来确定顶点数

LOD2行的信息表明这个LOD级别位于深度为4的树节点上,节点数为16*16,每个节点的顶点数为33*33

以上3个LOD级别可以共用一套顶点,位于深度为4的树节点上,每个节点上顶点数为129*129

LOD3行的信息表明这个LOD级别位于深度为3的树节点上,节点数为8*8,每个节点上的顶点数为33*33

LOD4行的信息表明这个LOD级别位于深度为2的树节点上,节点数为4*4,每个节点上的顶点数为33*33

LOD5行的信息表明这个LOD级别位于深度为1的树节点上,节点数为2*2,每个节点上的顶点数为33*33

以上三个LOD级别共用一套顶点,挂在树的深度为1的节点上

LOD6行的信息表明这个LOD级别位于树的根结点上,节点数为1,节点上顶点数为33*33

解读一下以上绿色部分让人疑惑的内容

l 为什么出现的各种数据都是2N+1?

很简单,因为整个地表都是根据四叉树分割的规则的格子,例如5*5个顶点才可以表示4*4个格子

l 为什么实际节点块的大小是129?

因为索引数据是用的16位整数,最大寻址能到129*129,下一个257*257超出了范围

l 为什么叶子节点有2个LOD级别?

计算公式(Math::Log2(mMaxBatchSize- 1.0f) -Math::Log2(mMinBatchSize
- 1.0f) + 1.0f); 上例中的最大批次为65,最小批次为33。所以计算出叶子节点上的lod级别为2,最大级别65是最精细的lod,33是次级,这样做是为了配合地表高度(delta)和相机距离来计算出更多样的lod层级。

l 怎么知道哪些LOD层级/树深度可以共用一套顶点?

顶点块都是129*129的,如上例所示16*16那一深度的129*129个顶点可够它自己和下一个深度的32*32的节点使用。2*2那一个树深度的129*129个顶点可供4*4和8*8的节点使用。具体的计算公式见Terrain::distributeVertexData()

l 为什么总的顶点数要多于2049*2049?

2049^2 = 4198401 vertices

最后使用的顶点数:(16 * 129)^2 + (2 * 129)^2 + 33^2 = 4327749 vertices

因为不是简单的平面切分顶点,而是用四叉树做分割,根据总的顶点数和最大批次最小批次等参数来决定数的深度以及顶点如何共用,所以要有2049只是作为一个基数来参考,最后用的129*129的块数才决定最终的顶点数。

具体的计算方法见Terrain::distributeVertexData()

http://blog.csdn.net/xuantao/article/details/7304073

http://blog.csdn.net/pizi0475/article/details/6321094

http://blog.csdn.net/swq0553/article/details/5888954

[Ogre][地形]OgreTerrain的实现原理分析的更多相关文章

  1. [Ogre][地形]OgreTerrain分析以及使用

    Ogre 1.7.2中的地形教程 ○读者可以对照着Ogre1.7.2中的terrain.h源码进行阅读加深理解,蓝色部分均为源码 ○去除了一些具体场景比如添加mesh,设置setAmbientLigh ...

  2. Handler系列之原理分析

    上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...

  3. Java NIO使用及原理分析(1-4)(转)

    转载的原文章也找不到!从以下博客中找到http://blog.csdn.net/wuxianglong/article/details/6604817 转载自:李会军•宁静致远 最近由于工作关系要做一 ...

  4. 原子类java.util.concurrent.atomic.*原理分析

    原子类java.util.concurrent.atomic.*原理分析 在并发编程下,原子操作类的应用可以说是无处不在的.为解决线程安全的读写提供了很大的便利. 原子类保证原子的两个关键的点就是:可 ...

  5. Android中Input型输入设备驱动原理分析(一)

    转自:http://blog.csdn.net/eilianlau/article/details/6969361 话说Android中Event输入设备驱动原理分析还不如说Linux输入子系统呢,反 ...

  6. 转载:AbstractQueuedSynchronizer的介绍和原理分析

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  7. Camel运行原理分析

    Camel运行原理分析 以一个简单的例子说明一下camel的运行原理,例子本身很简单,目的就是将一个目录下的文件搬运到另一个文件夹,处理器只是将文件(限于文本文件)的内容打印到控制台,首先代码如下: ...

  8. NOR Flash擦写和原理分析

    NOR Flash擦写和原理分析 1. NOR FLASH 的简单介绍 NOR FLASH 是很常见的一种存储芯片,数据掉电不会丢失.NOR FLASH支持Execute On Chip,即程序可以直 ...

  9. 使用AsyncTask异步更新UI界面及原理分析

    概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的内部实现是一个线程池,所有提交的异步任务都会在这个线程池中的工作线 ...

随机推荐

  1. spring4 文件下载功能

    需要准备的工具和框架 Spring 4.2.0.RELEASE Bootstrap v3.3.2 Maven 3 JDK 1.7 Tomcat 8.0.21 Eclipse JUNO Service ...

  2. linux bash history

    vim /etc/profile export HISTSIZE=10000 export HISTTIMEFORMAT="`whoami` : %F %T : " export ...

  3. Java基础之写文件——缓冲区中的多条记录(PrimesToFile3)

    控制台程序,上一条博文(PrimesToFile2)每次将一个素数写入到文件中,所以效率不是很高.最好是使用更大的缓冲区并加载多个素数. 本例重复使用三个不同的视图缓冲区加载字节缓冲区并尽可能加入更多 ...

  4. Building a RESTful Web Service Using Spring Boot In Eclipse

    一.构建restful web service 创建Maven的java web工程,maven的pom文件加入依赖包 创建包hello Greeting.java package hello; pu ...

  5. leetcode23 多个拍好序的链表进行归并排序 (java版本)

    题目: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexit ...

  6. qsort函数用法

    qsort函数用法   qsort 功 能: 使用快速排序例程进行排序 用 法: void qsort(void *base, int nelem, int width, int (*fcmp)(co ...

  7. WebService的简单应用

    具体看项目源文件:包含: ip地址查询, QQ在线状态查询,和自定义的MD5 破解和加密(呵呵有形无势...) http://pan.baidu.com/s/1bn09WQj SOAP 1.1 The ...

  8. Nopi .net下面的Excel第三方dll

    相关参考资料:1.npoi官网:http://npoi.codeplex.com/2.用NPOI操作EXCEL--插入图片:  http://www.cnblogs.com/atao/archive/ ...

  9. Android -- FragmentTabHost实现微信底部切换

    1,在商城类的项目中我们开始一个项目的时候经常出现这样的需求,如下图所示: 下面使用户可以切换的模块,上面是对应的模块的详细内容,实现这个效果有很多方式,可以使用radiobutton+fragmen ...

  10. Logic Bist Arch

    一般现在多用的都是offline BIST的架构,可以分为4大类: 1)those assume no special structure to the circuit under test; 2)t ...