(原、整)BSP的江湖传说
@author:黑袍小道
查看随缘,当苦无妨,良人可归。
引言
为什么叫江湖传说,因为实现了第一人是卡马克,就这么简单。(不接受那啥)
Quake3:http://www.mralligator.com/q3/#Nodes
必备
点积和叉积
|
点积 |
向量乘法的一种形式,它的计算结果是一个标量值;由于这一原因,有时也将点积称为标量积(scalar product)。设u=(ux,uy,uz),v=(vx,vy,vz),则点积定义
简言之点积等于两个向量对应分量的乘积之和。 点积的定义不存在任何明显的几何含义。但是,使用余弦定理可以发现存在如下关系:
|
|
叉积 |
是向量数学定义的第二种乘法形式。它与点积不同,点积的计算结果是一个标量,而叉积的计算结果是一个向量; 叉积只能用于3D 向量(2D 向量没有叉积)。通过对两个3D 向量u 和v 计算叉积,可以得到第3 个向量w,该向量同时垂直于u 和v。
|
BSP的最小说明
bsp树是一种空间分割树,它主要用于游戏中的场景管理,尤其是室内场景的管理。
它的本质是二叉树,也就是用一个面把空间分割成两部分,分割出的空间则继续用面分割,以此类推,直到到达特定递归深度,或者空间中不再有物体或只剩下一个物体(得到凸包/凸多面体)。
最终,叶结点对应场景中的物体,内部结点存储分割面。物体被"收纳"到各个包围盒中。
BSP的简化说明
简化部分 :
(1) 使用二维,而不是三维。
(2) 手工输入包围盒,而不是自动生成。包围盒为AABB包围盒(轴向),不支持上图中的凹多边形。
(3) 叶结点和内部结点共用一个数据结构。其中内部结点存储了方向(水平或竖直)以及分割线;叶结点存储了对应场景为实心还是空心。
(4) 沿着包围盒的边界进行分割(和图中所示相同),选择分割线的方法比较简单:
|
首先 |
分别选出水平和竖直方向的最优分割线。(判断标准:与空间中心最接近的包围盒边界线) |
|
然后 |
|
|
|
如果都相交或都不相交,那么优先选择距离中心点更近的(按相对比例来算) 如果选择的分割线与包围盒相交,那么把这个包围盒根据分割线拆成两个包围盒。 |
|
退出条件(或): |
|
|
|
达到最大分割层数,直接生成两个叶结点,返回。 |
|
|
空间里没有物体了,返回空叶结点。 |
|
|
空间里只剩下一个物体了,返回满叶结点。 |

蓝线:第一次分割 ; 紫线:第二次分割 ; 黄线:第三次分割
包围盒:
(4,10,4,16)
(10,24,4,9)
(7,19,23,27)
(22,28,13,24)
bsp树

BSP用于3D游戏
问题:

在当前的摄像机位置使用正确的渲染顺序去渲染所有的将要渲染的几何体的每一帧。
你可能会说.别忘了我可以使用ZBuffer来解决顺序问题.你当然可以使用Zbuffer 但是是在没有透明物体的情况下。
如果有半透明物体.那么你将无法正确的渲染使他正确的显示出来.(ZBuffer是一个深度缓冲相关。如果打开.渲染的时候就会根据渲染点的z值来决定那个点最后显示出来.从而呈现出遮挡的关系.如果是模型中有半透明的部分那么就必须要排序之后进行混合.关键问题就出在blender的顺序上.不透明的必定要先渲染.透明的必定要后渲染)
通过camera到每一个多边形的正确顺序来处理每一帧渲染循环都去解决排序和层次问题.
深度排序问题

上面的图片的渲染情况会出一个问题.当你尝试去从后往前画这两个多边形的时候(画家算法)。两个多边形会不能正确的被画出来,先画红的后画绿的绿色的会把红色的覆盖掉…通过Zbuffer是可以解决这种问题的.但是效率不太好。如果没有硬件加速是非常废系统资源的,但是Zbuffer也不是全能的,它并不能解决半透明问题。
通过BspTree技术可以轻松的解决上述的所有问题,不单如此,还可以处理其他领域的问题如碰撞检测(因为通过BSP渲染技术之后,一帧要渲染哪些多边形是知道的所以计算诸如FPS类型的游戏打枪到墙壁的时候碰撞检测会很简单遍历当前的多边形进行计算就可以了), 多边形剔除算法。
创建一个BspTree是一个离线的过程.你可以在游戏一开始就把bsptree预计算出来。然后游戏里面使用,所有的多边形排序都是预处理出来的。这是Bsp编辑器的工作,传入一个所有的多边形的列表来然后预先排序他们.处理出来的数据可以存到硬盘上.然后游戏运行的时候可以加载进来在游戏循环环境下快速的遍历。
不但BspTree可以用来正确的渲染所有多边形在场景里.而且可以超快速的来剔除当前视点看不见的多边形。
这是因为可以简单的测试多边形在实景,这样所有的后面被遮挡的多边形就会在你的游戏中被剔除掉。
可以简单的就剔除掉成千上万的多边形,我们还将使用bsptree快速的进行碰撞检测。
如何工作的?
看下下面的例图A.他显示了一个从上面看的简单的游戏层级.这些黑色的线就游戏视图里看到的墙.那些黑色的箭头描述了墙的面向的方向.可以理解成2d线的法线.
上面的Ca Cb Cc是三个实例.它表明游戏里的3个位置(相机的位置).通过摄像机的位置先渲染最远的墙.然后渲染最近的墙.我们应该取以下的顺序.
|
Camera Position |
Correct Drawing Order |
|
Ca |
D or E in any order, A , C & B is Unclear |
|
Cb |
D or E in any order, A , B & C is Unclear |
|
Cc |
C & B is Unclear , A , D or E in any order |
BspTree存储这所有多边形的层级关系,里面都是后面前面或者相邻的多边形。
但是有一个问题就是C和B墙,我们不能明确的描述C在B的前面还是后面。这个问题使我们无法在所有的位置来使用正确顺序来渲染.
因为我们不能描述墙C是在B的前还是后。BSPTree算法将写不出来.我们必须解决这个问题让BspTree能识别这个"前后"处理.这就是二分法…(我们延长B, C会被切割成两个我们叫C1 C2. 之后C1就是B的前 C2就是B的后.BSPTree就适应了)..后面细说.这块还有点抽象.
BSPTree存储多边形的的信息是把世界切成两半.所有的多边形检测哪个在多边形的哪边。
如果相交就切开.成多个之后进行记录.也就说原来的多边形被切成了新的两个多边形。所以我们的第一次分割完成了,我们拥有了两个新的多边形,相当于第一分割出了两个世界。
这两个世界里只有绝对的前面的多边形和绝对的后面的多边形,不会再有模糊的概念,之后这两个世界里的多边形选取一个继续分割。
最后当没有可以分割的就结束该过程了.(如何选取分割的面也是一门科学.)
|
Front List of split (A) |
Back List of Split (A) |
|
B , C |
D , E |
|
Front List of split (B) |
Back List of Split (B) |
|
Ca |
Cb |
|
Front List of split (D) |
Back List of Split (D) |
|
E |
Nothing |
第一次通过A来刨分生成两个空间.后面有 DE 前面有BC..先说前面的B之后继续刨分A前面的世界、
然后把C切分成了Ca Cb.Ca就在B的前世界,Cb就在B的后世界,Ca再分已经没东西了截止。
Cb再分也没东西了截止.
再看A的后面的世界,有D和E,我们选D来刨分,之后D的后面没有东西。
D的前面有E,之后E再分已经没有东西了。结束此过程, BSP创建成功。
(原、整)BSP的江湖传说的更多相关文章
- RCNN 和SPPnet的对比
一.RCNN: 1.首先通过选择性搜索,对待检测的图片进行搜索出2000个候选窗口. 2.把这2k个候选窗口的图片都缩放到227*227,然后分别输入CNN中,每个候选窗台提取出一个特征向量,也就是说 ...
- 空间金字塔池化(Spatial Pyramid Pooling,SPP)
基于空间金字塔池化的卷积神经网络物体检测 原文地址:http://blog.csdn.net/hjimce/article/details/50187655 作者:hjimce 一.相关理论 本篇博文 ...
- Spatial pyramid pooling (SPP)-net (空间金字塔池化)笔记(转)
在学习r-cnn系列时,一直看到SPP-net的身影,许多有疑问的地方在这篇论文里找到了答案. 论文:Spatial Pyramid Pooling in Deep Convolutional Net ...
- Linux从逻辑地址到物理地址
转自:http://blog.chinaunix.net/uid-24774106-id-3427836.html 我们都知道,动态共享库里面的函数的共享的,这也是动态库的优势所在,就是节省内存.C ...
- 基于2-channel network的图片相似度判别
一.相关理论 本篇博文主要讲解2015年CVPR的一篇关于图像相似度计算的文章:<Learning to Compare Image Patches via Convolutional Neur ...
- 转-------CNN图像相似度匹配 2-channel network
基于2-channel network的图片相似度判别 原文地址:http://blog.csdn.net/hjimce/article/details/50098483 作者:hjimce 一.相 ...
- hdu 4541(麻烦的模拟)
Ten Googol Time Limit: 500/200 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Su ...
- mysql查询语句中使用星号真的慢的要死?
前言 之所以写这篇文章,是源于以前看过的关于sql语句优化的帖子,里面明确提到了在sql语句中不要使用 * 来做查询,就像下面的规则中说的 2.尽量避免使用select *,返回无用的字段会降低查询效 ...
- sppNet论文学习
Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition 深度神经网络中用于视觉识别的空间金字塔池化 ...
随机推荐
- 8086汇编语言入门-HelloWorld
附件下载: http://pan.baidu.com/s/1i5R9qO9 密码:rfgk 80x86微处理器汇编语言编程.学习任何编程语言都免不了要跨越HelloWorld这道坎,面向机器的 ...
- centos7安装python3和ipython
CentOS7下默认系统自带python2.X的版本,这个版本被系统很多程序所依赖,所以不建议删除,如果使用最新的Python3那么我们知道编译安装源码包和系统默认包之间是没有任何影响的,所以可以安装 ...
- Extjs4.2 tabPosition left 相关
解决tabPosition:left 标签的方向问题 <%@ page language="java" import="java.util.*" pa ...
- JT/T 1077-2016《道路运输车辆卫星定位系统车载视频平台技术要求》平台标准符合性检测合同
合同编号: 道路运输车辆卫星定位系统 平台标准符合性检测合同 委托方(甲方): 受托方(乙方): 交通运输通信信息工程质量检测中心 签订时间: 签订地点: 北京市 委托方(甲方): 委托方(甲方): ...
- checkboxlist 如何配置数据源?
<f:CheckBoxList runat="server" ColumnNumber="4" ColumnVertical="true&quo ...
- Python 文件访问模式
f = open('xxx文件', '访问模式') r 以只读方式打开文件(read).文件的指针将会放在文件的开头.默认模式. w 打开一个文件只用于写入(write).如果该文件已存在则 ...
- this以及执行上下文概念的重新认识
在理解this的绑定过程之前,必须要先明白调用位置,调用位置指的是函数在代码中被调用的位置,而不是声明所在的位置. (ES6的箭头函数不在该范围内,它的this在声明时已经绑定了,而不是取决于调用时. ...
- leetcode第221题(最大正方形)的本地IDE实现及变形
问题描述: 在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积.PS:本文也对只包含0的最大正方形面积进行了运算 示例: 输入: 1 0 1 0 0 1 0 1 1 1 ...
- RabbitMQ安装---rpm安装
首先介绍一下个人的安装环境是Linux-centos7: 一.安装和配置rabbitmq的准备工作: 下载erlang: wget http://www.rabbitmq.com/release ...
- hibernate映射实体类查询时数据库空字段赋值给实体类报错的问题
因为一直报实体类空异常,去网上查了资料只查到了并没有查到数据库空值时不给实体类赋值的属性 异常 org.hibernate.InvalidMappingException: Could not par ...


