计算机图形学GAMES101(十三)光线追踪(加速结构)

AABB是怎么加速光线追踪的

  • 网格划分(Uniform grids)
  • 空间划分(Spatial partitions)

网格划分(Uniform grids)

1、找出包围盒
在这里插入图片描述
2、划分网格
在这里插入图片描述
3、找到有物体的格子
在这里插入图片描述
假设光线和格子求交是很快的,和物体求交很慢

这个时候有一条光线穿过这个包围盒,光线穿过的格子为蓝色。当光线走到一个有物体的格子就说明光线可能和物体相交,这个时候就需要求光线和物体是否相交了。其中深蓝色的格子就是光线和物体相交了。

这样做就避免了执行很多次光线和物体求交,改为执行光线各格子求交。光线和格子求交是很快的,所以加速了光线追踪的速度。
在这里插入图片描述

怎么划分格子的大小

当格子太稀疏无法确定哪些地方没有物体,哪些地方有物体,这样就需要做很多次光线和物体的求交,则实际上没有太大效果。

当格子太稠密,检测次数变多,效率也会降低

应该划分的格子数量:
C:表示某一个常数
cells:表示格子的总数量
objs:表示物体数量

C在三维平面里根据经验一般取值为 27
在这里插入图片描述

空间划分(Spatial partitions)

当场景中的物体分布比较均匀时,网格划分的效果很好
当场景中的物体分布不均匀时,网格划分的效果就不太行,那么就要用到空间划分了。

一个真实的场景中经常有一大块的空白区域,这一大块空白其实可一用一个大格子来覆盖,而其他物体稠密的区域仍然用小格子。

Oct-Tree:八叉树,对于三维空间中的一个场景将其横竖切三刀,切成八块,在二维空间表现为四叉。它的意思就是把包围盒切成四块,然后对于每一个子节点在切成四块,当格子是空的或者格子里面物体足够少时就停止。但是对于高维空间不好划分。

KD-Tree:类似二叉树,每次将包围盒分成两份,每次都是沿着某个轴的方向进行分割,并且分割顺序是x->y->z ->x->y->z……这样循环往复。

BSP-Tree:也是每次划分选择一个方向将空间分成两部分,与KD-Tree相比它不是横平竖直的划分,不好计算。

KD-Tree

在做光线追踪前需要把KD-Tree划分好然后进行光线追踪

假设A是一个场景,全部在这个包围盒里。然后进行第一次垂直划分(蓝色和绿色)
在这里插入图片描述
接下来进行第二次横向划分(绿色和黄色)。蓝色部分实际上也要做划分,这里并不进行演示。
在这里插入图片描述
然后在黄色部分进行垂直划分,最后再进行横向划分即可得到下面的图形。

可以发现这样就得到了一颗二叉树,叶子节点存放格子的序号。
在这里插入图片描述
建立好这个结构后就可以做光线追踪的加速了。

KD-Tree在实际中是怎么加速的

首先检查光线和场景中最大的包围盒A是否有交点在这里插入图片描述
如果有交点则检查光线和左子树是否有交点,当找到一个叶子节点时,那么就和该叶子节点里面的物体求交。(这里1号节点是叶子节点当到达这个节点,那么就要和这个节点里面的物体求交)

在这里插入图片描述
接下来光线经过了2号区域那么需要和2号区域里面的物体求交,光线又经过了3号区域那么也要和3号区域里面的物体进行求交。thit表示光线和最近的物体相交了。

可以发现4号区域和5号区域光线没有经过,所以不要和里面的物体进行求交,加速了计算速度。
在这里插入图片描述
KD-Tree也有很多缺点:

  • 对于有一个三角形构成的场景中,很难判定一个三角形和包围盒有交集
  • 一个包围盒被划分成了很多个小格子后,一个物体可能会在多个格子里,那么在这些格子都要保存这个物体,最后判断这个物体和光线是否相交也要执行很多次。

层次包围盒Bounding Volume Hierarchy(BVH)

之前的方法都是按照空间来划分的,这个是按照物体划分的。

这个方法现在广泛应用在光线追踪中

BVH的实现步骤

有一个场景 如下
在这里插入图片描述
然后将这个场景这个打的包围盒,划分成两部分,然后重新求这两部分的包围盒。
在这里插入图片描述
然后再对蓝色部分重新划分成蓝色和绿色,再次求包围盒
在这里插入图片描述
KD-Tree是先将盒子分成两部分,然后再考虑物体和盒子的相交情况。
BVH是物体分成两部分,然后再重新求包围盒,当叶子节点里三角形数量足够少时停止。

这么做BVH就有一个优点:一个物体只会出现在一个盒子里。 避免了和同一个物体多次求交

但是BVH对空间的划分可能会重叠,找到一个重叠少的划分方法,也可以提高效率

划分的依据

  • 为了让包围盒(节点)在空间中均匀分布,每一次都只沿着最长的轴将其划分。
  • 在一个节点里划分的时候取一个包围盒中间的物体,(每个三角形都有一个序号,取序号为n/2的三角形)这样分成两部分后,这两部分里面的三角形数量差不多相同,也就是要构造一个平衡二叉树

BVH伪代码

Intersect(Ray ray, BVH node) {
 if (ray misses node.bbox) return;		//光线和包围盒不相交
 if (node is a leaf node)				//该节点时叶子节点
 test intersection with all objs;		//测试光线和该节点里面的所有物体是否相交
 return closest intersection;			//返回最近的交点
 hit1 = Intersect(ray, node.child1);	//递归左子树
 hit2 = Intersect(ray, node.child2);	//递归右子树
 return the closer of hit1, hit2;
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值