赞
踩
光栅化在处理上面两种情况都不是很好,所以这时候需要采用光线追踪技术。
光栅化效果很快,但是质量相对低。
可以看到下图是只开了光栅化的效果,地面没有阴影,地面石头的模型细节程度也非常地低,纹理也看不太清楚。这是一种很原始的模型渲染的结果。
光线追踪很精确,但是速度非常慢。
三个关于光线的想法:
下图这个理论在现实生活中虽然是错的,但是在光路的可逆性下,是可以那么理解的,也是光线追踪的意思。
平面是物体的投影平面,后面是实际的物体。光线的投射的过程:假设我们目前在往一个虚拟的世界看,我们是透过投影上面的投影的屏幕向虚拟世界中看,投影的平面被我们分成了由许多个像素组成。
上面这一个过程就是利用光路的可逆性,正常是从光源到物体到人眼,而颠倒这个过程,就能够对光线进行追踪。
假设下图的情况是:
上图从人眼中发射出一条射线,射线发射到离它最近的一个点上,但是按道理来说,其实还可以继续发射到后面的物体上,但是我们只记录距离他最近的一个点的数据,这也是为了节省时间和资源,其实已经完美解决了深度测试的问题。
在前面光栅化进行深度测试时,需要维护一个深度缓存来记录每个像素所对应的最小深度,通过这种光线追踪的方式,找到最近的焦点就可以不用在记录深度了,怎么做后面再说。
所以最近的交点会这遮挡住别的点。
所以不考虑上述那种情况,如下图:
处理人眼发射射线,光源也会发射射线,如果光源与物体的那个点中间没有任何其他物体进行遮挡,就知道光源可以照亮这个点,如果有东西挡着,这个点就是在阴影里。
同时有了交点,自然也知道法线方向,所以有了法线,入射方向和出射方向,我们就可以算这一点的着色,着色结果算出来后,就能将这一点结果写入像素的值。
通过这种方法能够获得和光栅化近似相同的结果。但在这里光线只弹射了一次。
如上图Whitted样式的光线追踪的着色效果。两个球分别实现了折射和反射,阴影的程度也不相同,在这个方法中就计算了光线的多次弹射。
下面是Recursive Ray Tracing原理:
人眼发出射线,假设球体是玻璃的材质,所以第一条射线应该在球体上做一个镜面反射(假设都是完美反射和折射)。反射后的光线打在了三角形上。
同时它还可以折射进玻璃球内部,打到球内部的另一个点再折射出来。最后折射出来的光线打到了四方体上。
在这里由于光线弹射的次数多了,在每一个弹射的点都会去计算它着色的值。并且这条射线在场景中的折射反射点,所有算出来的着色的值都会被加到这个人眼发出射线的像素的值,即将四个点的着色相加,就得到了一开始“感知光线”透过的像素的着色效果。
可以看见最后所有结果的值(应该需要考虑各个点所占的比重) 都需要加到image plane的一个像素(像素为灰色的) 上去。
可以看出下图,有个阴影比较暗,有个阴影比较淡。
射线被定义为从起点开始并且是有方向的向量。
公式定义:
上面的表示的是,在时间t时,光线的所到达的位置。t = 0时,光线还未出发,此时的光线是一个点,t = 1时,光线从原点出发,经过单位时间到达了o + d的位置,o和o + d两个点的连线,就是此时的光线。
在数学中求一条线和一个面的交点时,只要令上面的两个式子相等,求得的解就是线和面的交点。
什么是交点?
交点p必须同时满足射线公式和球体公式。也就是p点又在射线上,又在球面上。
所以光线和球面的交点的求法也是将两个等式相等求解,经过化简,就可以得到下面的式子:
所以剩下的问题就是 t 的求解,求解公式如下,这里的at^2 + bt + c = 0是上面公式化简之后的简写,具体a,b,c都代表什么都写在了下面这张图中:
二次方程的根有三种情况,分别是0、1、2个根,所以不同的根数量对应的不同的交点情况如下:
就像上面讲解的隐式表面,隐式曲面是使用一个等式来表示:
同样的射线公式:
两个公式合并后,得到如下图所示,但对t有要求:
带入到不同的复杂的隐式模型表面公式中,得到如下所示:
隐式表达的曲面通过上述方法就可以求解,那么显示表达曲面该怎么办?就是通过求光线和三角形的交点。
通过光线和三角形求交点,甚至能判断一个点在物体外还是物体内。比如有一个物体,有一个点,从这个点发出一条光线,光线是一条射线:
那么如何求光线和三角形的交点?
三角形是处于一个平面内的,所以求光线和三角形的交点可以分解成两个问题:
所以接下来是要求光线和平面的交点,首先需要让“平面”有个明确的定义。
平面被定义为一个方向和一个点。
平面一定会有一个法线,但是如果只有一条法线却不够我们定义一个平面。
像定义一个平面,给平面一个任意一个点,再给这个平面一个法线,两个条件都满足,才能定义一个平面。
下面定义平面的公式:
平面上的任何一个点p构成的向量p’p和法向量N应该是垂直的。
p代表该平面上的任意一点,p‘代表平面上已知的一点,N代表法向量。然后将上面公式中各个点和向量展开,平面方程的一般表示形式为:
所以两个定义:射线定义和平面定义我们都知道了,可以推出光线和平面的交点公式和解:
当然,这里的t求出来的结果也要求是实数并且是正数。
求出了光线和平面的交点后,在判断这个点是否在三角形内,就可以完成求光线和三角形的交点问题。
但这种解法,还不够直接,人们发现了一种能更快求出光线和三角形的交点问题的算法——Möller Trumbore Algorithm。
该算法可以在判断是否相交的同时计算得到交点位置。
下面看这个公式,公式的左边是射线公式,右边是根据三角形的重心坐标求点。
可以看到等式右边的三个系数加起来是和为1。p0,p1,p2是三角形的三个顶点。
(1-b1-b2) + b1 + b2 = 1
只要(1-b1-b2)、b1、b2都为非负数就能定义这个点在三角形内。根据Gramer法则,解式子中的未知数:
上面已经说明了如何求光线和三角形如何求交点,那回到之前的问题:怎么求光线和物体的交点?
之前提到的求光线与物体内的每个三角形求交点,再取距离最近的那个交点作为最后结果是最简单的,但是计算速度非常慢,针对这个缺点,后面人们有提出了一个新的方式加速这个问题的求解。
包围盒的思想是:
这个概念虽然简单,但是非常有效。
我们通常认为长方体是一个立体图形,但在这里要将长方体(也就是包围盒)理解为三个不同的对面形成的交集。
一般认为的长方体:
在这里需要理解成:
如下图,前后面两个面认为是两个无限大的平面,这两个面形成一对面,这一对面会把中间的空间全部都给包含进去。
同理上下和左右:
在实际操作中,我们一般采用AABB(Axis-Aligned Bounding Box),即轴对齐包围盒。让形成的平面为xy、yz、xz平面,平行于坐标轴(xyz三条轴)。
在上面提到过,三维空间中,AABB是由三对相互垂直的平面所围成的,那么在2D的情况下,AABB就是由两对相互垂直的面所围成。
上图表示求光线和包围盒交点的过程:
核心思想:
下面要对时间的正负取值进行讨论:
光线与横平竖直的面求交好求。只要当光线的某一分量等于某一个特定值的时候,就说明光线和这个轴对齐的平面有交点了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。