快速区分清楚图形渲染中的AABB,KD树和BVH这些概念

快速区分清楚图形渲染中的AABB,KD树和BVH这些概念

主要想形象去区分好这些术语,目的是扫盲,先开好坑,内容持续填充。


0.先摆出这些词的全称

  • AABB: 原名:axis aligned bounding box;中文直译名:轴对齐包围盒。一般常见也会叫它aabb盒。
  • KD Tree: 原名:K-dimension tree, dimension是维度的意思。中文直译:KD树。
  • BVH: 原名Bounding Volume Hierarchies,Hierarchies是层次、结构的意思;中文直译名:层次包围盒。常见也会叫它BVH树(搞得人家对BVH是树还是盒傻傻分不清)

强烈建议无视中文直译名,因为无法帮助理解还看得人糊里糊涂,想记住理解这几个名词,最好以图为准,脑海中知道它们长什么样的(正如你对链表、二叉树这个数据结构的印象一样去理解)。


1.AABB(axis aligned bounding box)

AABB长的是白色线框这样,包围住兔子,兔子完全在AABB内:

在这里插入图片描述

你的一个三维模型,读入三维场景中,便坐落在了世界坐标系上(图中红绿蓝轴线分布对应xyz轴线),你的模型实际上是网格模型,许多个三维顶点组成模型的表面,那每个三维顶点都可以被xyz表示。

那么最简单最快速地去评估这个模型在场景中占了多少空间,就是去看模型分布在X、Y和Z轴的最小值和最大值是多少,只需要遍历每个顶点坐标,找出X、Y和Z的最小值和最大值。一共六个值,可以组成一个最小值点和一个最大值点。而X、Y和Z的最小值和最大值所包括的空间范围就是AABB,如上图的白色线框。(顺便一提:那最小值点和最大值点其实刚好是在对角。)

AABB是个立方体,是个盒子,里面包着就是模型,那是不是需要写一个类,或者写个数据结构去记录维护这个AABB呢?——其实不需要,因为我要的是最简单最快速,所以记录好六个值就能记录好AABB了(当然是不需要像上图那样可视化的情况下,只需要一个数组把X、Y和Z的最小值和最大值存储起来即可)。

所以AABB通常作为一个类属性放进模型数据这个类里面。

说一个AABB最直观的好处,假如一个兔子模型有几万个三角形组成,我现在做光线追踪渲染,我要判断一条光线有没有照射到兔子模型,那我先跟兔子的AABB(只有六个值)做相交检测,可以很快速地发现没有相交,那么就可以直接跳过兔子模型,几万个三角形都可以无视掉了,是不是很牛逼!

所以AABB很简单,但是在很多应用方面的第一步就已经能提供很大的帮助。


AABB与KD Tree和BVH的关系

我把AABB跟KD Tree和BVH放到一起,难道BVH这种词是指斜着放或者最小包围住模型的多边盒子吗?

其实AABB跟KD Tree和BVH根本不是一个维度的东西,但是我在接触图形渲染初期,就经常会想搞清楚AABB和BVH的区别,因为看中文直译名两个都说是盒子,一个轴对齐包围盒,一个层次包围盒,我就以为是类似的东西(像B树和B+树那样)要做区别,所以我才会强烈建议无视中文直译名。

先简单去说清楚,KD Tree和BVH是两种对空间做划分组织的方法,也可以说是数据结构,但是本质上还是对空间划分组织方式的不同。它们都会用到AABB,这就是它们之间的联系,KD Tree和BVH是方法,需要用到模型中AABB这个属性。


为什么需要KD Tree或者BVH对空间去做划分组织?

我们继续刚刚AABB中光线寻找照射点的例子,光线没有与兔子的AABB相交倒好,可以直接无视跳过几万个三角形不用管啦。但是万一光线与AABB相交了呢,那不得继续往几万个三角形里面钻啊,那这时光线要逐一与兔子表面的每个三角形做相交才能知道光线照射到哪一个三角形,如果光线找了前几个三角形就发现相交了还好说,万一要找到最后一个三角形才能发现相交,这个计算量想想都可怕(相交计算正是光线追踪渲染中消耗时间的大头)

最直观的解决想法

那我们就会去想方法减少无用功,例如我们想着能不能先判断光线与AABB的左半部分相交还是右半部分相交呢,然后不就可以排除掉将近一半的三角形了嘛,假如光线跟AABB的左半部分相交,那不是可以继续对该部分分下左右再去判断和排除了,一步步递进到最后才到三角形,不要一来就跟最小的三角形判断相交嘛。整个过程不就省下很多计算了吗

刚刚好这个想法就形成了KD Tree的雏形,或者说KD Tree就是这么想的,就是如此去对空间做划分,另外还有在上面想法中没有想到的组织方式的问题。


2.KD Tree(K-dimension tree)

其实记住简称和英文全称都对理解没多大帮助,看英文直译就是k维度树,完全不知道啥玩意,所以还是记形象的图片吧。

我们图形渲染都是跟三维空间打交道,网上很多解释都是拿二维图来说事,很难转过来验身都三维空间去理解,所以去理解KD Tree,应该直接用三维的方式去理解。

三维指的是x,y和z三个维度,KD Tree你往宏观去说,可以很多个维度,但是我们就在图形渲染中用,我们就看在图形渲染中怎么用的,用的就是三维的,我们就看x,y和z三个维度,其他的不管(但是原理是同样的,像多幂次的展开实际就是多次乘法一样)。

我们看看图片吧

3.BVH(axis aligned bounding box)

BVH的目的跟KD Tree是一样的——都是为了将模型中的三角形组织地更高效——》使得在找三角形的时候更高效省时。

  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用以下正则表达式来查找word文件aabb和abac形式的成语: aabb形式:\b(\w)\1(\w)\2\b abac形式:\b(\w)(?!\1)(\w)\1(\w)\b 其,\b表示单词边界,\w表示任意字母或数字,\1和\2表示第一个和第二个捕获组,(?!\1)表示后面的字符不能与第一个捕获组相同。 ### 回答2: 正则表达式是一种强大的文本搜索工具,可以帮助我们在大量的文本快速查找符合特定模式的字符串。在Word文件查找aabb和abac形式的成语,可以使用以下正则表达式: 1. 查找aabb形式的成语 由于aabb形式的成语是由两个相同的汉字组成的,因此可以使用反向引用来匹配。具体来说,可以使用`\b(\w)\1(\w)\2\b`来匹配aabb形式的成语,其`\b`表示单词边界,`(\w)`表示一个汉字,`\1`表示第1个捕获组(即第1个括号内的内容),`\2`表示第2个捕获组(即第2个括号内的内容)。 2. 查找abac形式的成语 abac形式的成语由两个不同的汉字和一个相同的汉字组成,因此可以使用正向后向引用来匹配。具体来说,可以使用`\b(\w)(\w)(\w)\1\b`来匹配abac形式的成语,其`\b`、`(\w)`、`\1`的含义同上,`(\w)(\w)(\w)`表示三个相邻的汉字。 在Word文档查找成语,可以使用Word的高级查找功能。具体步骤如下: 1. 打开Word文档。 2. 按下Ctrl和F键,打开查找和替换对话框。 3. 点击“高级查找”按钮,打开高级查找对话框。 4. 在“查找内容”文本框输入正则表达式,如`\b(\w)\1(\w)\2\b`或`\b(\w)(\w)(\w)\1\b`。 5. 点击“查找下一个”按钮查找匹配的成语。 6. 如果需要替换成语,可以在“替换内容”文本框输入替换字符,然后点击“替换”或“全部替换”按钮进行替换。 需要注意的是,在使用正则表达式进行文本搜索时,要确保正则表达式的准确性和正确性,避免出现匹配错误或漏掉匹配的情况。同时,由于正则表达式的语法较为复杂,所以需要较强的正则表达式基础知识和实战经验。 ### 回答3: 首先,我们需要明确两个问题:一是如何查找Word文件,二是如何使用正则表达式匹配“aabb”和“abac”形式的成语。 1. 查找Word文件 我们通常使用文件搜索功能或者命令行来查找Word文件。在Windows系统,我们可以通过按下“Win + F”来打开文件搜索功能,然后输入“.docx”或者“.doc”等文件扩展名来查找Word文档。如果我们想要搜索某个文件夹及其子文件夹的Word文件,可以在文件搜索功能设置搜索范围为“本地磁盘”或者某个文件夹。 如果想要使用命令行来查找Word文件,我们可以使用“dir”命令或者“find”命令。例如,在Windows系统,我们可以打开命令行窗口,输入“dir C:\*.docx /s”,这会搜索C盘及其子文件夹所有的.docx文件。如果要查找.doc文件,可以将命令改为“dir C:\*.doc /s”。 2. 使用正则表达式匹配“aabb”和“abac”形式的成语 要想匹配“aabb”和“abac”形式的成语,我们可以使用正则表达式的"()"、"\1"和"\2"等元字符。 首先,我们可以使用“()”将匹配到的内容分组,以便后续引用。其次,我们可以使用"\1"和"\2"来引用前面的分组。 例如,我们可以使用以下正则表达式来匹配“aabb”形式的成语: (\S\S)\1 这个正则表达式的意思是,匹配两个连续的非空白字符,并将它们分为一组。然后,使用“\1”引用前面的分组,表示这个组的两个字符重复出现了一次。 类似地,我们可以使用以下正则表达式来匹配“abac”形式的成语: (\S)\S\1\S 这个正则表达式的意思是,匹配四个非空白字符,其第一个和第三个是相同的字符,第二个和第四个是不同的字符。然后,使用“\1”引用第一个字符,表示这个字符在第一和第三位出现了一次。 对于一个Word文档,我们可以使用文本编辑器或者编程语言的正则表达式功能来匹配其的成语。例如,在Python,我们可以使用re模块来编写正则表达式匹配代码。代码示例如下: import re file_name = "example.docx" # Word文档的文件名 idiom_pattern1 = r"(\S\S)\1" # 匹配“aabb”形式的成语的正则表达式 idiom_pattern2 = r"(\S)\S\1\S" # 匹配“abac”形式的成语的正则表达式 with open(file_name, "r") as f: text = f.read() idioms1 = re.findall(idiom_pattern1, text) # 查找所有符合“aabb”形式的成语 idioms2 = re.findall(idiom_pattern2, text) # 查找所有符合“abac”形式的成语 print(idioms1) # 打印所有符合“aabb”形式的成语 print(idioms2) # 打印所有符合“abac”形式的成语 注意,以上Python代码只是一个示例,实际使用时需要根据具体情况进行调整。此外,还要注意Word文档的编码问题,如果文档包含非ASCII字符,可能需要进行编码转换才能正确匹配。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值