使用光线追踪的原因
-
光栅化无法很好地处理全局效果
- 软阴影
- 光线产生多次反弹
-
光栅化处理速度快但质量相对较低
-
光线追踪处理精准,但速度较低
- 光栅化:实时渲染,光线追踪:离线渲染
- 在生产环境中渲染一帧往往需要~10kCPU核心时
光线
- 光线沿直线传播(虽然是错误的)
- 光线在相交时互不影响(虽然也是错的)
- 光线从光源传播到眼睛(且光路是可逆的)
Ray Casting
1968年由Appel提出
- 通过每个像素投射一条光线的方式来生成图像
- 通过向光源发送光线的方式来生成阴影
生成视角射线(Generating Eye Rays)
Pinhole Camera Model
着色像素(shading pixel)
递归式光线追踪(Recursive Ray Tracing)
Recursiv Ray Tracing 又名 Whitted-Style Ray Tracing 由T.Whitted在1980年提出
"An improved Illumination model for shaded display"
总体计算流程
射线表面相交计算(Ray-Surface Intersection)
在进行射线表面相交计算前我们需要了解射线方程(Ray Equation)
Ray Equation and Plane Equation
射线:由一个起点和一个方向向量定义
对应的射线方程(Ray Equation)为: $$r(t) = o +td , \ \ \ \ 0\leq t < 100 $$
r:沿射线的点
t:"时间"
o:起始点
d:归一化后的方向向量
平面:由一个法线向量和在平面上的点定义
对应的平面方程(Plane Equation)为: $$P:(p - p') * N = 0,\ \ \ ax+by+cz+d = 0$$
p:所有在平面上的点
p':在平面上的一个点
N:法线向量
射线与球体相交(Ray Intersection With Sphere)
射线:$r(t) = o +td , \ \ \ \ 0\leq t < 100 $
球体:$p:(p-c)^2 - R^2 = 0 $
当射线与球体相交时,交点$p$必须同时满足射线和球体的方程
此时的解为:
$$(o + td - c )^2 - R^2 = 0$$
射线与隐式曲面相交(Ray Intersection With Implict Surface)
射线:$r(t) = o +td , \ \ \ \ 0\leq t < 100 $
一般隐式曲面:$p:f(p) = 0$
代入后的替代射线方程:$f(o + td) = 0$
!解必须为正根
射线与三角形网格相交(Ray Intersection With Triangle Mesh)
原因:
- 渲染上:计算可见性,阴影,光照
- 几何上:判断内外关系
计算:拆分
- 最简单的方式:对每个三角形进行一次相交判断
- 最简单但速度最慢
- 可以出现0次相交或一次相交
射线与三角形相交(Ray Intersection With Triangle)
三角形可以视为在一个平面中
- 可视为射线与平面相交
- 判断相交点是否位于三角形内部即可
射线与平面相交(Ray Intersection With Plane)
射线方程:$r(t) = o +td , \ \ \ \ 0\leq t < 100 $
平面方程:$P:(p - p') * N = 0,\ \ \ ax+by+cz+d = 0$
相交的解为:
设$p = r(t)$求解$t(0\leq t < \infty)$
$(p-p') * N = (o + td - p') * N = 0$
$t = \frac{(p'-o) * N }{d * N}$
Möller Trumbore Algorithm
一种更快地得出重心坐标的算法
光线追踪的性能瓶颈
通过简单地计算光线与场景的相交的方式:
- 需要对场景中每一个三角形判断光线是否相交
- 找到最接近的交点(即最小的t值)
带来的问题:
- 算法复杂度 = $pixels \times triangles (\times bounces)$
- 计算耗时极高
解决办法:
- 采取遍历物体而非三角形的方式进行计算
- 采用相关加速结构/算法