Skip to content

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考虑了光线的反射和折射现象,支持光线的多次反弹和穿透,从而生成更逼真的图像。其基本流程如下:

  1. 从摄像机出发,对每个像素发射一条主射线(Primary Ray)。
  2. 计算主射线与场景中物体的交点,找到最近的交点。
  3. 在交点处计算局部光照,包括环境光、漫反射和镜面反射。
  4. 如果材质具有反射属性,计算反射射线(Reflection Ray),
  5. 如果材质具有折射属性,计算折射射线(Refraction Ray)。
  6. 递归地追踪反射和折射射线,累积它们的光照贡献。
  7. 重复以上步骤,直到达到最大递归深度或光线强度低于阈值。将所有光照贡献累积,得到最终像素颜色。

Ray-Surface Intersection

射线由起点和方向定义,表示为:

\[ \text{Ray}(t) = \text{Origin} + t \cdot \text{Direction}, \quad t \geq 0 \]

对于不同的几何体,求解射线与其表面的交点的方法不同。

对于球,假设球心为C,半径为r,射线起点为O,方向为D,则交点满足:

\[ \|\text{Ray}(t) - C\|^2 = r^2 \]

更泛用地,对于隐式表达的曲面,满足\(f(p) = 0\),将射线方程代入,解方程\(f(\text{Ray}(t)) = 0\),即\(f(\text{Origin} + t \cdot \text{Direction}) = 0\),求解t。

对于显式表达的曲面,如三角形网格,注意到三角形位于平面上,先求解射线与平面的交点,然后判断该交点是否在三角形内。可以使用重心坐标法(Barycentric Coordinates)来判断。

那么如何计算平面与射线的交点呢?假设平面由点P0和法向量N定义,射线由起点O和方向D定义,交点满足:

\[ N \cdot (\text{Ray}(t) - P_0) = 0 \]

有一种更快的做法,即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}\)

\[ \begin{bmatrix} t \\ b_1 \\ b_2 \end{bmatrix} = \frac{1}{\vec{S_1} \cdot \vec{E_1}} \begin{bmatrix} \vec{S_2} \cdot \vec{E_2} \\ \vec{S_1} \cdot \vec{S} \\ \vec{S_2} \cdot \vec{D} \end{bmatrix} \]

其中:

  • \(\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} = \max(t_{x_{enter}}, t_{y_{enter}}, t_{z_{enter}})\qquad t_{exit} = \min(t_{x_{exit}}, t_{y_{exit}}, t_{z_{exit}}) \]

如果\(t_{enter} \leq t_{exit}\)\(t_{exit} \geq 0\),则射线与AABB相交。

对每个轴上的进入和离开时间的计算如下:

\[ t_{x_{enter}} = \frac{B_{min,x} - O_x}{D_x}, \quad t_{x_{exit}} = \frac{B_{max,x} - O_x}{D_x} \]

其他轴类似。

如果\(t_{exit} < 0\),表示交点在射线起点的后方,不考虑。如果\(t_{enter} < 0且t_{exit} \geq 0\),表示射线起点在AABB内部,交点为\(t_{exit}\)