光线追踪
1.Shadow Mapping
光栅化的问题:不能很好地表示全局的效果
Shadow Mapping: 主要是为了解决点光源的硬阴影的问题
阴影区域:点对相机可见,而对光源不可见
Shadow Map记录每个pixel是否在阴影区域, 其生成步骤如下:
1.从光源位置出发找出可见点,记录光源可见点的深度,得到光源深度图。
2.从相机出发,找可见点,如果点可见,坐标变换求此点到光源的距离。如果此距离与光源深度图中此位置的深度一致,说明此点可以被光源照到,是为光源、相机能同时看到点;如果不一致,说明是阴影点。
硬阴影与软阴影:
软阴影的形成在于全影和半影的渐变,点光源不存在软阴影问题,出现软阴影一定是光源有大小、不同照射位置有全影和半影这种渐变。
2.Whitted-Styled Ray Tracing
光线追踪利用的就是光的可逆性
利用递归的方法进行光线追踪,对每条光线,递归计算其多个弹射点,当前光线所对应的像素值是由全部弹射点共同决定的:
光源的定义:起点+方向
于是,光线上的点可表示为:
3.光线求交点
3.1 隐式表面
隐式表面求交点:将光线上的一点代入隐式方程中求解
3.2 显式表面
显式表面求交点:用光线与三角形求交
光线与三角形求交:光线与平面求交+判断交点是否在三角形内
平面的定义:平面上一点+平面的法线
求解交点的过程:
Möller Trumbore Algorithm:三角形的一个点可以使用重心坐标表示
注:解上图的方程,若$(1-b_1,b_2)、b_1、b_2$为正数,则交点在三角形内部
4.计算的加速
每个光线与全部三角形都要进行求交点的计算,会导致计算开销过大,所以需要进行计算的加速。
包围盒方法:在物体外面包一个包围盒,如果光线与盒子都没交点,那跟物体里的所有面更不会有交集。
一般使用轴对齐包围盒(Axis-Aligned Bounding Box、AABB)
判断光线和包围盒是否有交点:通过计算光线进入/离开长方体的三个对面的时间可以判断出,光线和包围盒是否有交点
立方体有三个对面:
进入/离开对面的时间:
进入盒、离开盒的时间为:
注:光线进入了三个对面则认为光线进入了盒子,而光线离开了任意一个对面,就认为光线离开了盒子。
若$t{enter}<t{exit}且t_{exit}>=0$,则有交点
注:$t_{exit}$<0,表示盒在光源背后,没有交点
5.加速结构
5.1 均匀空间划分 Uniform Spatial Partitions (Grids)
判断光线交到的是不是含有物体表面的格子,如果不是的话跳过,是的话和其中的物体求交
注:该方法适合物体分布较均匀的场景
5.2 空间划分
- Oct-Tree:八叉树
- KD-Tree
- BSP-Tree
KD-Tree
注:
1.KD-Tree中一个物体可能存在多个格子中
2.KD-Tree要计算三角形与盒子的求交,这较为困难
5.3 物体划分(BVH)
步骤:
1.找到一个包围盒
2.递归地将物体拆成两个部分
3.两个部分重新计算包围盒
4.在每个叶子节点中记录实际的物体
注:划分规则:选择最长轴划分,以中间位置的物体进行划分