RayTracing&&RTCore初探

collectcrop Lv4

Ray Tracing 基础概念

光线追踪是一种通过模拟光线在三维场景中的传播路径,并计算其与几何体的相互作用来生成图像的渲染技术。它的核心思想是:

  1. 从摄像机出发发射光线(primary rays)
  2. 计算光线与场景几何体的交点
  3. 根据材质计算反射、折射或阴影
  4. 递归生成新光线
  5. 计算最终颜色

Ray

在几何中,光线(ray)是:从一个起点出发,沿某个方向无限延伸的半直线。它有两个要素:起点(origin)和方向(direction)。

光线的参数方程(parametric equation)如下: 其每个参数的含义如下:

:光线起点(origin),三维向量 :方向向量(direction) :标量参数(实数)

这种表达方式把“几何问题”变成了“代数问题”。如果有一个物体表面满足: 只要把参数方程的每个分量拆出来()并代回物体的表面方程,就可以求解: 于是问题变成求 t 的方程,这就是所有“求交”算法的基础。所以光线追踪的本质就是求解参数t。

Triangle

在一开始接触光追的内容时,我发现大部分相交测试都是对光线与三角形求交,实际理论上光线可以与任意形状求交,但现实中使用几乎全部使用三角形,这主要是基于以下几个原因:

  • 三点确定一个平面:不会像四边形一样不共面
  • 任何复杂模型都可三角化,球体、曲面、角色模型,本质都可以近似为大量三角形
  • 现代 GPU 的光栅化管线天然支持三角形,实时图形 API 都以 triangle 为基本 primitive,RT Core也是用硬件支持了triangle的求交。

正因为三角形的表达能力强、数学简单、求交稳定、易于并行。因此:光追的核心任务就是Ray ∩ Triangle

AABB (Axis-Aligned Bounding Box)

AABB翻译过来是轴对齐包围盒,也就是一个边与坐标轴平行的长方体盒子。例如在 3D 空间:

1
2
3
x_min ≤ x ≤ x_max
y_min ≤ y ≤ y_max
z_min ≤ z ≤ z_max

这 6 个值就完全定义了一个 AABB。光追里用AABB是因为光线盒AABB的相交测试非常便宜,比如光线参数形式为: 对每个轴单独求解: 只需要几次除法和几次 min/max 比较,而且非常适合GPU并行,速度非常快。AABB主要是用来快速排除不可能相交的几何体的,比如一个光线和AABB不相交,那么在AABB其中的所有几何体都可以不用再进行相交测试了。

Primitive

在光线追踪中,primitive指的是BVH 叶子节点中,光线“直接做求交测试”的最小几何单元

也可以说是RT Core / 求交算法“原子级”能处理的几何对象

RT-Core原生可以用硬件支持triangleAABB的求交,其它primitive例如sphere都需要在CUDA core专门定义一个Intersection Shader来自定义求交算法,因此不能用硬件进行加速。

Möller–Trumbore 算法

这是最经典的光线-三角形求交算法

问题定义

已知光线: 三角形三个顶点: 是否存在 t ≥ 0,使得光线击中三角形内部?

算法结构

  1. 计算边向量

  2. 如果 det ≈ 0 → 平行

思想核心

三角形内部的点可以用重心坐标表示: 其中: 所以我们要解: 假设: 经整理得: 写成矩阵形式: 这是一个 3×3 线性系统

设: 我们要解: 其中: 计算行列式: 三维中: 所以: 这其实是光线方向和三角形法向量的关系,如果为0则光线平行三角形平面,无交点。

根据 Cramer 法则以及标量三重积的循环对称性: 定义 通过行列式恒等式可得到: 再定义: 用同样的方式可以得到: 最后推导t:

BVH算法

BVH = Bounding Volume Hierarchy(包围体层次结构)

它是一种空间加速结构(acceleration structure),主要用于:

  • 光线追踪(Ray Tracing)
  • 碰撞检测
  • 最近邻搜索
  • 空间查询

在光线追踪中,最基础的问题是:一条光线要和场景中的多少个三角形求交?如果场景有 N 个三角形,暴力做法是对每条 ray,和所有 N 个三角形做相交测试,其时间复杂度为。如果场景有 1000 万个三角形,这显然不可接受。

BVH 的核心思想与我们常见的Tree的思想类似,就是把物体分组,用包围盒(AABB)包住一组物体。结构形式如下:

1
2
3
4
5
      Root (AABB)
/ \
Node Node
/ \ / \
Leaf Leaf Leaf Leaf

最常见的BVH是一颗二叉树,且子节点的AABB是允许相交的,所以一个节点的左子树所代表的AABB如果和ray相交了,这并不能说明其右子树的AABB一定与ray不相交。

一般来说一条ray与AABB求交时,要么得不到一个合法的t区间,要么可以得到两个交点的t 区间 ,其中 ray-tracing 的默认行为是返回在遍历BVH时第一个相交的primitive,这是比较常见的需求,因为正常来说一个物体会遮挡光线继续向后传播,我们只需要渲染碰到的第一个物体的材质即可。所以实际BVH会采用类似带pruning的DFS算法来进行traverse。也就是说对于一个节点,会先分别对其左右子树的AABB进行求交测试。如果两个都不相交则可以直接返回miss,如果两个都相交则首先往小的进行遍历,把另一侧的节点压栈(由硬件状态机完成)。实际在traverse过程中会维护一个当前已经找到的 最近三角形交点的 t,记作​,其初始值为datatype的最大值,当遍历到某个 BVH 节点时,如果: 那么可以 100% 确定 这个节点及其所有子树,不可能包含更近的交点,原因很简单:

  • 光线 进入这个盒子的时间 都已经比当前 hit 晚了
  • 里面的任何三角形交点 t ≥ t_enter

所以我们可以 直接剪枝

实际我们也可以通过设置any-hit的CUDA shader来捕捉1个ray的所有hit,具体可见这个 answer

SAH算法

SAH = Surface Area Heuristic(表面积启发式)

它是构建高质量 BVH 时最重要的成本模型。当一条随机光线进入一个 AABB 时,它击中子节点的概率 ∝ 子节点的表面积。因此:

表面积越大,被访问的概率越高。SAH的成本函数如下: 其中:

  • :左右子节点表面积
  • :父节点表面积
  • :左右子树三角形数量
  • :遍历开销
  • :三角形求交开销

SAH构建的流程如下:

  1. 选择分裂轴(x,y,z)
  2. 将 primitives 排序
  3. 尝试所有可能分裂位置
  4. 计算 SAH cost
  5. 选最小 cost 的分裂

时间复杂度: 这样生成出的BVH质量很高。

RT-Core

RT Core(Ray Tracing Core)是 NVIDIA RTX GPU 中的固定功能硬件单元,用于硬件加速光线追踪中最昂贵的几何计算。RT-core主要的功能只有两个,一个是进行BVH的遍历,另一个是进行求交测试。对于primitive的求交测试,RT-core目前只支持了triangle的硬件求交加速,而其余的primitive需要我们自己设置intersection shader来进行自定义处理。这里需要注意的是,在BVH traverse时所对AABB的求交测试是RT-core用硬件支持的,因为这只用并行计算几个t值。但AABB不是一个renderable primitive,也就是说如果叶子节点的primitive是AABB,那么我们也需要手动设置一个处理求交的shader函数。

在 NVIDIA RTX 架构(Turing / Ampere / Ada)中:

  • RT Core 位于每个 SM(Streaming Multiprocessor)内部
  • 与 CUDA Core、Tensor Core 并列
  • 不是独立处理器,也不是独立芯片

RT Core 是 SM 的一个“专用协处理单元”。其相较于CUDA Core能够避免warp divergence的问题,比如如果用CUDA Core处理 ray tracing 问题,由于每个warp内部采用SIMT进行并行计算,那么求交结果的不同将会跳转到不同的分支,这种情况下SIMT的并行就失效了,就会让不同的分支交错执行,降低并行性能。

在GPU的每个SM里都含有1个RT-core,每个RT-core内部实际可以并行处理多个ray tracing。

  • 标题: RayTracing&&RTCore初探
  • 作者: collectcrop
  • 创建于 : 2026-03-03 16:25:35
  • 更新于 : 2026-03-03 16:44:17
  • 链接: https://collectcrop.github.io/2026/03/03/RayTracing--RTCore初探/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。