松散八叉树原理及其应用

Download Report

Transcript 松散八叉树原理及其应用

松散八叉树原理及其应用
需要明白的概念
1. 场景管理
 2. 视锥体裁剪
 3. 八叉树

场景管理

顾名思义,在游戏的实现方法中,我们往往需要一个统一的,高效的
方法来管理场景中的所有物体。让我们有限的CPU和显卡资源方便的
进行最重要的工作。同时,好的场景管理方法对我们游戏的上层逻辑
实现也会带来很大的方便。

从数据结构上理解,游戏中的场景管理器就是一个存放众多游戏单位
的容器。一般的,它需要提供如下功能:

1. 在场景中创建和放置活动物体、灯光以及摄像机,并维护他们在场
景管理数据结构中的变换。

2. 对场景查询的支持。比如,我们需要场景管理可以高效的回答下面
这个问题:在世界的某个空间中,都包含了哪些物体。或者是说,我
们像世界空间中首先一条射线,需要快速的回答出这条射线和哪些场
景物体相交了。

3. 方便的把物体放入场景,同时,也可以方便的把物体从场景中摘除。

4. PVS, BSP, PCZ…还有我们今天的主角,八叉树
视锥体裁剪

视锥体其实就是游戏中虚拟的摄像机可以看到的场景空间的图形化的
表示。我们可以想像,在这个图形外面的物体是不会出现在我们渲染
的画面中的,渲染它们等于浪费。所以我们需要抛弃它们不进行渲染。
更高级的视锥体裁剪会把一部分在视锥体内,一部分在视锥体外的物
体分解,而只渲染在视锥体内部的部分。
八叉树

八叉树是一种每一个节点都有八个孩子节点的树。它一般用于递归地
把一个三维空间分成八个等分。

八叉树的表示
class Octree : public NodeAlloc
{
…
Vector3 mHalfSize;
Octree * mChildren[ 2 ][ 2 ][ 2 ];
…
}
上面是对一个八叉树的一个节点的定义,很简单,是一个三维向量表
示这个节点有多大就行了。同时,每一个节点也保存着它的三个孩子
节点的指针。
递归的用八叉树划分空间
利用八叉树进行场景管理

简单的说,我们把场景中所有物体估算出一
个合适的包围盒(AABBox), 然后把它扔到
最合适的八叉树节点中.(大于它的包围盒的最
小节点)。当要进行视锥体裁剪时,我们首先
检测视锥体和哪些八叉树节点相交了,然后
我们只渲染相交节点中的游戏场景物体。
出现了问题?
物体横跨节点怎么组织?
 物体如果在我们划分的中心部分怎么办?

松散的八叉树



何为松散?
简单的说,它是一种技巧。我们的使八叉树的所有节点想互之间重叠
在一起而使之变得“松散”。假定在经典的八叉树的一个节点大小为N *
N * N, 那么对应的松散八叉树中,该节点的大小将可能为2N * 2N *
2N, 我们可以想像得到,这个节点是会和它的兄弟节点重合在一起的。
它同样的是一个八叉的树形结构。只是和前面介绍的经典八叉树结构
比较起来,它显得更为松散。
(为了便于说明,下面的介绍图片我将用平面的四叉树逻辑表示,它
们解决问题的道理和方法都是一样的。)

1. 经典的八叉树

+---+---+

|

+---+---+

|

+---+---+

2. 松散的八叉树

*********

* +---+ *

* |

* +---+ *

|
|
|
|
|*
*********
解决我们提出的问题

在松散八叉树中,我们同样需要先选择合适大小的八叉树节点并把该
游戏物体放入节点中。但此时,物体的大小和位置将作为我们选择树
的层级的依据,而物体的位置将作为我们选择该层级中物体放入哪个
结果的依据。(在经典八叉树中,此时,我们需要同时考虑物体的大
小和位置。)当我们选择好合适的层级后(该层级有八个儿子节点),
你只需要基于物体的位置,以对应的经典八叉树节点为依据,来选择
将该物体放入哪个松散八叉树节点即可。

前面我们提到过,我们寻找节点的目的是想找一个包围该物体的最小
的节点。因为在松散八叉树中节点与节点之间相互重叠,所以只要该
物体的大小小于该层松散八叉树节点的大小,那么它肯定会完全属于
一个松散八叉树节点的。

所以说,不会出现在经典八叉树节点中会出现的物体会跨界的情况。

不会出现经典的八叉树中会出现的很小的物体也需要放到很大的节点
之中的情况。
缺点

它的缺点也是来源于它的松散,由于节
点与节点之间是相互重叠在一起,相对
于经典八叉树来说,在做视锥体裁剪时,
程序逻辑可能需要检查更多的节点。
实现参考
1. Ogre OctreeSceneManager
 2. Generator Rex DS
