本文出自Physically Based Rendering 自行翻译和总结:
1.2节 Photorealistic Rendering and the Ray-Tracing Algorithm
Photorealistic Rendering and the Ray-Tracing Algorithm(真实感渲染和光线追踪算法)
逼真渲染的目标是创建与同一场景的照片无法区分的3D场景的图像。在我们描述渲染过程之前重要的是理解在这种情况下,不可区分这个词是不严谨的(imprecise),因为他涉及人类观察者,并且不同的观察者可能会以不同方式感知相同的图像。尽管我们将在本书中讨论一些感知的问题,但要说明给定观察者的精确特征是一个非常困难且基本上未解决的问题。在大多数情况下,我们将对光物理及其与物质相互作用的正确模拟刚到满意,依靠我们多显示技术的理解,向观众现实最佳的图片。
· 相机:相机型号决定了如何从那个位置上观看到场景,包括如何在传感器(sensor)上记录场景图像。许多渲染系统从相机开始生产观察光线,然后追踪到场景中。
· 射线与物体的交点:我们必须能够准确的判断给定射线与几何物体的交点。此外,我们需要确定交点处的对象的某些属性,例如曲面法线或其材质。大多数光线追踪器还具有一些用于测试的光线与多个对象的交点的功能,通常会返回沿光线最近的交点。
· 光源:没有照明,渲染场景就毫无意义。光线追踪器必须模拟整个场景中的光分布,不仅包括光本身的位置,还包括他们在整个空间中分配能量的方式。
· 可见性:为了知道给定的光是否在表面上某个点沉积能量,我们必须知道从该点到光源是否有不间断的路径。幸运的是,这个问题在光线追踪器中很容易回答。因为我们只需要构造从表面到灯光的光线,找到最近的光线的交点,并将交点的距离与灯光的距离进行比较。
· 表面散射:每个对象都必须提供对器外观的描述,包括有关等如何在与对象表面相互作用的信息,以及在辐射(或散射)光的性质,表面散射模型通常是参数化的,以便他们模拟各种外观。
· 间接光的传输:因为光可以在反射或穿过其他表面后到达次表面,因此通常需要追踪源自该表面的额外光线以完全捕捉这种效果。
· 射线的传播:我们需要知道沿着射线传播的光在穿过空间时会发生什么。如果我们在真空中渲染场景,光能沿光线保持不变。尽管真正的真空在地球上并不常见,单它们对于许多环境来说是一个合理的近似值。更多复杂的模型可用于追踪穿过雾,烟,地球大气层等的光线。
我们将在本节中简要讨论这些模型任务中的每一个,在下一节中,我们将展示PBRT与底层模拟组件的高级接口,并通过主渲染循环跟踪单个射线的进度。
相机(Camera)
几乎每个人都是用过相机并且熟悉他的基本功能,你希望表达出记录世界的照片,然后将图片记录在胶片或者电子设备上。最简单的拍照设备之一成为针孔相机。针孔相机有一个不透光的盒子组成。盒子的一端有一个小孔,当洞被揭开时,光线进入这个洞并落在一张贴在盒子另一端的相纸上。尽管它很简单,但这种相机今天仍在使用,经常用于艺术目的。需要很长的曝光的时间才能在胶片上获得足够的光线以形成图像。
![](https://i-blog.csdnimg.cn/blog_migrate/55e5c8b32a5ddb8b38e97799f9a6a00e.png)
尽管大多数相机比针孔相机复杂的多,但他时一个方便的模拟起点。相机最重要的一个功能时定义将被记录到胶片上的场景部分。在图1.1中,我们可以看到京针孔连接到胶片边缘如何创建一个延伸到场景中的双金字塔。不在这个金字塔内的物体不能在胶片上成像。因为实际的相机成像比金字塔更复杂的形状,所以我们将可能在胶片上成像的空间区域称为视椎体。
考虑针孔相机的另一种方法是将胶片平面放置在针孔前面但距离相同。请注意,将孔连接到胶片以定义与之前完全相同的视椎体,当然,这不是构建真实相机的使用方法,但出于模拟的目的,它是一种方便的抽象。当胶片(或图像)平面在针孔前面时,针孔通常被称为眼睛。
![](https://i-blog.csdnimg.cn/blog_migrate/fd201b90a12c42ce2a4f6f55c6ce73ca.png)
现在我们来到渲染的关键问题:在图像中的每个点,相机记录的颜色值时多少?如果我们回想一下最初的针孔相机,很明显,只有沿着针孔和胶卷上一个点之间的矢量传播的光线才能确定胶卷的位置。在我们的模拟相机中,胶片平面位于眼前,我们对从图像点到眼睛的光量感兴趣。
因此,相机模拟器的一项重要的任务是在图像中娶一个点并生成光线,入射光沿着该光线将有助于该图像位置,因为一条射线由一个原点和一个方向的矢量组成,所以对于图1.2的针孔相机模型,这个任务特别简单:它使用针孔作为原点,从针孔到近平面的矢量作为射线的方向。对于涉及多个镜头的更复杂的相机模型,对应与图像上给定点的射线的计算可能更复杂。
通过将图像的位置转换为完全封装在相机模块中的光线过程,渲染系统的其余部分可以专注于评估沿着这些光线的照明,并且可以支持各种相机的型号。
射线-物体相交(ray-Object Intersections)
每次相机生成一条射线时,渲染器的第一个任务时确定该射线首先与那个对象(如果有)相交以及相交发生的位置·。这个交点时沿线的可见点,我们将要在该点模拟光与物体的相互作用。要找到交点,我们必须针对场景中的所有对象测试射线是否相交,并选择射线首先相交的那个。给定一条射线,我们首先以参数形式编写它:
r(t) = o + td
其中o是射线的原点,d是他的方向向量,t是一个合法的参数范围(0,∞)。我们可以通过指定其参数值并评估上述方程来获得延射线的点。
通常很容易找到光线和隐式函数定义表面之间的交点。我们首先将射线方程代入隐式方程,生成一个新函数,其唯一的参数为t。然后我们求解这个函数并将最小的正根代入射线方程以找到所需的点。例如,以原点为中心半径为r的球体的隐式方程为:
x² + y² + z² - r² = 0
代入射线方程,我们有:
(Ox + tdx)² + (Oy + tdy)² + (Oz + tdz)² - r² = 0
除t值之外的所有值都是已知的,为我们提供了一个容易求解的关于t的二次方程。如果没有真正的根,射线就会与球体没有交际;如果有根,射线方程最小t
的解就是交点。
仅交点对于光线追踪器的其余部分来说是不够的;他需要知道该点表面的某些属性。首先,必须确定该点的材料表示并将其传递给光线追踪算法的后续阶段。齐次,还需要有关交点的额外信息才能对点进行着色。例如,始终需要表面法线n。尽管许多光线追踪器仅使用n,但更为复杂的渲染系统(如pbrt)需要更多信息,例如位置和表面法线相对于表面局部参数化的各种偏导数。
当然,大多数场景都是由多个对象组成的。蛮力方法是依次针对每个对象测试射线,选择所有交点的最小正值t以找到最近的交点。这种方法虽然正确,但速度非常慢,即使对于适度复杂的场景也是如此。更好的方法是结合 加速结构,在光线相交过程中快速拒绝整组对象。这种快速剔除不相关几何体的能力意味着光线追踪飞快 O(I log N)I次数,其中I是图像中的像素数,N是场景中的对象数。
光分布
射线-物体相交的阶段为我们提供了一个要着色的点以及该点的局部几何信息。回想一下,我们最终的母的是找到距离该点朝向相机的方向向量。为了做到这一点,我们需要知道有多少光到达这个点,这涉及场景中光的 几何分布和辐射分布。对于非常简单的光源(例如,点光源),照明的几何分布是知道灯光位置的简单问题。然而,点光源在现实世界中并不存在,因此基于物理的光照通常是基于区域的光源。这意味着光源与从其表面发射照明的几何对象相关联。但是,我们将在本节中使用点光源来说明光分布的组成部分;
我们经常向知道在交叉点周围的微分区域上沉积的光功率量图1.3.我们将假设点光源具有与其相关的一些功率Φ,并且它在所有方向上均等地辐射光。这意味着围绕光的单位球体上的单位面积功率为Φ /(4π)。
![](https://i-blog.csdnimg.cn/blog_migrate/08df7798b117ab6b1b912c58f1f0acab.png)
如果我们考虑两个这样的球体(图1.4),很明显,大球体上一点上的单位面积的功率一定小于小球体上一点上的功率,因为相同的总功率分布在更大的区域上。 具体来说,到达半径为r的球面上一点的面积成正比 比值为1/r²。
![](https://i-blog.csdnimg.cn/blog_migrate/6731c47d93ee32aea56a06501f189401.png)
此外,可以证明,如果微小的表面贴片 dA与从表面点到光的矢量倾斜一个角度θ,则沉积在 dA 上的功率量与成正比 。综上所述,每面积 dE 的微分功率(微分辐照度)为
![](https://i-blog.csdnimg.cn/blog_migrate/1cdbafe8fc61070bd8d6ed0be0afade9.png)
已经熟悉计算机图形基本照明的读者会注意到在这个方程中编码的两个熟悉的定律:上面提到的倾斜表面的余弦衰减,以及光随距离的1 / r平方衰减。
有多个灯光的场景很容易处理,因为照明是线性的:每个灯光的贡献可以单独计算和求和,以获得整体贡献。
可视化
上一节中描述的光照分布忽略了一个非常重要的组件:阴影。仅当从该点到灯光位置的路径畅通无阻时,每个灯光才会为被着色的点提供照明(图 1.5)。
![](https://i-blog.csdnimg.cn/blog_migrate/c9ec37deda87067b56c24c523fd0c643.png)
幸运的是,在射线追踪器中,很容易确定光线从被遮蔽的点是否可见。 我们只需构造一条新的光线,它的原点在表面点,方向指向光。 这些特殊的射线被称为阴影射线。 如果我们在环境中跟踪这条射线,我们可以检查是否在光线的原点和光源之间找到任何交点,通过将任何交点的参数t值与沿着光源位置的射线的参数t值进行比较。 如果在光和表面之间没有遮挡物,则包括光的贡献。
表面散射
我们现在能够计算出对点的正确着色至关重要的两条信息:它的位置和入射光。现在我们需要确定入射光是如何在表面散射的。具体来说,我们感兴趣的是沿着我们最初追踪的光线散射回来的光能量,以找到交点,因为该光线通向相机(图 1.6)。
![](https://i-blog.csdnimg.cn/blog_migrate/1efffed40d51d89c7f1da893300057b9.png)
场景中的每个对象都提供了一个材质,他是对其在表面上每个点的外观属性的描述。该描述有双向反射分布函数(BRDF)给出,这个函数高耸我们有多少能量从输入方向反射到输出方向。我们将点p出的BRDF作为fr(p,w0,wi).现在,散射回相机的光量的表示很简单:
for each light:
if light is not blocked:
incident_light = light.L(point);
amount_reflected =
surface.BRDF(hit_point, camera_vector, light_vector)
L += amount_reflected * incident_light;
这里我们用符号L来表示光,这表示光测量单位与之前使用的dE略有不同。L表示辐射度,测量光的单位。
很容易将BRDF的概念推广到透射光(叫做BTDF)或从表面两侧到达的光的一般散射。 描述一般散射的函数称为双向散射分布函数(BSDF)。 pbrt支持多种BSDF模型; 。 更复杂的是双向散射表面反射分布函数(BSSRDF),它模拟了从不同的点进入表面的光。
间接光的传播(Indirect Light )
Turner Whitted关于光线追踪的原始论文(1980)强调了光线追踪的递归性质,这是使在渲染图像中包含间接镜面反射和透射成为可能的关键。 例如,如果一个射线从相机打闪闪发亮的对象像一面镜子,可以反映出射线交点的曲面法线,递归地调用光线跟踪程序发现镜子上的光到达点,增加对原来的相机光线。 同样的技术可以用来追踪穿过透明物体的透射光线。 很长一段时间以来,大多数早期的光线追踪例子都是用镜子和玻璃球(下图)来展示的,因为这些类型的效果很难用其他渲染技术来捕捉。
![](https://i-blog.csdnimg.cn/blog_migrate/5100b9e2fdaddb303cc0138921ca7206.png)
![](https://i-blog.csdnimg.cn/blog_migrate/3592fc897a7b66c1b6d4a01059241d90.png)
一般来说,从物体上的一点到达相机的光量由物体发出的光(如果它本身是光源)和反射光量的总和给出。这个想法由光传输方程(也通常称为 渲染方程)也就是说,点p向wo方向发出的辐亮度Lo(p,wo)等于该点在该方向上发出的辐亮度Le(p,wo)加上球s²在p周围各方向入射的辐亮度乘以BSDF f(p,wo,wi)和余弦项:
![](https://i-blog.csdnimg.cn/blog_migrate/d01f7129e13f5576737c66e4165cd91d.png)
解析解决这个积分是不可能的,除了最简单的场景,所以我们必须作出简化假设或使用数值积分技术。
Whitted的算法简化了这个积分,忽略了来自大多数方向的入射光Li(p,wi),只计算到光源的方向以及完美反射和折射的方向。换句话说,它把积分变成了对少量方向的和。
Whitted的方法可以扩展到捕捉更多的效果,而不仅仅是完美的镜子和玻璃。例如,通过跟踪镜子反射方向附近的许多递归光线并平均它们的贡献,我们得到了一个光滑反射的近似值。事实上,每当我们碰到一个物体时,我们总是可以递归地跟踪一条射线。例如,我们可以随机选择一个反射方向wi,并通过评估BRDF fr(p,wo,wi) 来权衡这条新生成的射线的贡献。这个简单但强大的想法可以产生非常逼真的图像,因为它捕捉了所有之间的光的相互反射
当我们以这种方式递归地跟踪射线时,我们实际上是将射线树与每个图像位置(图1.8)关联起来,与来自相机的射线在树的根。树中的每条射线都有一个相关的权重;这让我们可以建模,例如,不反射100%入射光的闪亮表面。
![](https://i-blog.csdnimg.cn/blog_migrate/bea65b622ccf2b94b230290914d175d3.png)
光线传播(Ray Propagation)
到目前为止的讨论都假定射线是在真空中传播的。例如,当描述来自一个点源的光的分布时,我们假设光的功率均匀地分布在以光为中心的球体表面上,而不会沿着这个方向减少。参与媒介的存在,如烟雾、雾或灰尘,可以使这种假设无效。模拟这些效果很重要:即使我们没有渲染一个充满烟雾的房间,几乎所有的室外场景都受到参与媒体的影响。例如,地球的大气层使得较远的物体看起来不那么饱和(图)。
![](https://i-blog.csdnimg.cn/blog_migrate/5b18f52f1a273b61079259bcf710c8e4.png)
介质可以通过两种方式影响沿光线传播的光。首先,介质可以通过吸收或向不同方向散射来熄灭(或减弱)光。我们可以通过计算射线原点和交点之间的透射率T来捕捉这种效应。透过率告诉我们在交点散射的光有多少会回到射线原点
参与的介质也可以增加传递的光线。这种情况可能发生在介质发出光(如火焰)或介质沿光线散射其他方向的光(图1.10)。我们可以通过计算体积光传输方程来得到这个量,就像我们计算光传输方程来得到从表面反射的光量一样。就目前而言,我们可以计算参与媒介的效果,并将其效果与射线所携带的光量相结合。
![](https://i-blog.csdnimg.cn/blog_migrate/16c4b4be2cc6af77a406808d7c0985a0.png)