当前位置: 代码迷 >> 综合 >> 光线追踪Ray Tracing(1)(笔记)
  详细解决方案

光线追踪Ray Tracing(1)(笔记)

热度:40   发布时间:2023-11-27 07:52:05.0

文章目录

  • 前言
  • 一、光线追踪
      • 光线追踪概述
      • 光线(Light Rays)
      • 光线投射算法(Ray Casting)
  • 二、递归的(Whitted-Style)光线追踪算法(Recursive (Whitted-Style) Ray Tracing)
      • 递归光线追踪
      • 光线和隐式几何物体表面的交点
      • 光线和三角形网格的交点
      • Moller Trumbore Algorithm
  • 三、光线和表面求交的加速方法
      • 包围盒(Bounding Volumes)
      • 如何判断光线和包围盒有交点
      • 为什么要求轴对齐?
  • 课程的最后


前言

今天的内容是光线追踪中的Whitted-Style。


一、光线追踪

光线追踪概述

光线追踪,简单来说,根据光路可逆性,从摄像机发射光线去主动感知场景。
在这里插入图片描述
光栅化不能解决或者不能很好的解决一些问题,比如说一些全局的效果,软阴影,Glossy Reflection(类似于毛玻璃这样的反射),间接光照(Indirect Illumination 光线在抵达摄像机/人眼之前反射了多次的情况)。以上效果用光栅化的办法也不是不行,就是效果不怎么好。
在这里插入图片描述
总的来说,光栅化很快,但是质量相对不好。
在这里插入图片描述
光线追踪是一种准确的方法,但是运算速度非常慢。所以我们一般在实时渲染(每秒钟要渲染30帧以上)中一般使用光栅化。而光线追踪使用在像电影特效一类的非实时(offline)的渲染中,一般需要10k cpu/小时来渲染一帧。

光线(Light Rays)

在这里插入图片描述
关于光线有三个要点

  • 首先,光线是沿着直线传播的(这实际上是错的,光线在物理上是一种波,但是我们不考虑那么多)。
  • 其次,光线和光线不会发生碰撞(当然在现实生活中这也是不对的,但是我们依然不考虑那么多)。
  • 最后,光线一定是从光源发出,经过不断地反射直射(当然也可能直接),进入眼睛的(我们能看到东西一定是因为有光线这么做了,没有这么做的光线我们看不到,也就没有讨论意义)。同样的,这个过程也可以反着表示,也就是我们可以认为光线从眼睛出发经过一系列反射折射,到达光源。这叫做光路可逆性(Reciprocity)。

光线投射算法(Ray Casting)

在这里插入图片描述
通过每个像素发射一条光线,得到通过这个光线打到场景中的某个物体上来确定这个像素能看到什么,再从这个打到物体上的点发射一条向着光源的光线,根据能不能到达光源来判断该点是否是阴影。
在这里插入图片描述
通过找到eye ray,也就是从眼睛发出的射线打到场景中的最近的位置,我们找到了眼睛能看到的物体,并且解决了深度问题。
在这里插入图片描述
接下来,从之前找到的最近点向光源发射一条射线(我们管这条射线叫Shadow Ray)。如果这条射线被东西挡着了,就说明这个点在这个光源的阴影里。并且能根据相关信息对发射射线打到这个点的像素进行着色。
当然你也应该发现了,既然找到的是最近的点,我们得到的结果依旧是光线经过一次反射的结果。既然都上光追了干嘛还这么没追求?

二、递归的(Whitted-Style)光线追踪算法(Recursive (Whitted-Style) Ray Tracing)

递归光线追踪

在这里插入图片描述
假设上图中的球是玻璃材质,那么我们从眼睛中发出的光线要做镜面反射,打到远处的三角物体上,同样的光线还会做折射,再打到远处的矩形物体上。在Whitted-Style中,你可以计算在任意一个点的反射和折射,并且计算这些反射折射点的阴影,最后将这条光线所有的反射折射点的所有着色值都加到像素中去(当然,每次反射折射的能量损失是考虑在内的)。
Whitted-Style,简单来说,就是直接模拟光线的运动过程。

光线和隐式几何物体表面的交点

在这里插入图片描述
在数学上,光线是一个通过他自己的原点和方向定义的向量。光线上的任何一个点都可以用上图中的公式来表示。
在这里插入图片描述
我们有光线的公式和球的公式,假设我们的光线要和一个球体求交,也就是说一个点既要在光线上也要在球上,那我们要做的就是解方程。
在这里插入图片描述
根据方程我们可以解出时间t,也就是光线打到球体的时间。
在这里插入图片描述
由上面球体的例子,我们可以将公式推广到一般情况。如上图。

光线和三角形网格的交点

在这里插入图片描述
光线怎么和三角形网格求交?最简单的办法是,让光线和每一个三角面求交。最近的交点也就是和网格的交点。当然这个计算量超大。注意:我们不考虑射线正好就在三角面上,要么有交点,要么没交点。
在这里插入图片描述
要判断射线和三角面的相交关系,可以先求射线和三角面所在平面的交点,在判断交点在不在三角形内。现在要做的就是定义平面。
在这里插入图片描述
平面可以通过平面上的一点p’和平面的法线来定义。如果p点在平面上,则p - p’得到的向量和平面法线点乘为0。我们可以将上述写成公式。
在这里插入图片描述
于是我们又可以用数学公式去求交了。求出交点以后再判断交点是否在三角形内即可。

Moller Trumbore Algorithm

在这里插入图片描述
这是一种更快速的方法。将三角形内的点写成用重心坐标表示的形式,这样求出来的结果直接就在三角形内。

三、光线和表面求交的加速方法

原始的办法计算量极大。我们需要找到一种办法加速这个过程。

包围盒(Bounding Volumes)

在这里插入图片描述
对于一个相对复杂的几何物体,我们使用一个简单的几何将他包围在里面。如果一个光线连包围盒都碰不到,就更不可能碰到包围盒里面的物体。
在这里插入图片描述
我们认为,盒子是一个三对不同的对面(Pairs of Slabs 是一对无穷大的平面)的交集(Intersection)。
在这里插入图片描述
我们通常使用的包围盒叫做轴对齐包围盒(Axis-Aligned Bounding Box, AABB),也就是包围盒的任意面都是和x,y或者z轴中的一条对齐的。

如何判断光线和包围盒有交点

在这里插入图片描述
我们先考虑二维中的情况,首先,得到光线和一对包围盒面(之前说的无穷大的平面)的交点,将得到的两个最近点tmin和最远点tmax连在一起得到一条线段。再得到光线和另一对包围盒面的交点,同样将近点远点连起来得到线段。接下来,将得到的两条线段求交集。得到的就是在包围盒中的tmin到tmax。
在这里插入图片描述
那么对于三维来说,我们可以确定一下几个关键思想,首先,光线只要在进入了所有的包围盒面对才能进入包围盒(当然说进入有点奇怪,只要在某对里面,他就肯定进入了,哪怕一开始就在里面)。其次,光线离开任意一对面,说明他就一定离开盒子了。
在这里插入图片描述
对于每一对面,求出tmin和tmax。那么在三维盒子中,tenter,也就是进入盒子的t时间,为求出的所有tmin中的最大值,texit,离开时间,为tmax中的最小值。
在这里插入图片描述
如果tenter < texit,我们就知道光线进入过包围盒。
在这里插入图片描述
由于光线是一个射线,所有一定要检测时间t是否是正的,来确保物理正确性。
如果说,光线离开盒子的时间是负的,说明盒子在光线背后,这是不可能有交点的。
当离开的时间是非负的,进入的时间是负的,说明光线的起点就在盒子里面,光线和盒子肯定有交点。
总结,当且仅当进入的时间小于离开的时间并且离开的时间是非负的时,光线和AABB才有交点。

为什么要求轴对齐?

在这里插入图片描述
光线和轴平行的面求交点比较好求,上图说明了轴对齐时求交公式更简单。

课程的最后

其他的加速方式,以及进一步的方法。会在之后讲解。