概述
games101_Ray Tracing1——Whitted-Style Ray Tracing
- 为什么需要光线追踪?
- Basic Ray-Tracing Algorithm(基础的光线追踪算法)
- Light Rays(光线)
- Ray Casting(光线投射)
- Generating Eye Rays(生成摄像机射线)
- Recursive (Whitted-Style) Ray Tracing(递归光线追踪)
- 原理
- Ray-Surface Intersection(光线与面的交点)
- Ray Equation(射线定义)
- Ray Intersection with Sphere(射线和球的交点)
- Ray Intersection With Implicit Surface(光线和隐式面的交点)
- Ray Intersection With Triangle Mesh(光线和三角形网格的交点)
- Plane Equation(平面定义)
- Möller Trumbore Algorithm(MT算法)
- Accelerating Ray-Surface Intersection(加速光线和平面求交点)
- Bounding Volumes(包围盒)
- Ray-Intersection With Box(射线和包围盒的交点)
- Ray Intersection with Axis-Aligned Box(光线和轴对齐包围盒的交点)
- 如何判断光线是否通过包围盒
- 为什么使用轴对齐?
为什么需要光线追踪?
- 光栅化并不能很好地处理全局的效果
- 实现(软)阴影
- 光线不止弹射一次(如下图图3)
光栅化在处理上面两种情况都不是很好,所以这时候需要采用光线追踪技术。
-
光栅化效果很快,但是质量相对低。
可以看到下图是只开了光栅化的效果,地面没有阴影,地面石头的模型细节程度也非常地低,纹理也看不太清楚。这是一种很原始的模型渲染的结果。
-
光线追踪很精确,但是速度非常慢。
- 光栅化:实时, 光线追踪:离线
- 光线追踪在产品中一帧需要花费一万个CPU小时去渲染,这也意味着这种情况对设备的要求很高,是将程序写好之后,花费大量的时间运行出来。
Basic Ray-Tracing Algorithm(基础的光线追踪算法)
Light Rays(光线)
三个关于光线的想法:
- 我们认为光线是沿着直线传播的(虽然在物理上来看是错的)
- 当几束光线交叉时,并不会产生碰撞(虽然在物理上看是错误的)
- 光线是从光源传播到人眼的,但是在反转的情况下也是相同的,即从人眼传播到光源(reciprocity光线的可逆性)。
正常来说,人眼能够看到物体,是因为有光线进入了人的眼中,但是光的可逆性我们可以理解为人眼发出“感知光线”的路径和光线的传播路径是相同的,即光路的可逆性。我们就是利用光路的可逆性,从人眼出发,对光线进行追踪。
下图这个理论在现实生活中虽然是错的,但是在光路的可逆性下,是可以那么理解的,也是光线追踪的意思。
Ray Casting(光线投射)
平面是物体的投影平面,后面是实际的物体。光线的投射的过程:假设我们目前在往一个虚拟的世界看,我们是透过投影上面的投影的屏幕向虚拟世界中看,投影的平面被我们分成了由许多个像素组成。
- 我们先从人眼放出“感知光线”,放出的光线透过投影平面上的一个像素投射到虚拟世界的物体上的某一点
- 然后再从这一点向光源发出一条光线,检查该点是否在光照的范围内。
上面这一个过程就是利用光路的可逆性,正常是从光源到物体到人眼,而颠倒这个过程,就能够对光线进行追踪。
Generating Eye Rays(生成摄像机射线)
假设下图的情况是:
- 对于场景中的物体,我们认为,如果光线打到他身上之后,会产生完美的反射或折射现象。
- 人眼或者说摄像机是看作一个针孔摄像机,而不考虑人眼本身的大小。
- 光源认为是点光源。
上图从人眼中发射出一条射线,射线发射到离它最近的一个点上,但是按道理来说,其实还可以继续发射到后面的物体上,但是我们只记录距离他最近的一个点的数据,这也是为了节省时间和资源,其实已经完美解决了深度测试的问题。
在前面光栅化进行深度测试时,需要维护一个深度缓存来记录每个像素所对应的最小深度,通过这种光线追踪的方式,找到最近的焦点就可以不用在记录深度了,怎么做后面再说。
所以最近的交点会这遮挡住别的点。
所以不考虑上述那种情况,如下图:
处理人眼发射射线,光源也会发射射线,如果光源与物体的那个点中间没有任何其他物体进行遮挡,就知道光源可以照亮这个点,如果有东西挡着,这个点就是在阴影里。
同时有了交点,自然也知道法线方向,所以有了法线,入射方向和出射方向,我们就可以算这一点的着色,着色结果算出来后,就能将这一点结果写入像素的值。
通过这种方法能够获得和光栅化近似相同的结果。但在这里光线只弹射了一次。
Recursive (Whitted-Style) Ray Tracing(递归光线追踪)
如上图Whitted样式的光线追踪的着色效果。两个球分别实现了折射和反射,阴影的程度也不相同,在这个方法中就计算了光线的多次弹射。
原理
下面是Recursive Ray Tracing原理:
-
人眼发出射线,假设球体是玻璃的材质,所以第一条射线应该在球体上做一个镜面反射(假设都是完美反射和折射)。反射后的光线打在了三角形上。
-
同时它还可以折射进玻璃球内部,打到球内部的另一个点再折射出来。最后折射出来的光线打到了四方体上。
-
在这里由于光线弹射的次数多了,在每一个弹射的点都会去计算它着色的值。并且这条射线在场景中的折射反射点,所有算出来的着色的值都会被加到这个人眼发出射线的像素的值,即将四个点的着色相加,就得到了一开始“感知光线”透过的像素的着色效果。
-
可以看见最后所有结果的值(应该需要考虑各个点所占的比重) 都需要加到image plane的一个像素(像素为灰色的) 上去。
-
可以看出下图,有个阴影比较暗,有个阴影比较淡。
Ray-Surface Intersection(光线与面的交点)
Ray Equation(射线定义)
射线被定义为从起点开始并且是有方向的向量。
公式定义:
上面的表示的是,在时间t时,光线的所到达的位置。t = 0时,光线还未出发,此时的光线是一个点,t = 1时,光线从原点出发,经过单位时间到达了o + d的位置,o和o + d两个点的连线,就是此时的光线。
Ray Intersection with Sphere(射线和球的交点)
- 第一个公式为光线的公式
- 第二个公式则是球面的隐式表示公式。球面上的一个点与该球的半径长度是一致的。
在数学中求一条线和一个面的交点时,只要令上面的两个式子相等,求得的解就是线和面的交点。
什么是交点?
交点p必须同时满足射线公式和球体公式。也就是p点又在射线上,又在球面上。
所以光线和球面的交点的求法也是将两个等式相等求解,经过化简,就可以得到下面的式子:
所以剩下的问题就是 t 的求解,求解公式如下,这里的at^2 + bt + c = 0是上面公式化简之后的简写,具体a,b,c都代表什么都写在了下面这张图中:
二次方程的根有三种情况,分别是0、1、2个根,所以不同的根数量对应的不同的交点情况如下:
Ray Intersection With Implicit Surface(光线和隐式面的交点)
就像上面讲解的隐式表面,隐式曲面是使用一个等式来表示:
同样的射线公式:
两个公式合并后,得到如下图所示,但对t有要求:
- 解出来的t要求要是实数(物理上有意义)
- 并且是正数(因为是射线,t一定大于等于零)
带入到不同的复杂的隐式模型表面公式中,得到如下所示:
Ray Intersection With Triangle Mesh(光线和三角形网格的交点)
隐式表达的曲面通过上述方法就可以求解,那么显示表达曲面该怎么办?就是通过求光线和三角形的交点。
通过光线和三角形求交点,甚至能判断一个点在物体外还是物体内。比如有一个物体,有一个点,从这个点发出一条光线,光线是一条射线:
- 如果点在物体内,那么光线和物体的交点一定是奇数个。
- 如果在外,则是偶数个。
- 前提是这个物体是封闭的。
那么如何求光线和三角形的交点?
- 最简单的做法:让每一个三角形都和光线求交点,最后取最近的交点。
- 简单的做法虽然简单,但是速度很慢。
三角形是处于一个平面内的,所以求光线和三角形的交点可以分解成两个问题:
- 光线和平面求交点
- 判定交点是否在三角形内
所以接下来是要求光线和平面的交点,首先需要让“平面”有个明确的定义。
Plane Equation(平面定义)
平面被定义为一个方向和一个点。
平面一定会有一个法线,但是如果只有一条法线却不够我们定义一个平面。
像定义一个平面,给平面一个任意一个点,再给这个平面一个法线,两个条件都满足,才能定义一个平面。
下面定义平面的公式:
平面上的任何一个点p构成的向量p’p和法向量N应该是垂直的。
p代表该平面上的任意一点,p‘代表平面上已知的一点,N代表法向量。然后将上面公式中各个点和向量展开,平面方程的一般表示形式为:
所以两个定义:射线定义和平面定义我们都知道了,可以推出光线和平面的交点公式和解:
当然,这里的t求出来的结果也要求是实数并且是正数。
求出了光线和平面的交点后,在判断这个点是否在三角形内,就可以完成求光线和三角形的交点问题。
但这种解法,还不够直接,人们发现了一种能更快求出光线和三角形的交点问题的算法——Möller Trumbore Algorithm。
Möller Trumbore Algorithm(MT算法)
该算法可以在判断是否相交的同时计算得到交点位置。
下面看这个公式,公式的左边是射线公式,右边是根据三角形的重心坐标求点。
可以看到等式右边的三个系数加起来是和为1。p0,p1,p2是三角形的三个顶点。
(1-b1-b2) + b1 + b2 = 1
只要(1-b1-b2)、b1、b2都为非负数就能定义这个点在三角形内。根据Gramer法则,解式子中的未知数:
Accelerating Ray-Surface Intersection(加速光线和平面求交点)
上面已经说明了如何求光线和三角形如何求交点,那回到之前的问题:怎么求光线和物体的交点?
之前提到的求光线与物体内的每个三角形求交点,再取距离最近的那个交点作为最后结果是最简单的,但是计算速度非常慢,针对这个缺点,后面人们有提出了一个新的方式加速这个问题的求解。
Bounding Volumes(包围盒)
包围盒的思想是:
- 使用一个立体的盒子,将物体完整的包围起来。
- 当光线入射的时候,先判断光线是否和包围盒有交点,如果和包围盒没有交点,那么光线和包围盒内部的物体一定没有交点,就可以不用再对这个内部物体上的每个三角形求交点;
- 如果光线和包围盒有交点,则下一步:求光线和内部物体的每一个三角形的交点。
这个概念虽然简单,但是非常有效。
Ray-Intersection With Box(射线和包围盒的交点)
我们通常认为长方体是一个立体图形,但在这里要将长方体(也就是包围盒)理解为三个不同的对面形成的交集。
一般认为的长方体:
在这里需要理解成:
如下图,前后面两个面认为是两个无限大的平面,这两个面形成一对面,这一对面会把中间的空间全部都给包含进去。
同理上下和左右:
在实际操作中,我们一般采用AABB(Axis-Aligned Bounding Box),即轴对齐包围盒。让形成的平面为xy、yz、xz平面,平行于坐标轴(xyz三条轴)。
Ray Intersection with Axis-Aligned Box(光线和轴对齐包围盒的交点)
在上面提到过,三维空间中,AABB是由三对相互垂直的平面所围成的,那么在2D的情况下,AABB就是由两对相互垂直的面所围成。
上图表示求光线和包围盒交点的过程:
- 图1(光线和垂直x轴平面的交点):求出光线在x = x0 和 x = x1上的交点,分别用t(min)和t(max)表示,代表光线最早和最晚通过在垂直x轴方向上的对面。
- 图2(光线和垂直y轴平面的交点):求出光线在y = y0 和 y = y1上的交点,分别用t(min)和t(max)表示,代表光线最早和最晚通过在垂直y轴方向上的对面。这里的t(min)是负数,但是没关系,这里先放着。
- 图3(最后的交点结果):求上面求出的两个光线进入时间和离开时间的交集。这个结果是图一和图2两条红色线段形成的交集。
如何判断光线是否通过包围盒
核心思想:
- 当光线和每一对平面都有交点时,才能说光线进入了包围盒。
- 当光线离开任一对平面时,光线也就离开了包围盒。
- 对于每一对面(共有三组对面,xyz),计算他们的t(min)和t(max)。 (就算取值是负数也可以)
- 可以推导出,对于每一个3D包围盒:
- 如果 t(enter) < t(exit) 时,我们就知道,光线曾有一段时间是在盒子内部,也就是说光线和包围盒有交点。
下面要对时间的正负取值进行讨论:
- 如果 t(exit) < 0 —— 说明盒子在射线“后面”,该盒子与射线不相交。
- 如果 t(exit) >= 0 && t(enter) < 0 —— 说明射线的起点在盒子里,一定会有交点。
- 总结起来,如果光线和包围盒有交点,当且仅当下面的条件满足时成立:
- t(enter) < t(exit) && t(exit) >= 0
为什么使用轴对齐?
光线与横平竖直的面求交好求。只要当光线的某一分量等于某一个特定值的时候,就说明光线和这个轴对齐的平面有交点了。
最后
以上就是顺利鸵鸟为你收集整理的games101学习笔记_Ray Tracing1为什么需要光线追踪?Basic Ray-Tracing Algorithm(基础的光线追踪算法)Recursive (Whitted-Style) Ray Tracing(递归光线追踪)Ray-Surface Intersection(光线与面的交点)Ray Intersection with Sphere(射线和球的交点)Ray Intersection With Implicit Surface(光线和隐式面的交点)Ray Intersect的全部内容,希望文章能够帮你解决games101学习笔记_Ray Tracing1为什么需要光线追踪?Basic Ray-Tracing Algorithm(基础的光线追踪算法)Recursive (Whitted-Style) Ray Tracing(递归光线追踪)Ray-Surface Intersection(光线与面的交点)Ray Intersection with Sphere(射线和球的交点)Ray Intersection With Implicit Surface(光线和隐式面的交点)Ray Intersect所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复