计算机图形学笔记十二:Ray Tracing2(AABB加速光线追踪)

1.包围盒(Bounding Volumes)

遇到非常复杂的场景,三角形面数太多,且光线复杂,将会花费大量时间来渲染。如下图有着10.7万个三角形面:
在这里插入图片描述
因此,引入包围盒(Bounding Volumes)

将物体包围在有一定范围内,如果射线没有击中包围盒,那么它就不会击中物体。过程很简单:光线有打到盒体上,那么再去计算光线与物体表面的交点。
在这里插入图片描述
包围盒定义:一个包围盒由三对平行面包围而形成的一个三维空间中的区域:

1.1轴对齐包围盒Axis-Aligned Bounding Box (AABB)

我们通常使用轴对齐包围盒Axis-Aligned Bounding Box (AABB)
在这里插入图片描述
为什么要轴对齐?
如下图所示,明显在计算难度上,用了轴对称后的会更简单计算:
在这里插入图片描述

1.2AABB计算交点的具体步骤

Step1:在x,y平面上分别求出光线经过两对平行面的进入时间 t ( m i n ) t(min) t(min)和出去时间 t ( m a x ) t(max) t(max)
Step2:在整体区域上,光线进入该区域的时间取两个 t ( m i n ) t(min) t(min)中的最小值,出去该区域的时间取 t ( m a x ) t(max) t(max)中的最大值( t t t可以取负数)
在这里插入图片描述
对于3D盒体:

  • 3D物体的包围盒盒体就是一个三对无限大的平板
  • 只有光线同时进入所有相对的面才算进入盒体
  • 只有光线从一个相对面中出去才算离开盒体
  • 对于每对面,求 t m i n , t m a x t_{min},t_{max} tmintmax(负值情况后面介绍)
  • 然后,对于整个盒体, t e n t e r = m a x ( t m i n ) , t e x i t = m a x ( t m i n ) t_{enter}=max(t_{min}),t_{exit}=max(t_{min}) tenter=max(tmin),texit=max(tmin)
  • t e n t e r < t e x i t t_{enter}<t_{exit} tenter<texit时,认为光线进入了盒体

如果 t m i n , t m a x t_{min},t_{max} tmintmax出现了负数:

  • 光线不是直线
  • t e x i t < 0 t_{exit}<0 texit<0时,盒体在阴影中,即与光线没有交点
  • t e x i t ≥ 0 t_{exit}\geq0 texit0时,光线起点在盒体内,有交点
  • 总之,光线与AABB相交,当且仅当 t e n t e r < t e x i t & t e x i t ≥ 0 t_{enter}<t_{exit} \& t_{exit}\geq0 tenter<texit&texit0

2.AABB加速光线追踪

2.1均匀空间划分

在之前包围盒的基础上,做了进一步均匀空间划分,
具体步骤
Step1:创建包围盒包围物体
Step2:均分网格(网格大小与实际物体数量有关,测试出来网格数量一般为 27 × \times ×物体数量)
Step3:将每个对象存储在其所占有单元格中
在这里插入图片描述
Step4:将光线入射,先判断是否经过物体所占的单元格
Step5:若经过物体所占的单元格,再判断是否与物体所占的单元格相交
注:判断光线经过了哪些网格时,不需要遍历全部网格,如下图所示,光线是从左下到右上,则光线所经过的下一个网格,一定在当前网格的上方或者右方
在这里插入图片描述
但是,这种将空间均分的方法,也有其局限性,并不能适应大多数情况,如下图所示:
适用于:大小和空间上均匀分布的大型对象集合
在这里插入图片描述
不适用于:分布极不均匀的物体
在这里插入图片描述

2.2空间划分(KD-Tree)

由于上述方法是均匀划分空间的,不能很好的将物体放在一个单元格中,因此我们提出空间划分的方法,为了能够将一个或更多物体整体的放在一个格子里面。
Oct-Tree(八叉树):将包围盒 x , y , z x,y,z x,y,z方向"各切一刀"一分为八(等区域),然后在切出来的各个子盒中再次一分为八,直至子包围盒中没有物体,存在高维度不好划分的问题;
KD-Tree(类似二叉树):下面再详细介绍;
BSP-Tree(类似二叉树):和KD-Tree思想一样,只是将水平切和竖直切,变成了斜着切,并且不符合AABB规则,存在高维度不好划分的问题;
在这里插入图片描述

2.2.1 KD-Tree

Step1:划分网格,保存信息
对包围盒进行有规律的划分(例如:按顺序沿着x、y、z轴进行依次划分),当子盒体中物体数量很少时,该子盒体就得停止划分;最后将物体的各种信息都保存在自己所在的最小盒体所对应的叶子节点上,如下图所示:
注:例子只划分了右半部分,实际上左右部分都需要划分,这里仅以右边为例
在这里插入图片描述
Step2:依次遍历KD-Tree子节点判断是否相交,如果相交则继续与其子节点判断,直到叶子节点,再去与叶子节点内存储的物体求交点
判断1判断B
直至:
在这里插入图片描述
KD-Tree存在的问题:

  • 判断物体与包围盒边界的相交关系的算法较难,不容易写出;
  • 一个物体可能在多个包围盒内,那么就会有多个叶子结点包含此物体信息;

2.3对物体划分(BVH方法)

BVH是基于三角形面进行空间划分的光追加速算法。

具体步骤
Step1:首先将场景中的物体用一个大的AABB包起来
在这里插入图片描述
Step2:将大的AABB再次依据物体分布,分为两个小的AABB(可能会重叠,但不影响);人为规定停下的要求(比如盒内物体数量小于等于3时)
注:例子只划分了左半部分,实际上左右部分都需要划分,这里仅以左边为例
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注:

  • 每次划分尽量选择最长轴x,y,z轴进行划分,这样可以保证每次划分在空间上较平均
  • 尽量选择中间节点进行划分,这样可以保证划分出来的二叉树无限接近于平衡二叉树

BVH伪代码:
在这里插入图片描述

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
射线追踪法是一种计算机图形中常用的算法,用于生成逼真的图像。直达波ray tracing 试射法是射线追踪算法的一种应用,可以模拟光线直接从光源射到物体表面上的效果。以下是一个简单的C源代码示例: ```c #include <stdio.h> typedef struct { float x; float y; float z; } Vector3; typedef struct { Vector3 origin; Vector3 direction; } Ray; typedef struct { Vector3 position; Vector3 normal; } Plane; int intersectRayPlane(Ray ray, Plane plane, float* t) { float denominator = plane.normal.x * ray.direction.x + plane.normal.y * ray.direction.y + plane.normal.z * ray.direction.z; if (denominator == 0) { return 0; } float numerator = plane.normal.x * (plane.position.x - ray.origin.x) + plane.normal.y * (plane.position.y - ray.origin.y) + plane.normal.z * (plane.position.z - ray.origin.z); *t = numerator / denominator; if (*t >= 0) { return 1; } return 0; } int main() { Ray ray; ray.origin.x = 0; ray.origin.y = 0; ray.origin.z = 0; ray.direction.x = 1; ray.direction.y = 0; ray.direction.z = 0; Plane plane; plane.position.x = 5; plane.position.y = 0; plane.position.z = 0; plane.normal.x = -1; plane.normal.y = 0; plane.normal.z = 0; float t; if (intersectRayPlane(ray, plane, &t)) { printf("The ray intersects the plane at t = %f\n", t); } else { printf("The ray does not intersect the plane\n"); } return 0; } ``` 以上代码示例定义了一个包含原点和方向的射线结构体`Ray`以及一个包含位置和法向量的平面结构体`Plane`。通过调用`intersectRayPlane`函数,可以判断射线和平面是否相交并计算相交点的参数`t`值。在示例中,射线的原点在坐标原点,方向为X轴正方向,平面的位置在X轴上5个单位处,法向量为X轴负方向。输出结果将显示射线是否与平面相交以及相交点的参数`t`值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值