光线追踪算法概览

本文翻译自Scratchapixel 3.0[1],是一个关于计算机图形学的系统性的学习教程。
如果有误,欢迎在评论区讨论。
翻译:iOS成长指北


由伊本·海塔姆描述的现象解释了我们看到物体的原因。基于他的观察,可以得出两点有趣的评论:首先,没有光,我们什么也看不见;其次,如果我们环境中没有物体,我们也看不到光。如果我们在星际空间旅行,这通常就会发生。如果我们周围没有物质,我们只能看到黑暗,即使光子潜在地穿过那个空间(当然,如果有光子,它们必须来自某个地方。如果你直接看它们,如果它们进入你的眼睛,你会看到它们反射或发射的物体的图像)。


正向追踪

光线追踪算法概览
图1:光源发射的无数光子撞击绿色球体,但只有一个光子会到达眼睛表面。

如果我们试图在计算机生成的图像中模拟光与物体的相互作用过程,那么还有另一个物理现象需要我们注意。相对于物体反射的光线总数,只有少数几条光线会到达我们眼睛的表面。举个例子,想象我们创建了一个只发射一束光子的光源。现在让我们看看这个光子会发生什么。它从光源发射出来,沿着直线路径行进,直到撞到我们物体的表面。忽略光子吸收,我们可以假设光子会以随机方向反射。如果光子撞到我们眼睛的表面,我们就会"看到"光子反射的点(图 1)。

你声称“照亮区域或物体上的每个点都会向每个方向辐射(反射)光线”。这难道不与“随机”相矛盾吗?

解释为什么光会在每个可能的方向上反射超出了本课程的范围(可以参考光物质相互作用课程获得完整的解释)。然而,简单回答你的问题:是和否。当然,在自然界中,真实的光子会被真实的表面以特定的方向反射(因此不是随机的),该方向由几何拓扑和光子在交点处的入射方向所定义。如果我们用肉眼观察一个漫反射物体的表面,它看起来很光滑。但是如果我们用显微镜观察它,我们会发现微观结构可能更加复杂和光滑。左侧的图像是不同放大比例下的纸张照片。光子非常小,微观特征和形状会反射在物体的表面上。如果一束光线照射在这个漫反射物体的表面上,光束内的光子将会撞击微观结构的不同部位,因此会以许多不同的方向反射。我们可以说,这些方向几乎涵盖了“每个可能的方向”。如果我们想要模拟光子和微观结构之间的相互作用,我们就会以随机方向发射光线,统计学上来说,这与它们被反射到每个可能的方向相同。

有时,材料在宏观层面上的结构会以特定的方向反射光线,这被描述为各向异性反射,并将在光材料相互作用课程中详细解释。材料的宏观结构也会导致不寻常的视觉效果,例如我们可以在蝴蝶的翅膀上观察到的虹彩效应。

光线追踪算法概览

现在我们可以从计算机图形学的角度来看待这种情况。首先,我们用由像素组成的图像平面代替我们的眼睛。在这种情况下,发射的光子将会撞击图像平面上的像素之一,将该点的亮度增加到大于零的值。这个过程会重复多次,直到所有像素都被调整,创建出一个计算机生成的图像。这种技术被称为「正向光线追踪」,因为我们从光源到观察者追踪光子的路径。

然而,你看到这种方法存在潜在问题吗?

问题如下:在我们的示例中,我们假设反射光子总是与眼睛表面相交。实际上,光线会以每个可能的方向反射,每个方向都有非常非常小的可能性击中眼睛。我们需要从光源投射无数光子,才能找到只有一个光子会击中眼睛的情况。这就是自然界中的工作方式,因为无数的光子以光速沿着所有方向传播。在计算机世界中,模拟许多光子与场景中的物体相互作用不是一个实际的解决方案,原因我们将在接下来的解释中说明。

你可能会想:“我们需要随机发送光子吗?既然我们知道眼睛的位置,为什么不只是将光子沿着那个方向发送,并查看它是否通过了图像中的像素?”这是一种可能的优化。但是,我们只能针对某些类型的材料使用这种方法。在后面关于光与物质相互作用的课程中,我们将解释方向性对于漫反射表面并不重要。这是因为击中漫反射表面的光子可以在以接触点处法线为中心的半球内的任何方向上反射。但是,假设表面是一面镜子并且没有漫反射特性。在这种情况下,光线只能反射成一个确切的方向,即镜像方向(我们稍后将学习如何计算)。对于这种类型的表面,如果光子应该遵循镜像方向,我们不能人为地改变光子的方向,这意味着这种解决方案可能更令人满意。

“ 眼睛只是一个点接收器,还是有一个表面积?即使接收面非常小,它仍然具有面积,因此比一个点更大。如果接收面积大于一个点,则表面肯定会接收到不止一个光线中的 1 个。

读者是正确的。眼睛不是点接收器,而是表面接收器,就像相机中的胶片或 CCD 一样。因为这个课程只是光线追踪算法的介绍,所以这个主题需要详细解释。相机和人眼都有一个透镜,将反射的光线聚焦在其后面的表面上。如果透镜的半径非常小(这在技术上不是这种情况),则从物体反射的光只能来自一个方向。这就是针孔相机的工作原理。我们将在相机课程中讨论它们。

“ 即使我们决定使用这种方法,只使用由漫反射物体组成的场景,我们仍然需要帮助。我们可以将从光源向场景中投射光子的过程可视化,就好像我们在物体表面喷洒光线(或小颗粒的颜料)。如果喷雾不够密集,则某些区域将无法均匀照亮。

想象一下试图用白色记号笔在黑色纸张上制作点来绘制茶壶(将每个点视为光子)。如下图所示,只有少数光子与茶壶物体相交,留下许多未覆盖的区域。随着点数的增加,光子的密度增加,直到茶壶“几乎”完全被光子覆盖,使物体更容易识别。

光线追踪算法概览

但是,即使发射 1000 个光子,甚至是 X 倍以上,也不能保证我们的物体表面被光子覆盖。这是这种技术的一个重大缺点。换句话说,我们必须让程序运行,直到我们决定它已经向物体表面喷洒足够的光子才能得到准确的表示。这意味着我们必须观察图像在被渲染时决定何时停止应用程序。在生产环境中,这是不可能的。正如我们将看到的,光线跟踪器中最昂贵的任务是找到光线和几何体的交点。从光源创建许多光子不是问题,但在场景中找到它们的所有会议将是难以承受的昂贵的。

结论:「正向光线跟踪」(或因为我们从光源发射光线而称为「光线跟踪」)使得在计算机上模拟光线如何在自然中传播成为技术上可能。然而,如上所述,这种方法可能更有效和实用。在 1980 年发表的一篇名为“用于阴影显示的改进照明模型”的开创性论文中,图形学早期研究者之一的 Turner Whitted 写道:

❝在一种明显的光线跟踪方法中,从光源发出的光线沿其路径追踪,直到它们击中观察者。由于只有少数光线会到达观察者,因此这种方法可能更好。在 Appel 提出的第二种方法中,光线沿相反的方向从观察者到场景中的物体追踪。❞

现在,我们将看看 Whitted 谈到的另一种模式。


反向追踪

光线追踪算法概览
图2:反向光线跟踪。我们从眼睛到球体上的一个点跟踪一条光线,然后从该点到光源跟踪一条光线。

我们不是从光源到接收器(如我们的眼睛)追踪光线,而是从接收器到物体反向追踪光线。因为这个方向与自然界中的光线传播方向相反,所以被称为「反向光线追踪」或「眼睛追踪」,因为我们从眼睛的位置射出光线(图 2)。这种方法提供了一种方便的解决方案,以弥补前向光线追踪的缺陷。由于我们的模拟不能像自然界一样快速和完美,因此我们必须妥协,从眼睛射入场景中的光线。如果光线击中一个物体,我们通过从击中点向场景中的光源投射另一条光线(称为光线或阴影光线)来确定它接收到多少光。偶尔,这个“光线”会被场景中的另一个物体遮挡,这意味着我们最初的击中点在阴影中,它不会从光源接收任何照明。因此,我们不将这些光线称为光线,而是称为「阴影光线」。在 CG 文献中,我们从眼睛(或相机)射入场景中的第一条光线称为「主光线」、「可见性光线」或「相机光线」。

❝在本课程中,我们使用前向追踪来描述从光源发射光线的情况,与反向追踪相反,其中从相机射出光线。然而,一些作者使用相反的术语。前向追踪意味着从相机射出光线,因为它是 CG 中最常用的路径追踪技术。为避免混淆,你也可以使用更明确的术语光线追踪和眼睛追踪。这些术语更常用于双向路径追踪的上下文中(请参见光传输部分)。❞


结论

在计算机图形学中,从光源或从眼睛射出光线的概念被称为「路径追踪」。也可以使用光线追踪这个术语,但是路径追踪的概念表明,这种制作计算机生成图像的方法依赖于从光源到相机(或相反)的路径。通过以物理上真实的方式这样做,我们可以轻松模拟光学效应,例如焦散或场景中另一个表面反射的光线(间接照明)。这些主题将在其他课程中讨论。



本文转自:iOS成长指北,转载此文目的在于传递更多信息,版权归原作者所有。

最新文章