0%

光线追踪其一

光线追踪

光线追踪

游戏内的光线定义——光线追踪模拟的性质:

  • 光沿直线传播
  • 光线没有碰撞体
  • 光线从光源出发到达眼睛

光路:光源发出光线的同时,也可以让摄像机发出“感应光”检测到光线(光线的可逆性)

 

光线投射

1.从摄像机投射一条光线

2.将光线打到的点与光源进行连线,如果这个点被光源也能看到,则着色

类似深度缓存,这个交点的“深度”也会被记录

 

Whitted-Style光线追踪

光线折射——在任意一个交点,只要计算出折射方向,就可以继续传播

也就是模拟光线不断弹射的过程

pi8V5dO.png

pi8ZnkF.png

光源会将所有单个点吸收到的光相加,再反应到着色上。

 

Ray-Surface Interface

首先求光线表面的交点

首先光线定义如下:

pi8e2b6.png

那么方程出来了,也就是说在那物体方程与光线方程解方程就行了:

pi8eh5D.png

当然,游戏内的光线打入物体这个场景大部分都是在研究三角形

应用:判断点是否在物体内

和2D一样的,一个点射出任意射线,如果与封闭物体有奇数个交点,则在物体内,如果有偶数个交点,则在封闭物体外

那么现在开始设想如何让我们知道光线是不是打到物体上了——有一种思路是把物体的所有三角形分别和光线进行计算是否相交,然后取“最近”的点。

很显然实在太慢了。

那么先把问题缩小到三角形和光线求交,这个比较简单,有一个很好的方法:pi8mdsI.png

那就是转换成光线和三角形所在平面相交,然后再计算交点是不是在三角形内。

首先定义平面——中学知识,法线和固定点定义平面:

pi8m5wV.png

p为平面内任意点。

全部过程如下:

pi8mHW4.png

 

MT算法(Moller Trumbore算法)

立即计算出交点是否在三角形内

射线方程与三角形方程写成这个形式,其中三角形方程和重心坐标插值相关

pi8a3j0.png

未知数只有t、b1、b2,目的是计算出是否有解,有解则说明有交点

//解法过程todo

 

光线表面求交优化(加速)

 

包围盒

pi8nj3Q.png

如图所示——如果光线连包围盒都没碰到,那么里面更复杂的物体更不用算了

看起来很简单,但十分有效

所以还有什么理由不去学一下包围盒的原理呢?

 

最常见的包围盒——长方体,也可以叫轴对齐包围盒(AABB)

生成逻辑:AABB包围盒本质是x轴上的一段距离,y轴上的一段距离,z轴上的一段距离相切出来的长方体

 

光线与AABB

先看二维上的:

pi8K3d0.png

本质上还是先算光线与形成包围盒的大平面进行相交计算,然后对比不同的线段的交集,回到三维,方法如下:

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消掉)