光线追踪
为什么引入光线追踪?
光栅化难以处理一些全局的效果,比如
- 软阴影
- 光滑物体的镜面反射
- 间接光照
光栅化效率高,但是质量差,通常用于实时的效果
光线追踪质量高,但是效率低,通常用于离线应用
光线追踪基于以下假设
- 光线沿直线传播(尽管这是假的)
- 光线之间不会发生碰撞(尽管这是假的)
- 光源发出光线传播到眼睛中(光线具有可逆性,可以逆向从相机发射光线打到物体上反射)
Whitted-Style光线追踪
光线从眼睛投射出去后可以通过反射、折射打到其他物体
每次折射反射都会有能量损失
与光源连接被遮挡的部分是阴影部分
光线的定义
用一个原点和一个方向就能表示一条光线
R a y : r ( t ) = o + t d 0 < = t < ∞ Ray: r(t) =o + td\space\space\space 0<=t<∞ Ray:r(t)=o+td 0<=t<∞
光线与物体交点的求解
与隐式表面的交点: 将 o + td 代入隐式方程,求解 t,取 t 较小的解。
与显式表面的交点:
简单方法:与每个三角形做判断,计算交点数。
图形学中,假定光线不会与三角面完美平行。
解法一:
平面上的任意一条直线,都与法线垂直,所以对于平面上的任意一点p
满足:
(
p
−
p
′
)
⋅
N
=
0
(p - p') · N = 0
(p−p′)⋅N=0
再与光线方程联合,便能求得光线与平面的交点,最后再判断点是否在三角形内部。
解法二:
三角形所在平面内的所有点都可以使用重心坐标的方式表示。
故求解下式即可:
o
+
t
d
=
(
1
−
b
1
−
b
2
)
P
0
+
b
1
P
1
+
b
2
P
2
o + td=(1-b_1-b_2)P_0+b_1P_1+b_2P_2
o+td=(1−b1−b2)P0+b1P1+b2P2
如何更快地求解?
使用一个包围盒将几何形体包裹,如果光线没有经过包围盒,则不用再去一个一个检查三角面。
通常使用轴对齐(AABB)包围盒
对于二维包围盒来说:
分别对x,y轴求
t
m
i
n
t
m
a
x
t_{min} t_{max}
tmintmax,取最大的
t
m
i
n
t_{min}
tmin和最小的
t
m
a
x
t_{max}
tmax
对于三维来说同理,只不过增加了一面
如果 t m i n < t m a x t_{min}<t_{max} tmin<tmax,说明光线进入了包围盒中
如果
t
e
x
i
t
<
0
t_{exit}<0
texit<0,说明包围盒在光线背后
如果
t
e
n
t
e
r
<
0
t_{enter}<0
tenter<0 且
t
e
x
i
t
>
=
0
t_{exit} >= 0
texit>=0,说明光源在包围盒内部
总结:当且仅当 t e n t e r < t e x i t t_{enter}<t_{exit} tenter<texit, t e x i t > = 0 t_{exit} >= 0 texit>=0 时,光线与包围盒有交点。
预处理
八叉树:
KD-Tree:每一次轮流选一维切分,是一颗二叉树
BSP-Tree:主要思想是二分,并不是横平竖直地切分,不适合AABB包围盒
BVH: 根据物体划分,避免了依据空间划分情况下在边界的物体被重复储存
查询伪代码:
Whitted-Style Ray Tracing的问题:
- 只能表示高光反射,无法渲染出Glossy效果。
- 在漫反射表面会停止弹射。
辐射度量学
Intensity:单位立体角的光线强度,不会随着距离衰减
Irradiance:某一个平面接收的光线强度,随着距离平方衰减
Radiance:单位面积往单位立体角辐射的能量密度
BRDF(双向反射分布函数)
针对单个输入源,描述了光线在不同方向上的能量分布情况
反射方程
针对某个着色点,积分所有输入源的BRDF,包括反射过来的光线
渲染方程
在反射方程的基础上加上物体本身辐射的能量