游戏开发论坛

 找回密码
 立即注册
搜索
查看: 6116|回复: 5

pvs算法 

[复制链接]

33

主题

118

帖子

173

积分

注册会员

Rank: 2

积分
173
发表于 2005-5-5 18:29:00 | 显示全部楼层 |阅读模式
终于将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上因此需要进行两次。

15

主题

248

帖子

248

积分

中级会员

Rank: 3Rank: 3

积分
248
发表于 2005-5-5 21:36:00 | 显示全部楼层

Re:pvs算法 

哈!不错不错,收下了,多谢多谢!!

13

主题

145

帖子

149

积分

注册会员

Rank: 2

积分
149
发表于 2005-5-8 13:20:00 | 显示全部楼层

Re:pvs算法 

呵呵,能不能详细的介绍一下怎么根据AB生成Frustum?没看明白.

18

主题

112

帖子

112

积分

注册会员

Rank: 2

积分
112
发表于 2005-5-8 17:19:00 | 显示全部楼层

Re:pvs算法 

dream,
    你好,如何能联系上你呢?
    我的MSN是:szlongman@hotmail.com

szwaiwai

33

主题

118

帖子

173

积分

注册会员

Rank: 2

积分
173
 楼主| 发表于 2005-5-10 17:34:00 | 显示全部楼层

Re:pvs算法 

hello,chenA,那段话确实不太容易理解,简单解释一下,如果portal A和B都是一个四边形的话,frustum的四个面是这样组成的,A的左边和B的右边构成一个plane,A的右边和B的左边构成一个plane,上下方向也是,这样就形成一个frustum。但是当portal由多个顶点构成时,组成frustum的面也不会只有四个,这样形成的会是一个多面的frustum。

18

主题

579

帖子

583

积分

高级会员

Rank: 4

积分
583
发表于 2005-5-11 07:04:00 | 显示全部楼层

Re:pvs算法 

好东西,顶
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-20 05:55

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表