700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 计算机图形学【GAMES-101】7 光线追踪原理(线面求交 预处理空间划分)

计算机图形学【GAMES-101】7 光线追踪原理(线面求交 预处理空间划分)

时间:2018-12-17 17:15:25

相关推荐

计算机图形学【GAMES-101】7 光线追踪原理(线面求交 预处理空间划分)

快速跳转:

1、矩阵变换原理Transform(旋转、位移、缩放、正交投影、透视投影)

2、光栅化(反走样、傅里叶变换、卷积)

3、着色计算(深度缓存、着色模型、着色频率)

4、纹理映射(重心坐标插值、透视投影矫正、双线性插值MipMap、环境光遮蔽AO)

5、几何(距离函数SDF、点云、贝塞尔曲线、曲面细分、曲面简化)

6、阴影映射(Shadow Mapping)

7、光线追踪原理(线面求交、预处理光追加速)

8、辐射度量学与光线追踪

9、蒙特卡洛路径追踪(Path Tracing)(光源采样)

10、材质(BRDF)(折射、菲涅尔项、微表面模型、各向异性材质)

11、渲染前沿技术介绍(双向路径追踪BDPT、MLT、光子映射、实时辐射度、外观建模)

12、相机(视场、曝光、光圈(F-Stop)、薄棱镜近似、CoC、景深)

13、光场、颜色与感知

14、动画(物理模拟、质点弹簧系统、粒子系统、运动学、动作捕捉、欧拉方法)

Lecture13~14

1 光栅化和光线追踪2 Whitted-Style光线追踪2.1 定义图形学中光线的性质2.2 光线仅弹射一次的光追3 光线-物体求交点3.1 光线与球体表面3.2 光线与隐式表面求交3.3 光线与显式表面(三角形)求交4 预处理 —— 包围盒求交加速4.1 空间网格划分4.2 非均匀空间划分4.3 对象划分 Bounding Volume Hierarchy(BVH)GAMES101图形学专栏

1 光栅化和光线追踪

光栅化:已知三角形在屏幕上的二维坐标,找出哪些像素被三角形覆盖。物体 找 像素点

光线追踪:从相机出发,对每个像素发射射线,去探测物体,判断这个像素被谁覆盖。像素点 找 物体

光栅化

光栅化不能很好的模拟全局光照效果

基本只考虑光线弹射一次,即从光源打到物体表面弹射到相机

是一种近似的效果,不准确、不真实光线追踪的优势

更方便地处理间接光照(光线到达相机之前弹射多次)

更好实现软阴影、毛玻璃效果

准确、真实、符合物理规律、质量非常高光线追踪唯一的缺点:特别慢

2 Whitted-Style光线追踪

2.1 定义图形学中光线的性质

不同于光在波动学中的定义,对于图形学中的光线简化(并不是很正确、很物理)的定义:

(1)光沿直线传播

(2)光线之间不会相互影响、碰撞

(3)光本该从光源出发照射到物体反射进入人眼,但图形学中反着来,眼睛发射光线。

2.2 光线仅弹射一次的光追

Whitted-Style光追,实际上只考虑了直接光照,即直接从光源照射到物体,然后物体反射光进入人眼。它并未考虑间接光照的影响,即别的物体反射的光打到另一个物体上再进入人眼。所以它不能很好的模拟全局光照的效果。

算法过程(眼睛发射光)

(1)通过摄像机对每一个像素发出一道射线(View Ray)

(2)射中物体,把该点直接连接到光源(Shadow Ray),判断是否在阴影中(没被挡住就不在阴影内)

(3)计算着色(Blinn Phong model)

光追算法其实很好理解,摄像机(眼睛)到某像素两点一线发出射线,击中一个或多个点后,取最近一个,连到光源,若没被阻挡则不在阴影内,被阻挡则在阴影内。之后对每一个像素做一遍这个操作,有几百万个像素就要射出几百万根,所以对并行计算性能要求特别高。

如图看透明球,不仅能看到透明球,还能看到球后面的物体,这不就是光线击中球后,还进行了折射最后击中后面的地面,那交点有多个每个交点都进行着色计算,然后按照一定的权重加到像素上

光线命名区分

primary ray:从摄像机射出的光线

secondary ray:反射或折射(一次或多次)后的光线

shadow rays:交点到光源的连线

3 光线-物体求交点

射线方程

定义光线:光源点、方向。t时刻光线的位置 = 光源点坐标 + t * 方向向量

3.1 光线与球体表面

球体方程如下

注意这个跟平常的定义不太一样(x-x0)2+(y-y0)2+(z-z0)2=R2;但其实是另一种表示而已,比如p其实就是球面上任意一点(x,y,z),c就是圆心(x0,y0,z0) 这俩相减得到一个向量,再平方(自己跟自己点积)得到的是一个标量,这个量就是R2;所以下面这个方程表示的就是位于圆心在c半径为R的球表面上的任意一点。射线与球面相交与p点(已知:球心c,半径R,光源o,射线方向d)

求解过程就是解方程额

(1) o + td = p

(2) (p - c)2 - R2 = 0

把(1)带入(2)得到关于t的一元二次方程解之即得t,交点是p = o+td,(注意:根t必须为实数才有意义,即△ ≥ 0)

3.2 光线与隐式表面求交

解出来的是t,交点p还要o+td

3.3 光线与显式表面(三角形)求交

通过光线和三角形求交

渲染:可判断可见性,计算阴影、光照

几何:可判断点是否在物体内(很简单,光源发射射线,判断该射线与物体的交点有几个

奇数个交点表示在物体内,偶数个交点则在物体外)计算方法:遍历物体每个三角形,判断与光线是否相交

(1)光线-平面求交(三角形属于平面)

(2)计算交点是否在三角形内(3次叉乘)

那么如何定义一个平面呢?

法线N+面内一个点p’(跟法线向量垂直的面有无数个,再额外给定某个点,即可唯一确定一个面)

平面方程:平面内所有点p满足(p - p’)·N = 0,只有p在该平面内,(p-p’)点乘N才为0,垂直嘛。

打开括号,p(x,y,z)·N(a,b,c) = ax+by+cz;然后p’·N = d然后求交点——解方程组

p = r(t) = o+td,(p - p’)·N = 0联立这两个方程即可得到t的结果,很简单甚至没有二元一次方程了

t的右侧全都是已知量,注意验证t必须是实数

到这里只是算出t,交点= o + td,算出交点还不够(这是和平面的交点),还要满足这个点在三角形内,才能说这个点是光线和三角形的交点,即还要叉乘判断内外,结束。有点麻烦啊,算这么多步骤,能不能一步到胃?——阔以

Möller-Trumbore射线-三角形求交算法

这种算法更方便快捷他以另外一种方式描述了平面(重心坐标)

等式左边是射线(光线)方程,t是未知量

等式右边是三角形的重心坐标,P0,P1,P2是三角形三个已知顶点,b1b2是P1,P2的权重,也是交点的重心坐标的两个分量,第三个分量可以1-b1-b2算出

所以未知量一共3个t,b1,b2

由于坐标都是三维的所以每个分量都可以对应建立1个方程,即3个未知数3个方程,可以解方程组得到3个未知量

解线代方程组得到结果。要验证(t>0;b1+b2+b3 = 1,且非负)

具体推导过程

4 预处理 —— 包围盒求交加速

目前求交算法的花销

一根光线与场景每一个三角形都判断一次是否有交点,找到最近的击中点(通过找最小的t)。

计算次数 = 像素个数 x 场景中所有三角面个数 x 反射次数,超级慢加速方法:用简单的体积包住复杂对象

场景的物体都被一个个包围盒包住,先用光线跟盒子求交,光线如果连包围盒都碰不到,里面的三角形那是必然碰不到的。

我们认为,一个盒子其实就是6个平面围住的一块公共区域,下图只画了2个平面后面所有包围盒都遵循Axis-Aligned-Bounding-Box(AABB)轴对齐包围盒

轴对齐即面跟xoyxozyoz任一平面平行

AABB(轴对齐),如何快速求交点(以与x轴对齐的面为例)?

光线方程:p=o⃗+t⋅d⃗\large p=\vec{o}+t·\vec{d}p=o+t⋅d

与x轴对齐的面:x=x0\large x=x_0x=x0​

两者求交的方式很简单,明确目的:求t只要求出t就能用光线方程得到交点

仅看光线方程的x轴分量,公式可以变成 px=ox+t⋅dx\large p_x=o_x+t·d_xpx​=ox​+t⋅dx​,三个已知量,t很容易得出

ox\large o_xox​:光线起点的x分量

dx\large d_xdx​:光线的方向的x分量

px\large p_xpx​:目标平面的x值

稍微整理一下

求光线与面x=x0\large x = x_0x=x0​的交点:t=x0−oxdx\displaystyle \large t=\frac{x_0-o_x}{d_x}t=dx​x0​−ox​​求光线与面x=x1\large x = x_1x=x1​的交点:t=x1−oxdx\displaystyle \large t=\frac{x_1-o_x}{d_x}t=dx​x1​−ox​​

也可以通过物理的方式记忆这个公式,ttt是时间,x0−oxx_0 - o_xx0​−ox​是两个点之间的水平距离,dxd_xdx​是水平方向的速度,时间 = 距离÷÷÷速度

2D中的轴对齐盒子的求交

看着挺复杂的哈

(1)首先第一幅图是跟X0,X1两个无限大的平面求交点,得到两个相交时间tmin、tmax

(2)然后跟y0、y1面求交点得到另一对时间tmin、tmax

(3)实际上这两次求交分别得到了两个线段,再对两个线段求个交集即得到最后一张图的跟盒子的实际交点了

再看3D中做法

提醒:一个盒子是3对无限大的面围的一块区域

判断进入包围盒:光线进入所有对面才算进入包围盒

判断离开包围盒:光线出任意一个对面就算离开包围盒小的里面找大的,大的里面找小的,就是进入和离开盒子的时间 进入3D盒子的时间:tenter =max{tmin}离开3D盒子的时间:texit =min{tmax}

(如果texit < 0:盒子在光线发射方向的后面,不可能有交点)

(如果texit >= 0 && tenter < 0:光源在盒子内部,必然有交点)总结:有交点的判定条件(tenter < texit && texit >= 0 )

4.1 空间网格划分

做光线追踪之前,预先构建好包围盒网格

(1)构建包围盒

(2)构建网格

(3)网格跟物体表面求交,记录内部有物体的网格

做光线-场景相交计算

光线跟格子求交,如果遇到"内部有物体的"格子则需要做光线-物体求交,判断光线是否跟该物体相交,从而可以找到光线跟所有物体的交点。

问题:如何知道光线首先打到哪个格子,下一次又会打到哪个格子呢?

简单的一个想法,具体算法可能与这个想法有差别:

第一个格子:可能就遍历所有格子求出一个最近的相交的格子。

下一个格子:判断光线的方向,比如向右上方发射的光线,击中某个格子后,下一个可能击中的格子必然是右边或者上面的格子,就不用遍历所有格子了。其实就是光栅化一条直线,具体算法,课中未提及格子的数量对于加速效果的影响?

格子太多:比像素数量还多,那你这是加速还是减速。。。

格子太少:整个世界就用一个格子,完全没有加速。

所以格子数量的多少是有讲究的。经验公式:格子数 = 对象数量 x 27Uniform Spatial Partitions适用的场景,物体均匀分布在场景的各个位置

4.2 非均匀空间划分

物体少的地方格子少一些,物体分布密集的地方格子多一些。

例子是2D,自己脑补3D

Oct-Tree:类似八叉树结构,注意下面省略了一些格子的后续划分,格子内没有物体或物体足够少时,停止继续划分。KD-Tree:每次划分只沿着某个轴砍一刀,XYZ交替砍,不一定砍正中间,每次分出两块,类似二叉树结构。BSP-Tree:空间二分的方法,每次选一个方向砍一刀,不是横平竖直,所以不好求交,维度越高越难算。

KD-Tree 预处理

注意KD-Trees有两类节点,存放的信息是不同的内部节点(如ABCD)存放

(1)对齐的轴:x、y、z的其中一个

(2)分割的位置:分裂平面沿着轴的坐标

(3)节点指针:指向两个孩子节点的指针叶子节点(如12345)存放:物体对象的列表KD-Tree遍历

如果是内部节点则分裂、如果是叶子结点则与内部存放的对象求交

求交过程详细描述(假设KD-Tree就长上面这个样子)

光线进入盒子A触发以下逻辑

(1)判断光线与其两个子节点是否有交点

(2)孩子节点1:是叶子节点,光线与其存放的所有物体求交点

(3)孩子节点B:是内部节点,判断光线与其两个子节点是否有交点

递归,直到遍历完所有的相交的叶子结点为止。KD-Tree的巨大缺陷:判定物体和包围盒的交集、物体是否属于某包围盒、同一物体可能存放于多个包围盒的问题,这些问题导致KD-Tree并不受欢迎。很难去建立一个很好的KD-Tree

4.3 对象划分 Bounding Volume Hierarchy(BVH)

不划分空间,而是划分物体!——(换个角度思考,就美美的解决问题)根节点依然是最外层大包围盒

逐步对物体进行分区:

(1)所有物体分成两组,对两组物体分别求一个包围盒(xyz的最值作为包围盒边界)

(2)递归,对每个包围盒内部物体重复(1)中步骤,直到包围盒中的物体足够少

BVH方法的包围盒有相交,应当尽可能减少相交量

节点细分原则

选择某一个轴进行划分,横平竖直永远切割最长的轴,切割位置选择在物体数量的中位数附近(可以沿着该轴方向对所有三角形的中位数进行排序,找出中间的那个,复杂度o(logn);也可以不排序,快速选择算法,直接找出中间数o(n))节点中的物体数量小于某个数就停止划分(比如5个)

BVH数据的存储结构

中间节点存放

1.包围盒

2.指向孩子节点的指针叶子节点存放

1.包围盒

2.对象列表

遍历BVH的算法

遍历每个盒子的算法跟KD-Tree遍历的算法没有区别,两者只是划分盒子的角度不同

递归

GAMES101图形学专栏

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。