光线追踪
游戏内的光线定义——光线追踪模拟的性质:
- 光沿直线传播
- 光线没有碰撞体
- 光线从光源出发到达眼睛
光路:光源发出光线的同时,也可以让摄像机发出“感应光”检测到光线(光线的可逆性)
光线投射
1.从摄像机投射一条光线
2.将光线打到的点与光源进行连线,如果这个点被光源也能看到,则着色
类似深度缓存,这个交点的“深度”也会被记录
Whitted-Style光线追踪
光线折射——在任意一个交点,只要计算出折射方向,就可以继续传播
也就是模拟光线不断弹射的过程
光源会将所有单个点吸收到的光相加,再反应到着色上。
Ray-Surface Interface
首先求光线表面的交点
首先光线定义如下:
那么方程出来了,也就是说在那物体方程与光线方程解方程就行了:
当然,游戏内的光线打入物体这个场景大部分都是在研究三角形
应用:判断点是否在物体内
和2D一样的,一个点射出任意射线,如果与封闭物体有奇数个交点,则在物体内,如果有偶数个交点,则在封闭物体外
那么现在开始设想如何让我们知道光线是不是打到物体上了——有一种思路是把物体的所有三角形分别和光线进行计算是否相交,然后取“最近”的点。
很显然实在太慢了。
那么先把问题缩小到三角形和光线求交,这个比较简单,有一个很好的方法:
那就是转换成光线和三角形所在平面相交,然后再计算交点是不是在三角形内。
首先定义平面——中学知识,法线和固定点定义平面:
p为平面内任意点。
全部过程如下:
MT算法(Moller Trumbore算法)
立即计算出交点是否在三角形内
射线方程与三角形方程写成这个形式,其中三角形方程和重心坐标插值相关
未知数只有t、b1、b2,目的是计算出是否有解,有解则说明有交点
//解法过程todo
光线表面求交优化(加速)
包围盒
如图所示——如果光线连包围盒都没碰到,那么里面更复杂的物体更不用算了
看起来很简单,但十分有效
所以还有什么理由不去学一下包围盒的原理呢?
最常见的包围盒——长方体,也可以叫轴对齐包围盒(AABB)
生成逻辑:AABB包围盒本质是x轴上的一段距离,y轴上的一段距离,z轴上的一段距离相切出来的长方体
光线与AABB
先看二维上的:
本质上还是先算光线与形成包围盒的大平面进行相交计算,然后对比不同的线段的交集,回到三维,方法如下:
1.当光线进入三个对面的所有空间,说明进入盒子了
2.当光线跳出任意一个对面,说明退出盒子了
然后记录进入和退出的时间t(enter)=max{t(min)},t(exit)=min{t(max)}.
t(min)与t(max)意思是单对对面的进入时间与退出时间
判断条件:t(enter)<t(exit)说明光线在盒子里面待了一段时间
问题考虑
上面都是正常在里面的情况,如果t<0这种情况出现怎么办
如果t(exit)<0说明盒子在关线背后!
如果t(exit)>=0&&t(enter)<0说明光线起点在盒子里面!
如果t(enter)<t(exit)&&t(exit)>=0说明光线穿过了盒子!
Q:为什么用AABB
A:算起来简单——如果光线出现和某一个平面平行的情况(可以把N消掉)