光线跟踪
# 光线跟踪
Owner: -QVQ-
算法步骤
对平面上每一个像素,执行如下操作:
第一步:
- 从视点出发通过该像素中心向场景发出一条光线,并求出该条光线与场景中物体的全部交点
- 将各交点沿光线方向排序,获得离视点最近交点
- 依据局部光照明模型计算该交点处的光亮度Ic,并赋值
第二步:
在P处沿着R镜面反射方向和透射方向各衍生一条光线(非镜面或不透明体,则无需这一步)
第三步:
分别对衍生出的光线递归地执行前面步骤,计算来自镜面反射和透射方向上周围环境对点P光亮度的贡献Is(镜面反射光)和It(投射光)
第四步:
依据Whitted光照明模型即可计算出点P处的光亮度,并赋值该像素
光线树
定义:
树的结点:代表物体表面与跟踪线的交点。
结点连线:代表跟踪线。
左儿子:代表反射产生的跟踪线(r),
右儿子:代表透射产生的跟踪线(t)。
空箭头:表示跟踪线射出场景。
遍历:该像素的光强是父节点加上所有孩子节点的合成,后序遍历调用光照模型访问光线树,算出跟踪射线方向的光强,并按两表面交点之间的距离进行衰减后,传递给父结点。
终止条件
- 光线与环境中任何物体均不相交,或交于纯漫射面
- 被跟踪光线返回的光亮度值对像素颜色的贡献很小
- 已递归到给定深度
伪代码
RayTrace(R, ratio, depth, color) //说明:光线跟踪子函数 { //1. 终止条件 if(终止条件2 || 终止条件3 || 终止条件1){ return; } 用局**部光照明模型**计算交点P处的**颜色值**,并将其存入local_color; //2. 计算反射光线 并递归 if(交点P所在的表面为光滑镜面) { 计算反射光线Rr; //递归调用! RayTrace(Rr, ks*ratio, depth+1, reflected_color); } //3. 计算透射光线 并递归 if(交点P所在的表面为透明表面) { 计算透射光线Rt; //递归调用! RayTrace(Rt, kt*ratio, depth+1,transmitted_color); } //4. 依照Whitted模型合成最终的颜色值 color = local_color + ks*reflected_color + kt*transmitted_color; return; } // 光线跟踪子函数RayTrace( )结束
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29光线跟踪的四类光线
- 从视点发出的
- 物体表明上的点向光源发出
- 从物体表面上的点沿镜面反射方向发出
- 从物体表面上的点沿透射方向发出
光线跟踪的优缺点
优点:
- 显示它不仅考虑到光源的光照,而且考虑到场景中各物体之间彼此反射的影响,因此显示效果逼真。
- 有消隐功能:采用光线跟踪方法,在显示的同时,自然完成消隐功能。
- 有影子效果:光线跟踪能完成影子的显示,
- 该算法具有并行性质:每条光线的处理过程相同,结果彼此独立,因此可以大并行处理的硬件上快速实现光线跟踪算法。
缺点:计算量非常大,速度极慢。
光线跟踪中包含阴影的phone模型
从P出发向光源L发射一条阴影测试光线R。若R在到达L的途中与场景中的物体不相加,则点P受光源L直接照射。反之,如果点P被位于它与光源L之间某一物体所遮挡,若遮挡物为不透明体,则点P位于光源阴影之中。
光线跟踪的加速技术
包围盒技术
将场景中的所有表面按其空间位置关系分层次组织成树状结构:
根结点:整个场景 中间结点:空间位置较为接近的一组表面 叶结点:单个景物表面
每一结点中的表面或表面片集合都用一形状简单的包围盒包裹起来,
当光线与包围盒有交时,才进行光线与其中所含的景物面片求交运算
常用的包围盒:
空间分割技术
将景物空间分割成一个个小的空间单元 被跟踪的光线仅与它所穿过空间单元中所含物体表面进行求交测试
利用相邻空间单元的空间连贯性,使光线快速跨越空单元,求得光线与景物的第一个交点