GAMES101-12&13:Whitted-Style 光线追踪(1)

前言

GAMES101-12:光栅化下的处理思路:阴影映射、软阴影

GAMES101-13:Whitted-Style 光线追踪与求交问题、AABB 包围盒

光栅化下的阴影处理:阴影映射(Shadow Mapping )

着色是一种局部现象,不考虑整体因此处理不了阴影,为此,人们发明了 Shadow Mapping。

Shadow Mapping 的思路:一个点不在阴影含义是,这个点必须同时被光源和摄像机看到。

步骤:

  1. 从光源做一次光栅化,记录光源看到的点的深度信息。(不用进行着色)
  2. 从摄像机做一次光栅化,对每个点投影回去,如果和“从光源看”的深度指向的点不一致,那么说明这个点在阴影里,否则不在阴影里。

Shadow Mapping 的特点:

  • 不需要知道场景的几何信息;
  • 阴影会产生走样现象:光源处分辨率的限制;
  • 阴影带来巨大开销;
  • 只能处理硬阴影:即要么是阴影,要么不是阴影的情况;
  • 只能处理点光源
  • 浮点数对比有的时候有很多脏数据;

光栅化下也有一些软阴影处理方案,此处不加以介绍。通常都比较麻烦而且不一定准确。

软阴影

软阴影即介于阴影和无阴影之间的的边界是软边界,模糊过渡的一种阴影。产生这种现象的原因是光源本身有不可忽略的大小,即非点光源。

一个例子是日食下的日月,光源太阳不是点光源。如果地球上一地区完全接收不到太阳光,那么这个地方就在月亮的硬阴影里;如果太阳被月亮挡住了部分,那么就是月亮的软阴影部分;否则,完全不被挡住,无阴影。

Whitted-Style 光线追踪

光栅化通常都是快速且近似的方法,光线追踪通常都比较慢。

光线追踪对光线的约束(尽管这些在物理学中不一定正确)

  • 光沿直线传播;
  • 光线之间不相互碰撞;
  • 光从光源出发,抵达人的眼睛,并且光路可逆;

光线投射

  1. 从眼睛(一个点)发出光线(eye ray)经过屏幕上一个像素打到物体表面得到一个交点,这个交点就是需要被着色的点(因此光线追踪不需要深度测试)。
  2. 如果光源发出的线(shadow ray)可以直接打到该点,就会有一次着色,否则结束。
  3. 这个点经过反射、折射(如果有)得到的二次交点们同样检查是否被 shadow ray 照亮。
  4. 把二次交点们发出的折射/反射的光(记为 second ray)对一次交点的着色结果累加到一次交点。
  5. 对二次交点当然也可以递归上述过程。

光线投射

求交点

光线是一个有起点的射线,我们如下定义

r(t)=o+td(0t<)r(t)=o+t\vec{d} (0\leq t<\infty)

其中向量 d 是单位向量表示方向。

对一个隐式几何表面 f(x,y,z)=0f(x,y,z)=0 求交就是说

f(r(t))=f(o+td)=0f(r(t))=f(o+t\vec{d})=0

当然多个交点时取最近的。

对于一个显式几何,最简单的办法是对每个三角形求交。思想如下:

  1. 首先求射线和三角形所在平面的交点;

    射线如上表示为 r(t)r(t),平面表示为点 pp' 和法线 N\vec{N} 的组合。就有 平面上一点表示为 (pp)N=0(p-p')\cdot\vec{N}=0,代入有

    (o+tdp)N=0(o+t\vec{d}-p')\cdot\vec{N}=0

    于是

    t=(po)NdN   (0t)t= \frac{(p'-o)\cdot\vec{N}}{\vec{d}\cdot\vec{N}} \ \ \ (0\leq t)

  2. 然后判断是否在三角形内。例如使用叉积

或直接应用 Moller Trumbore 算法:

用三角形的重心坐标有:

O+tD=(1b1b2)P0+b1P1+b2P2\vec{O}+t\vec{D}=(1-b_1-b_2)\vec{P_0}+b_1\vec{P_1}+b_2\vec{P_2}

其中 O\vec{O}N\vec{N}Pi\vec{P_i} 都是三个数的坐标,应用克莱默法则即可求解。
(1b1b2)(1-b_1-b_2)b1b_1b2b_2 都满足重心坐标系的要求(在 [0,1] 之间)那么就说明和三角形相交。

我们还可以

隐式三角形求交的优化算法:AABB 包围盒

现代模型往往有百千万级别的面数,如果依次按上述方法求交,无疑太慢了。对此的一种改进方法是包围盒:用一个简单图形(例如长方体)包围模型,如果和这个包围盒都无交点,那就不需要求和模型的交点。

如果将包围盒定义为三个方向的面都平行于一个轴面,那三个方向就都可以都简单记为一个 x/y/z 轴上区间的情况,这种包围盒就叫 AABB 包围盒(Axis-Aligned Bounding Box,轴对齐包围盒)。

AABB 包围盒的好处:

对于普通包围盒:

t=poNdNt=\frac{p'-o\cdot N}{d\cdot N}

对于轴对齐包围盒(以 x 轴为例):

t=pxoxdxt= \frac{p'_x-o_x}{d_x}

对每个轴上的对立面求进入的“时间”和离开的时间,中间的差即在两个面之间的时间。对三个对立面分别这样处理,并取交集,即 tenter=max(tin)t_{enter}=max(t_in)tleave=min(tout)t_{leave}=min(t_out),那么就能得到光线在 AABB 包围盒中滞留的时间。进行分析:

  1. tenter>0t_{enter}>0tleave>tentert_{leave}>t_{enter},正常地和 AABB 盒相交;
  2. tenter<0t_{enter}<0tleave>0t_{leave}>0,光源在 AABB 盒内,到处都相交;
  3. tleave<0t_{leave}<0 ,盒子在光源后面,没有实际的交点。

跳转

Home:GAMES101-1:课程总览与笔记导航

Prev:GAMES101-11&12:曲线与面

Next:GAMES101-14:Whitted-Style 光线追踪(2) 包围盒求交的速度优化