games101学习笔记_Ray Tracing2

加速结构

对AABB结构进行优化来加速光线追踪的速度/Using AABBs to accelerate ray tracing

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

Uniform Spatial Partitions(Grids)(均匀空间划分)

当场景中物体分布不均匀时,不适合使用这种方法。

Preprocess – Build Acceleration Grid(预处理-建立加速网格)

  • 找到包围盒
  • 把包围盒为何分成一堆格子
  • 判定哪些格子里有物体(把与物体相交的格子都给标记出来,注意这里说的物体是物体的表面,不考虑物体内部)

在这里插入图片描述

Ray-Scene Intersection(光线场景求交)

  • 对光线与光线可能经过的格子进行求交判断
  • 若相交,进一步判断格子里的物体是否与光线相交

在这里有可能会有人提出疑问,怎么找光线会相交的网格?在这里只简单说一下方法,但在实际中并不用这种方法:当光线从左下向右上打光,那么确定好一个网格后,下一个会与光线相交的网格要么在该网格的右边,要么在该网格的上边。

在这里插入图片描述

Grid Resolution(格子划分的解决方法)

划分的格子数太少或太多都会影响求交的效果。比如下图,1x1就没有加速的必要。
在这里插入图片描述
如果格子太密集了,就需要进行很多次光线和格子的求交,如下图:
在这里插入图片描述

经过前人不断的实践,得出了下面的公式和数,用来划分格子效果最好。

  • 格子数#cells = 某个常数C * 物体的数量#objs
  • 下面在3D中的C≈27是试验出来的,并没有什么意义。
    在这里插入图片描述

Spatial Partitions(空间划分)

在这里插入图片描述

  • Oct-Tree:八叉树(在二维情况下是四叉树),把空间中一个大的包围盒切成八份(横竖平三刀切成八份),对于每一个子节点都再切成八块,当每个盒子中有足够少数量的物体则停止切割。但是维度高不好计算。上图中就对一个大块进行了细分,事实上对每一个放个都需要进行细分切割。
  • KD-Tree:每次划分只沿着一条轴砍一刀,分成两块。竖直切割和水平切割在树的层次中交替。划分有点像二叉树,但是划分并不平均。例:第一层一个节点水平分割,第二层两个节点竖直分割。
  • BSP-Tree:二分法,每次选一个方向将空间分割开。相较于KD-Tree,每次切一刀不限于坐标轴方向,可以为任意方向,只要将空间切为两个部分即可 。

接下来主要举例KD-Tree

KD-Tree

Pre-Processing

给一个场景,先把加速做好,再考虑求交。
在这里插入图片描述
对于KD-Tree加速结构:

  • 物体只保存在叶子节点(不再划分的节点)上。
  • 中间节点不保存物体,保存的是它会被划分成什么格子,长什么样。

用来存储KD-Tree的数据结构

在这里插入图片描述

非叶子节点存储:

  • 划分轴:当前轴是沿着哪一个方向切割的(x?y?z?)
  • 划分位置:沿轴的分割平面坐标
  • 子节点:指针指向孩子节点
  • 中间节点不存储物体

叶子节点存储:

  • 对应区域包含的物体

Traversing a KD-Tree(遍历KD-Tree)

在这里插入图片描述
对树结构进行逐级判断,判断每个节点表示的包围盒与光线是否有交点。

  • 若一个节点与光线有交点,则其子节点都必须进行下一步判断。
  • 若一个节点与光线没有交点,则可直接忽略该节点及其子节点,不用进行下一步判断。

举例光线与1号包围盒相交的情况:
在这里插入图片描述
假设划分根据就是右边的二叉树,那么1号节点就是叶子节点(在这里其实应该继续划分的,但是在这里我们就认为它是叶子节点,不再继续划分),那么光线就直接与1号节点内的物体求交。

在这里插入图片描述

KD-Tree的不足

  • 对于KD-Tree有一个问题很难解决:给一个AABB包围盒,很难判断三角形和盒子是否是相交的。三角形可能三个顶点都不在盒子中,但与盒子相交(垂直),这种情况很难判断。
  • 一个物体可能出现在多个叶子节点里。

Object Partitions(物体划分)

Bounding Volume Hierarchy(BVH)

BVH是将物体两堆两堆地划分下去,每一次划分完成都需要计算其包围盒,不同包围盒可以相交。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这样就能实现让一个物体(我们定义的)只被包含在一个包围盒内(但包围盒内可以有多个物体)。比如D里面的一个红色三角形只会被包含在D包围盒中,而不被其他包围盒包含,但D包围盒本身包含了多个红色三角形。

这样就避免了KD-Tree中一个物体可能会被包含在多个叶子节点中的情况。

建立BVH总结

在这里插入图片描述
处理过程:

  • 找到一个包围盒
  • 递归地把一个包围盒拆成两个部分(通过把包围盒里的物体分成两个部分)
  • 把这两个新拆出来的两个部分重新计算他们的包围盒
  • 在必要的时候停下来(当节点包含很少的元素时停止)
  • 在每一个叶子节点中存储实际物体

如何划分一个节点

  • 选择一个维度来划分
  • 技巧1:总是选择最长的轴来进行划分,让最长的轴变短,通过这种方式最后能变成一种比较均匀的状态。
  • 技巧2:选择中间的物体作为划分。这样可以让划分的两个部分包含的物体差不多相等。
    • 所有的物体按照先后排列在要划分轴方向上, 取这个序列的中位数为分界点来保证划分是均匀的,找中位数一般是不需要排序的,可以用快速选择算法在O(n)时间复杂度内完成。(快速选择:可在O(n)时间内完成找到第K大的数字)

Termination criteria(终止标准):

  • 技巧:当节点包含很少的元素时停止。

用来存储BVH的数据结构

中间节点的存储:

  • 包围盒
  • 子节点指针

叶子节点的存储:

  • 包围盒
  • 包含的物体

Nodes represent subset of primitives in scene

  • All objects in subtree

BVH Traversal(BVH遍历算法)

在这里插入图片描述

Intersect(Ray ray, BVH node) {
 //如果光线和这一整个BVH包围盒都不相交就退出这个函数
 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;
}

空间划分(Spatial Partitions) vs 物体划分(Object Partitions)

两种方式通常是BVH更经常被采用,因为划分容易。
在这里插入图片描述

Base Radiometry(辐射度量学)

之前提到的Blinn-Phong模型是一种经验模型,得到的结果并不真实,不是物理上正确的。现在从物理的角度来考虑光照模型。在物理上精确的定义了光的各个属性,可以精确的定义光,光与物体的交互,实现真实的光照。

Radiant Energy and Flux(Power)

  • Radiant Energy:是光源辐射出来的能量总量(Q),单位是焦耳(J)。
    在这里插入图片描述
  • Radiant Flux(power) : 是单位时间内光源辐射出的能量(单位时间内能量,功率),单位是瓦特(W)。
    在这里插入图片描述
    FLux还可理解为单位时间内通过的sensor(光子)
    在这里插入图片描述

我们认为重要的并且感兴趣的光的测量值

  • 光源会辐射出的各种不同的能量,我们怎样定义他们(方向性的Radiant Intensity)
  • 在任何一个物体表面,他会接收到多少能量(Irradiance)
  • 光线在传播的过程中,他的能量用什么样的方法来定义(Radiance)
    在这里插入图片描述

Radiant Intensity

定义:单位时间内光源向单位立体角(Solid Angles)所辐射出的能量。即单位时间内通过单位立体角的功率。

可以理解为在某个方向上的辐射通量。
在这里插入图片描述

Angels and Solid Angles(角和立体角)
  • 角(angle):使用弧长来定义,弧长/半径.所以圆的角度是2pi。
    在这里插入图片描述
  • 立体角(Soild Angles):立体角是二维角度在三维空间中的扩展。球体上子面积与半径平方的比率。
    对于某个立体角,从球心出发,打到一块球表面上。立体角的大小等于这块表面的面积除以球半径的平方。所以球的立体角是4pi。
    在这里插入图片描述
Differential Solid Angles(微分/单位立体角)

在这里插入图片描述

  • dA:球面上某个单位面积
  • dw:dA对应的立体角,也成为单位立体角或微分立体角

对单位立体角在球面进行积分(解一个二重积分)得到整个球面上的立体角的大小。球的立体角是S²。
在这里插入图片描述
使用立体角可以代表从球心发出的光线的方向。
在这里插入图片描述

Isotropic Point Source

Intensity就是光源在任何方向的亮度。对所有方向上的Radiant Intensity(用I表示)进行积分,可以得总的辐射通量(Radiant Flux)。
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值