进行3D游戏的渲染,特别是比较大的场景,例如现在很多游戏中的无缝链接地图,需要我们对空间进行拣选。剔除不必要渲染的部分,减少GPU的压力。

根据PCS方法,我们可以将一个视锥判断的结果分为三类:完全可见,完全不可见,部分可见。其中,前两者我们都需要渲染,剔除最后一种,不渲染它。

常见的拣选方法有BSP二叉树,四叉树,八叉树锥形遮挡法,层次结构拣选法,优先层投影法,深度投影遮挡拣选,直接离散遮挡等办法,在其中又可进行扩展投影做预处理,虚拟遮挡物,点采样等手段。

我们可以理解,以前使用的视锥剔除,就是将场景进行分割为一个个场景节点,当我们的摄象机可见锥体与之重合时,视之为可见,则进一步将其分割判断,而不可见部分,则直接剔除。

此时,我们从几何学上可以将方法提出分为三种

1:直接将视锥投影为一个三角形,再与地图节点进行判断是否相交,这样是矩形与三角形的交互判断,运算量比较低,但不精确。

2:将视锥近似的棱锥体与空间节点半平面进行求交运算,当棱锥和半平面各点的点积具有同样符号时,我们认为视锥各顶点位于平面同侧,两者不相交。这种算法消耗时间较长,但可以相对精确计算出剔除节点。

3:这是个很有意思的办法,判断过物体碰撞的朋友应该知道,两个球体判断相对位置比其他任何形状体都方便,它就是将视锥和空间节点都做出一个最小外界球,判断这两个球是否相交,这样算法速度上有极大优势,很易判断,但缺乏精度比较严重。

上面三种算发都各有优势,一定程度上拣选了相对比较多的不可见三角形,但因为精确度不足,容易造成拣选不完全或者可见区被拣选掉的糟糕情况,而实际上渲染一个节点的时间要远远长于进行精确拣选的时间,因此我们,需要寻找更高效的一种拣选方法,在更高的精确度要求之下,兼顾一定的速度。


  • 首先,我们将远视锥平面进行缩小,将视锥变换为一个长方体的剪裁视锥。这样,我们可获得一个视程未变的长方体,进行初步的判断,判断完毕后,我们再对远平面进行恢复工作,进行第二次判断修正。 之后,我们将整个平面单位化,我们就可以很方面的测绘出地形节点到平面之间的距离,因为所有平面是面向视锥的,当节点到远剪裁视锥面的距离大于0时,则他在平面前方,反之后方,等于0时节点在远视锥面上,我们也设置为可见。将位于后方的部分可以拣选掉。

  • 接下来我们可以对可见的地形节点中的模型进行拣选,这里的判断很简单,设置包围体,让其与视锥六个面进行判断。设置包围体时,FK强烈推荐大家使用DX9.0中的BoundingMesh,它不仅速度上优于BoundingBox,Sphere,而精确度也高于前两者。原因是,BoundingMesh不是我们使用几何方法计算产生的,而是在构造Mesh时,D3D已经通过实点扩张构造好的。

  • 另外,为了加快拣选速度,希望大家不要在屏幕大小的主缓冲区进行拣选,可以设置一个小些的缓冲,如320X240这样的区域进行粗略的拣选工作,会加快一定的速度。