二叉空间分割

释义

  BSP(二叉空间分割Binary Space Partitioning)树是另一种类型的空间分割技术,其已经在游戏工业上应用了许多年(Doom是第一个使用BSP树的商业游戏)。

应用范围

  尽管在今天BSP树已经没像过去那么受欢迎了,但现在仍在广泛地采用这项技术。当你看一下BSP在碰撞检测方面那极度干净漂亮和高速的效率,立刻能让你眼前一亮。不但BSP树在多边形剪切方面表现出色,而且还能让我们有效地自由运用world-object式的碰撞检测。BSP树的遍历是使用BSP的一个基本技术。碰撞检测本质上减少了树的遍历或搜索。这种方法很有用因为它能在早期排除大量的多边形,所以在最后我们仅仅是对少数面进行碰撞检测。

使用原理

  正如我前面所说的,用找出两个物体间的分隔面的方法适合于判断两个物体是否相交。如果分隔面存在,就没有发生碰撞。因此我们递归地遍历world树并判断分割面是否和包围球或包围盒相交。我们还可以通过检测每一个物体的多边形来提高精确度。进行这种检测最简单的一个方法是测试看看物体的所有部分是否都在分割面的一侧。这种运算真的很简单,我们用 迪卡尔 平面等式 ax + by + cz + d = 0 去判断点位于平面的哪一侧。如果满足等式,点在平面上;如果ax + by + cz + d > 0那么点在平面的正面;如果ax + by + cz + d < 0点在平面的背面。
  在碰撞没发生的时候有一个重要的事情需要注意,就是一个物体(或它的包围盒)必须在分割面的正面或背面。如果在平面的正面和背面都有顶点,说明物体与这个平面相交了。
  不幸的是,我们还没有一个很好的方法检测在一个时间间隔内的碰撞。然而,我已经看到有另外的 数据结构 像BSP树一样开始广泛使用了。

BSP文件格式

  是QUAKE 2用于存储地图的一种 文件格式 ,说得具体点,就是用于渲染Q2世界的。尽管有其他的信息包含在BSP文件中,用于其他游戏部分(如敌人AI,等等),在这篇文章中,我不将讨论他们。如果你有这方面的知识,请告诉我,我的E-MAIL在下面。在这篇文章中难免有错误之处,请告诉我。
  为了更清楚的描述BSP文件格式,在这篇文章中将试图对Q2渲染引擎进行技术方面的描述。现在让我们假想这个渲染器使用的是基本的3D图形技术,包含BSP树结构。
  我们在这篇文章中描述的是Q2的BSP文件格式,这个文件格式由Kingpin使用(他建立了Q2引擎)。对于Q1和Q3的文件格式,虽然他们很相同,但还是有点不兼容。不管怎样,BSP的文件结构和技术不是很难,这篇文章将对于那些对这些格式赶兴趣的人。"



原文地址


Binary Space Partioning Tree英文簡稱為BSP Tree,二元空間分割樹,簡稱為二叉樹。它於1969年被Schumacker在文章《Study for Applying Computer-Generated Images to Visual Simulation》首次提出,並被ID公司第一次使用到FPS遊戲Doom中,Doom的推出獲得了空前的成功,不僅奠定了ID公司在FPS遊戲開發的宗師地位,也使BSP技術成為室內渲染的工業標準,從BSP產生到現在已經有30多年了,其間雖然產生了大量的室內渲染的算法,但卻無人能撼動它的地位,對於以摩爾定律發展的計算機業來說這不能不是一個奇蹟。

※為什麼使用BSP Tree

一個BSP Trees如同它的名字一樣是一個層次樹的結構,這個樹的葉節點保存了分割室內空間所得到的圖元集合。現在隨著硬體加速Z緩衝的出現,我們只需要用很小的代價就可以對空間中的圖元進行排序,但是在90年代初由於硬體的限制,使用BSP的主要原因是因為它可以對空間中的圖元進行排序來保證渲染圖元的順序是按照由後至前進行的,換句話說,Z值最小的物體總是最後被渲染。當然還有其他的算法可以完成這個功能,例如著名的畫家演算法,但是它與BSP比較起來速度太慢了,這是因為BSP通常對圖元排序是預先計算好的而不是在運行時進行計算。從某種意義上說BSP技術實際上是畫家算法的擴展,正如同BSP技術的原始設計一樣,畫家演算法也是使用由後至前的順序對場景中的物體進行渲染。

產生BSP tree的步驟:

Step 1: Make a list of all the walls.
Step 2: Choose one of the walls, “the splitter wall" to split up the space into two parts, P1 and P2.
Step 3: Put all of the walls that are completely in front of the splitter wall into one list, called “front".
Step 4: Put all of the walls that are completely in back of the splitter wall into another list called “back".
Step 5: If the splitter wall intersects any of the walls, split that wall into two parts, putting the part of the wall in front of the splitter wall into the front list and the other part in the back list.
Note: for simplification, this algorithm doesn’t address walls that lie on the same line as the splitter wall.
Step 6: The splitter wall is placed in the bsp tree. The first wall simply becomes the root of the tree. Thereafter, the wall is placed in the bsp tree to the right of its parent wall if in the scene the wall is in front of the parent wall. The wall is placed in the bsp tree to the left of the parent wall if in the scene the wall is in back of the parent wall.
Step 7: Recursively split up the P1 space until you are left with one line segment only. Then recursively split up the P2 space until there is only one line segment remaining.

最後的繪出的場景。

俯視場景,分別標出牆的號碼。

第一次選擇C牆(從A-H任意選),F牆被分割為F1和F2牆。在C牆前面的有F1、G、H牆,而在後面的有A、B、D、E、F2牆。

第二次選擇G牆(從1、G、H牆任意選)。在G牆前面的有F1牆,而在後面有H牆。

依上述類推,右子樹為前方,左子樹為後方,最後產生的BSP樹。BSP樹並不唯一,因為每次牆都可以任選。


Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐