eXtreme3D

导航

BSP技术详解(补充)--pvs算法

终于将HL2的vbsp,vvis看完了,随便也翻了翻q3map代码,发现两者的代码太相似了,可以看出在BSP分割,portal的查找方面在Q2中都应该已经定型了,因此两者使用的算法都是一样的。下面我主要谈一下计算pvs的算法,因为在我翻译的那篇文章《bsp技术详解》中计算pvs是通过在每个portal上确定一些采样点然后进行ray cast来计算pvs的,这种方法的速度没有保证,而且处理起来也非常麻烦。而ID通过对每一个portal的polygen进行clip的方法来获取pvs,确实速度上要比上一个方法好上
很多。下面我来对算法进行详细的介绍,如果你对bsp不是很熟的话需要明确一下几个概念,一个是cluster,对于室内场景来说它完全是由cluster组成的,简单的你可以将它认为是场景中的一个房间,另一个是portal,场景中的cluster是由portal连接为一个整体,你可以把它看作是房间的门或窗户。在进行pvs计算的时候已经将整个场景划分为bsp tree,查找完portal并将cluster和leaf node连接起来了。

 

1、首先对所有的portal先进行一下预处理,让一个portal只和一个cluster发生联系,这样作的目的是为了获得一个单向的portal,也就是说portal只在一边可见,这样做是为了方便进行处理。我们知道一个portal通常连接了两个cluster,一般情况下使用的是portal所在plane正面的portal,但为了达到上述目的,我们需要将portal分为正反两个,由于在bsp中每一个plane都保存正反两个,因此位于反面的portal只需要对ploygen颠倒一下
顶点顺序即可。这里规定一个portal只和位于其plane的法线方向上的luster发生联系,预处理后保存的portal数量是原来的2倍。

2、接着我们需要对portal进行一下分类处理。通过简单的常识我们知道,由于现在每一个portal都是单向可见,因此只有位于portal可见方向(称为front方向)的portal才可能是可见的,我们需要对每一个portal都获得一个front portal列表并保存起来。

3、下面我们需要进一步的对每一个portal的front portal列表中不可见的portal进行剔除。我们知道场景完全是由一个个portal连接起来的cluste组成的,对于一个portal来说位于同一个cluster的portal一定可见,而其他portal要想可见最基本的要求是它可以通过其他portal连接到这个cluster上,因此通过portal的连接关系我们可以从front portal列表中剔除那些和当前portal没有连接关系的portal,并保存到floodportal列表中。

4、好了经过上面的处理我们已经剔除了大部分不可见的portal,可见的portal一定包含在flood portal列表中,因此需要使用更精确的方法进行检查。为了方便描述,我假定当前计算pvs的portal为A,任选和A所在的cluster ca相连的一个portal称为B,注意B一定是可见,因此B所在的cluster cb一定可见,但是和cb相连的其它portal并不一定可见,为了检查是否可见,我们假定选取其中的一个portal称为C。好了现在的问题简化为已知A和B求C是否可见,算法如下:
在A上选取一条边和B上的一个顶点构成一个clip plane,为了保证这是一个合法的clip plane我们需要做一下检查,为了简单化我们首先需要保证clip plane的法线方向必须指向portal A的外部,也就是说A上所有的顶点都位于clip plane的背面。
其次我们要保证portal B上所有的顶点都位于clip plane的正面,这样做可以保证当你选择A上最左边的一条边时必须要和B上最右边的一个顶点构成clip plane,当你选择A上最右边的一条边时必须要和B上最左边的一个顶点构成clip plane,将所有的clip plane合并起来实际上就获得一个A到B的最大可见frustum,只有位于frustum内部的portal才是可见的。当建立起这个frustum后我们就可以使用它对C的polygen进行clip操作了,当C clip后如果没有polygen在frustum内部那么它是不可见的,否则portal C可见并将可见的polygen保存下来。当C可见后我们需要接着对和C相连的portal进行检查,方法还是一样不过上面的portal B变成了C而且必须要注意,建立frustum使用C的polygen应该是clip后的polygen数据。通过上面的方法对A的flood portal列表进行递归运算最终将获得一个真正的可见portal集合保存到vis portal列表中。还需要指出一点的是建立clip plane的过程实际上需要两次,第一次是从A到B,第二次是从B到A,这样做的原因是并不是所有的极值点都位于B上的,也可能位于A上因此需要进行两次。

Q:怎么根据AB生成Frustum?
A:如果portal A和B都是一个四边形的话,frustum的四个面是这样组成的,A的左边和B的右边构成一个plane,A的右边和B的左边构成一个plane,上下方向也是,这样就形成一个frustum。但是当portal由多个顶点构成时,组成frustum的面也不会只有四个,这样形成的会是一个多面的frustum。

posted on 2007-03-25 16:46  Dreams  阅读(3106)  评论(4编辑  收藏  举报