光线追踪
在光线追踪中,假设相机是个点而不是个矩形。
然后将每个像素和相机相连并延长这条线,作为光线,这条线被称为“眼睛光线”。
这根光线会和场景中的物体相交,记录下最近的交点。
将交点与光源相连,判断能否被光源直接照到。
使用着色器进行着色,写入该像素点的颜色值。

Whitted风格光线追踪
当光线与物体相交时,计算该光线的反射光、折射光。同时不断递归反射光、折射光,计算每一个反射光、折射光与场景的交点、产生的反射光、折射光,并与光源相连,判断是否能被光源直接照射到。然后使用着色器进行着色,并将最后将得到的所有颜色值相加。

光线与模型的交点
定义光线
对于任意一条光线,可以用[latex]r(t)=o+td (0 \le t < \infty [/latex]来表示。
其中r为光线,t为时间,o为光源,d为光线方向。

光线与球体的交点
球体p的定义[latex](p-c)^2-R^2=0[/latex]

将光线带入球体的公式中:[latex](o+td-c)^2-R^2=0[/latex]
[latex]a t^2+b t+c=0, \text { where }[/latex]
[latex]a=\mathbf{d} \cdot \mathbf{d}[/latex]
[latex]b=2(\mathbf{o}-\mathbf{c}) \cdot \mathbf{d}[/latex]
[latex]c=(\mathbf{o}-\mathbf{c}) \cdot(\mathbf{o}-\mathbf{c})-R^2[/latex]
[latex]t=\frac{-b \pm \sqrt{b^2-4 a c}}{2 a}[/latex]
利用△可知与球体的交点个数,用求根公式即可得出交点

光线与隐式表面的交点
定义隐式表面p:[latex]f(p)=0[/latex]
将光线带入公式[latex]f(o+td)=0[/latex]
解出方程的根即可
光线与显式表面的交点
求光线与显式表面的交点,即为求光线与三角形求交点。
定义平面:
定义平面的法线N,再定义平面上任意一点[latex]p^{\prime}[/latex],如果有一点在平面内,这个点与p'的连线与法线垂直。

即平面p: [latex](p-p') \cdot N=0[/latex]
令[latex]p=r(t)[/latex]
[latex]\left(\mathbf{p}-\mathbf{p}^{\prime}\right) \cdot \mathbf{N}=\left(\mathbf{o}+t \mathbf{d}-\mathbf{p}^{\prime}\right) \cdot \mathbf{N}=0[/latex]
即可求出t:
[latex]t=\frac{\left(\mathbf{p}^{\prime}-\mathbf{o}\right) \cdot \mathbf{N}}{\mathbf{d} \cdot \mathbf{N}}[/latex]
[latex]0 \leq t<\infty[/latex]
Möller Trumbore算法
该算法可以快速求出光线在三角形内的交点。
如果光线与平面的交点在三角形内,那这一点也就能够用重心坐标表示,即:
[latex]\overrightarrow{\mathbf{O}}+t \overrightarrow{\mathbf{D}}=\left(1-b_1-b_2\right) \overrightarrow{\mathbf{P}}_0+b_1 \overrightarrow{\mathbf{P}}_1+b_2 \overrightarrow{\mathbf{P}}_2[/latex]
令:
[latex]\begin{aligned}
& \overrightarrow{\mathbf{E}}_1=\overrightarrow{\mathbf{P}}_1-\overrightarrow{\mathbf{P}}_0 \\
& \overrightarrow{\mathbf{E}}_2=\overrightarrow{\mathbf{P}}_2-\overrightarrow{\mathbf{P}}_0 \\
& \overrightarrow{\mathbf{S}}=\overrightarrow{\mathbf{O}}-\overrightarrow{\mathbf{P}}_0 \\
& \overrightarrow{\mathbf{S}}_1=\overrightarrow{\mathbf{D}} \times \overrightarrow{\mathbf{E}}_2 \\
& \overrightarrow{\mathbf{S}}_2=\overrightarrow{\mathbf{S}} \times \overrightarrow{\mathbf{E}}_1
\end{aligned}[/latex]
利用Cramer 法则:
[latex]\left[\begin{array}{l}
t \\
b_1 \\
b_2
\end{array}\right]=\frac{1}{\overrightarrow{\mathbf{S}}_1 \cdot \overrightarrow{\mathbf{E}}_1}\left[\begin{array}{c}
\overrightarrow{\mathbf{S}}_2 \cdot \overrightarrow{\mathbf{E}}_2 \\
\overrightarrow{\mathbf{S}}_1 \cdot \overrightarrow{\mathbf{S}} \\
\overrightarrow{\mathbf{S}}_2 \cdot \overrightarrow{\mathbf{D}}
\end{array}\right][/latex]
即可求出上述方程的解,其算力开销非常低。
加速算法
包围盒
使用包围盒将每一个模型包围起来,如果光线与包围盒相交,才计算光线和包围盒内模型的每个三角形是否相交。
将包围和理解为3组对面形成的交集:

轴对齐包围盒AABB
Axis-Aligned Bounding Box,每个面都和坐标轴的面平行。
在二维中,判断一个长方形和一条直线是否有交集,可以先求出其和线x0,x1的两个交点,再求出和线y0,y1的两个交点

因为当光线进入到所有的面,才能确定光进入到包围盒中,而当光线离开任意一个面,即为离开包围盒。所以求出其中最大的[latex]t_{min}[/latex]和最小的[latex]t_{max}[/latex]即为光线实际进入和离开盒子的时间。

即[latex]t_{enter}=max(t_{min}),t_{exit}=min(t_{max})[/latex]。在三维空间中同理。
如果[latex]t_{enter}<t_{exit}[/latex],即为光线经过了包围盒(光线在包围盒中待了一段时间)。
但是光线是射线,不是直线,所以当[latex]t_{exit}<0[/latex],说明物体在光线的背后,即不可能有交点。
当[latex]t_{exit}>=0,t_{enter}<0[/latex],即光线的起点在包围盒内部。
所以当且仅当[latex]t_{enter}<t_{exit},t_{exit}\ge0[/latex]时,光线穿过包围盒。
计算光线与面何时相交:
[latex]t=\frac{\left(\mathbf{p}^{\prime}-\mathbf{o}\right) \cdot \mathbf{N}}{\mathbf{d} \cdot \mathbf{N}}[/latex]
而这里的面是与坐标轴平面平行的,所以可以简化运算:
对于yz平面平行,即为垂直于x轴:
[latex]t=\frac{\mathbf{p}_x^{\prime}-\mathbf{o}_x}{\mathbf{d}_x}[/latex]
Comments | NOTHING