图形学笔记十 光追二 划分加速 辐射度量学

2021-12-28  本文已影响0人  合肥黑

参考课程:
https://www.bilibili.com/video/BV1X7411F744?p=14

一、使用轴对齐包围盒加速光线追踪

如果场景非常复杂,我们会先找到包围盒,然后再根据包围盒的情况进行对物体的求交,找到包围盒的过程是空间划分的过程。

1.均匀空间划分

首先我们找到一个场景的包围盒,然后对这个包围盒进行划分,分成一堆格子,接着判定与物体相交的格子,标记出来。做完以上预处理之后,我们得到了可能含有物体的格子。


image.png

在接下来做光线追踪的过程中,我们只要判断光线有交到的是不是有物体的格子,不是的话直接跳过,是的话再对盒子里的物体求交(此处假设光线与物体求交很慢,与盒子求交很快)。

下图一条光线沿着右上打过去,我们怎么知道它会碰到哪个盒子呢?难道每个盒子都要判断一遍么。不需要的,最简单的想法是,如果是右上,那么下一个盒子一定在右边或者上边(这也是之前光栅化没提到的话题,如何光栅化一条线)


image.png
2.加速效果怎么样

考虑一个极端情况,如果划分成1×1的格子,那么没有加速效果。如果划分太密集,效率也不高。根据经验,人们大概得出划分成场景中物体数目的27倍的格子数比较好。

格子的划分方法在大量均匀分布的物体上比较有效,然而在复杂空旷的场景中表现不好,会出现类似体育场中找茶壶的现象。

二、Spatial Partitions空间划分

在格子法中,空间划分的都是大小相同的格子,然而有些空旷的地方不需要这样,太浪费了,我们在没物体的地方用大盒子,有物体的地方用密集的盒子,这也就引出了空间划分的方法。


image.png
1.Oct-Tree

八叉树,先把三维空间切三刀,也就是切成八份(二维的话如图是四份),对于每一个子节点,再切一遍,以此类推。

如何停止呢,我们可以定个类似这样的规则,比如二维的情况,切成四块时三块都没物体,就不在往下切 之类的,其思想也就是划分到一定程度还没物体就不切了。

但是人们不喜欢八叉树,因为比如在二维这种划分方法是四叉树,三维是八叉树,那么维度更高,就是2的n次方叉树,这样并不好,维度更高会越来越复杂。

扩展阅读:
游戏场景管理的八叉树算法是怎样的? - Milo Yip的回答 - 知乎

2.KD-Tree

为了解决这个问题,能让空间得到划分并且和维度无关,人们发明了KD树。KD树和八叉树的划分方法几乎完全相同,只不过它每次沿着某一个轴砍开,并且只砍一刀,永远这么做。

空间被划分成类似二叉树的结果,每次节点的划分底下都只有两个子节点。划分时为了均匀起见,xyz依次砍。

3.BSP-Tree

是一种对空间二分的划分方法,它每次选一个方向砍开,它和KD树的区别是它不是横平竖直地砍,而且它会有越高维越不好计算的问题(砍开二维用线,砍开三维用面,维度越高越复杂)

三、KD树
1.建立树

以下是一个KD树划分的例子。我们先明确,这些空间划分方法是在光线追踪之前,先把空间加速结构划分好,然后再进行光线追踪。下图每一块都需要砍开,只不过示意图只沿着右边在做。

一开始竖直划分成1 B,之后B划分成2 C,以此类推


image.png
2.看看这个结构将如何加速光线追踪

考虑我们划分成这种情况


image.png

首先考虑最大的包围盒A,发现有交点,那么对于左右子节点可能都有交集。我们发现和左边蓝色的有交点,我们假设它是叶子节点,就先这样,继续看右边,发现也有交点。以此类推判断2 然后判断C,然后判断3,发现3是叶子节点,在3中与物体求交,找到交点。

结论就是,如果光线和某个格子没有交点,那么什么都不用做。如果有交点,那么光线可能和它的两个子节点有交点,所以都要判定一下。相当是一个递归,直到叶子节点,如果无交点就结束,如果有交点就进入盒子判定物体。

KD树会产生一些问题

四、物体划分Bounding Volume Hierarchy(BVH)

空间划分存在一些问题,于是人们发现了另一种做法,我们不从空间划分,我们从物体开始划分,这种划分形成的加速结构也就是所谓的BVH。BVH在离线和实时渲染中,都得到了广泛应用。

1.BVH是怎么运作的呢

最开始也一样有一个盒子包围场景作为根节点

image.png
然后我们把物体分为两部分(怎么求之后再说),然后重新求他们这两部分的包围盒
image.png
以蓝色节点为例,我们继续划分再重新求包围盒,划分到比较少的三角形,比如5个三角形左右就可以停止
image.png
把物体分成两堆,重新计算它们的包围盒。

BVH的特性是,一个物体可以只存在在一个节点里,并且不用算三角形和包围盒求交了。但是BVH的划分并没有划分开,包围盒可能会相交,不过没什么问题,我们做到尽可能重叠少就好,这也是当今一个研究的方向。

2.划分方法

可以向KD TREE学习,XYZ维度进行交替,这样就会比较均匀。

还有一个技巧是,如果整个场景都在一个长条里,应该更多地把长条变短。也就是,每次都沿着最长的那个轴进行切分,这样就更均匀。

还有一个类似二分法,每次都找中间的那个物体进行切割,这样两侧的三角形数量都是差不多的。

3.如果物体动了,加减物体,没办法,要重新计算BVH。
五、辐射度量学

在之前讲Blinn-Phong着色模型时,会设置一个数当做光照强度I,但是这个数真实的物理意义我们并不甚清楚,我们只是极大简化成一个数。

Whitted风格的光线追踪不是一个真实的结果。所有的这些都会被辐射度量学解决,这也是路径追踪的基础。

辐射度量学给出了一系列度量方法和单位去定义光照。它定义了光照在空间中的属性,这在物理上是完全正确的。简单翻译如下:

1. Radiant Energy and flux(Power)

Radiant energy:辐射能量,单位焦耳Joule,
Radiant Flux(Power):单位时间内辐射出的能量,可以表示光的亮度


image.png

Flux也可以理解为单位时间内通过这个平面的光子的数量


image.png
2.由Energy和Power定义出其他物理量
image.png
4.立体角前置知识

在视频后面要讲解Intensity,需要对立体角进行理解,可以参考知乎链接来加深理解:

怎么理解立体角,立体角的意义是什么,能不能通过平面角作为工具去理解立体角?

平面角:圆的弧长与半径之比。我们之所以采取这样的定义是因为,利用弧长与半径之比,能够在二维尺度下唯一确定这个角的大小。但是对于三维的角呢?比如说圆锥的顶角大小。由于他是三维的,显然说他是多少多少度是不合适的。可能你听过某些说法比如圆锥的顶角大小是多少多少度,其实这样的说法是把他投射到二维上说的,也是不够严谨的。

那我们如何唯一确定三维空间某个“角”的大小呢?立体角:投影面积与球的半径平方之比。注意这里的投影面积是球上的投影面积。这样的定义允许我们在三维空间中唯一确定某个三维尺度上“角”的大小。

注意到我们用的是投射面积,那么投射当然是以某个点为“源”进行投射,所以我们在说立体角时,要具体说明是关于哪一个点的立体角,如果没说那就是默认在投射体内。e.g.一个完整球体对于球内任意一点的立体角如何计算呢?


image.png

在你以后的学习过程中会更多的用到他的微分形式:


image.png https://www.zhihu.com/question/60313596/answer/2266950884
4.Radiant Intensity

在单位时间内,往每个立体角(Solid Angle)上辐射出的能量


image.png

那什么是立体角呢,我们先从平面角入手。平面角的定义是以弧长除以半径,并且此时圆的放大缩小并不影响这个角度,平面角最大为2π。扩展到三维,立体角的定义是面积除以半径的平方,根据积分可得立体角最大为4π。


image.png
极坐标或者叫球坐标,得到微分立体角:
image.png

现在回头看Intensity,我们定义一个均匀发光的点光源,积分全部的单位立体角上的Intensity得到能量,单位立体角上的Intensity也就是能量Power除以4π


image.png

下面举一个生活中的例子:标着60w的LED灯,其实是功耗为11w,亮度相当于60w的白炽灯。我们也可以算它的Intensity,假设是均匀发光,用能量lumens除以面积4π得到单位立体角上的Intensity。


image.png
上一篇下一篇

猜你喜欢

热点阅读