Lecture 13: Ray Tracing 1(Whitted-Style Ray Tracing)¶
光线追踪(Ray Tracing)是一种通过模拟光线传播路径来生成图像的技术。它通过追踪光线与场景中物体的交互,计算光线的反射、折射和阴影,从而生成逼真的图像。可以更好地处理软阴影、Glossy Reflection(模糊反射)和间接光照等效果。
光线追踪准确,但计算量大,通常用于电影制作和高质量渲染。
Whitted-Style Ray Tracing¶
光的三个假设:光线是直线传播的,光线之间不会发生碰撞,光线从光源发出并最终到达眼睛(也可以反过来考虑)。
对于摄像机来说,我们认为摄像机是一个针眼摄像机模型。从摄像机出发,对每个像素发射一条射线,追踪其与场景中物体的交互,判断射线碰到的第一个物体的交点处是否被光源照亮,从而决定这个位置的光照情况。
以上只是最简单的光线追踪方法。Whitted-Style Ray Tracing在此基础上增加了对反射和折射的处理。
Whitted-Style Ray Tracing考虑了光线的反射和折射现象,支持光线的多次反弹和穿透,从而生成更逼真的图像。其基本流程如下:
- 从摄像机出发,对每个像素发射一条主射线(Primary Ray)。
- 计算主射线与场景中物体的交点,找到最近的交点。
- 在交点处计算局部光照,包括环境光、漫反射和镜面反射。
- 如果材质具有反射属性,计算反射射线(Reflection Ray),
- 如果材质具有折射属性,计算折射射线(Refraction Ray)。
- 递归地追踪反射和折射射线,累积它们的光照贡献。
- 重复以上步骤,直到达到最大递归深度或光线强度低于阈值。将所有光照贡献累积,得到最终像素颜色。
Ray-Surface Intersection¶
射线由起点和方向定义,表示为:
对于不同的几何体,求解射线与其表面的交点的方法不同。
对于球,假设球心为C,半径为r,射线起点为O,方向为D,则交点满足:
更泛用地,对于隐式表达的曲面,满足\(f(p) = 0\),将射线方程代入,解方程\(f(\text{Ray}(t)) = 0\),即\(f(\text{Origin} + t \cdot \text{Direction}) = 0\),求解t。
对于显式表达的曲面,如三角形网格,注意到三角形位于平面上,先求解射线与平面的交点,然后判断该交点是否在三角形内。可以使用重心坐标法(Barycentric Coordinates)来判断。
那么如何计算平面与射线的交点呢?假设平面由点P0和法向量N定义,射线由起点O和方向D定义,交点满足:
有一种更快的做法,即Möller–Trumbore算法,直接在三角形上计算交点,避免了计算平面方程。其基本思想是使用重心坐标系表示三角形内的点,并通过解线性方程组来找到交点。
公式如下:
\(\vec{O} + t\vec{D} = (1-b_1-b_2)\vec{P_0} + b_1\vec{P_1} + b_2\vec{P_2}\)
其中:
- \(\vec{E_1} = \vec{P_1} - \vec{P_0}\)
- \(\vec{E_2} = \vec{P_2} - \vec{P_0}\)
- \(\vec{S} = \vec{O} - \vec{P_0}\)
- \(\vec{S_1} = \vec{D} \times \vec{E_2}\)
- \(\vec{S_2} = \vec{S} \times \vec{E_1}\)
Accelerating Ray-Surface Intersection¶
在复杂场景中,直接计算每条射线与所有物体的交点会非常耗时。为了提高效率,可以使用空间划分技术,如包围盒层次结构(Bounding Volume Hierarchy, BVH)或八叉树(Octree),来加速射线与场景的交互计算。
Bounding Volume¶
包围盒(Bounding Volume)是一种简单的几何体,用于包围复杂的物体,从而简化碰撞检测和射线交点计算,如轴对齐包围盒(Axis-Aligned Bounding Box, AABB)和包围球(Bounding Sphere)。轴对齐包围盒是与坐标轴对齐的矩形盒子,定义为两个对角点。包围球是一个球体,定义为中心点和半径。
对于AABB,假设盒子由最小点\(B_{min}\)和最大点\(B_{max}\)定义,射线与AABB的交点可以通过计算射线与盒子各个面的交点来确定。
具体方法是计算射线在每个轴上的进入和离开时间,然后取最大进入时间和最小离开时间,如果最大进入时间小于最小离开时间,则射线与AABB相交。
即:
如果\(t_{enter} \leq t_{exit}\)且\(t_{exit} \geq 0\),则射线与AABB相交。
对每个轴上的进入和离开时间的计算如下:
其他轴类似。
如果\(t_{exit} < 0\),表示交点在射线起点的后方,不考虑。如果\(t_{enter} < 0且t_{exit} \geq 0\),表示射线起点在AABB内部,交点为\(t_{exit}\)。