在实时渲染与离线光线追踪系统中,Bounding Volume Hierarchy(BVH)仍是当前最主流的加速结构。相比 KD-Tree 等替代方案,BVH 在 GPU 上的内存访问模式更友好,且支持高效的自顶向下构建。本文从构建阶段的启发式策略出发,讨论遍历阶段的数值鲁棒性问题,并给出可直接落地的参数配置。
构建阶段:超越经典 SAH
Surface Area Heuristic(SAH)是 BVH 构建的核心准则,其基本思想是选择分割平面使得左右子树的表面积加权和最小化,从而降低光线与包围盒的期望求交次数。标准 SAH 公式为:
Cost = C_traversal + (SA_left/SA_parent) * N_left * C_intersect + (SA_right/SA_parent) * N_right * C_intersect
其中 C_traversal 和 C_intersect 分别表示遍历节点和图元求交的相对开销。
然而纯 SAH 在复杂场景中存在包围盒重叠过高的问题。2022 年的改进工作将空间距离度量引入分割决策,在保持 SAH 框架的同时,优先选择能够减少子树空间重叠的分割方案。实测表明,这种混合策略在典型测试场景下可获得 20%-35% 的遍历性能提升,而构建时间增加控制在 15% 以内。
可落地的构建参数:
- 最大叶子图元数:4-8 个三角形(GPU 场景建议 4,CPU 可放宽至 8)
- 分割候选采样数:每个轴向上均匀采样 16-32 个候选平面
- 终止条件:当节点图元数 ≤ 最大叶子图元数,或遍历深度超过 32-64 层
- 空节点剪枝:若某子节点包围盒为空,直接合并到另一子树
遍历优化:数值鲁棒性与内存布局
BVH 遍历的性能瓶颈往往不在算法复杂度,而在内存访问模式和浮点精度处理。现代 GPU 实现需要特别关注以下两点:
逆方向向量的 padding 处理
光线 - 包围盒求交使用 slab 方法时,需要计算 tmin 和 tmax 区间。当光线方向分量接近零时,逆方向计算 1.0/dir 会产生极大的数值误差。鲁棒的做法是对逆方向施加微小 padding:
float invDirX = 1.0f / (fabs(dir.x) < 1e-8f ? copysign(1e-8f, dir.x) : dir.x);
这种处理在 JCGT 的鲁棒 BVH 遍历研究中被验证可有效消除因数值精度导致的漏检问题。
内存布局优化
BVH 节点应采用 32 字节或 64 字节对齐的紧凑结构,确保 GPU 的合并内存访问(coalesced access)。推荐布局:
struct BVHNode {
float3 minBounds; // 12 bytes
int leftChild; // 4 bytes (叶子节点时为图元索引)
float3 maxBounds; // 12 bytes
int rightChild; // 4 bytes (叶子节点时为图元数量)
};
遍历栈深度通常限制在 32-48 层即可覆盖绝大多数场景,使用静态数组避免动态分配。
复杂几何体的求交策略
对于超出简单三角形网格的几何体,BVH 需要配合特定的求交策略:
实例化(Instancing)
通过两层 BVH 结构处理:顶层 BVH 的叶子节点存储变换矩阵和指向局部 BVH 的指针。遍历时需要将光线变换到局部坐标系,求交后再将结果变换回世界坐标系。注意变换后的光线方向需要重新归一化,且 t 值需要在世界空间计算。
运动模糊(Motion Blur)
线性运动模糊可通过将图元包围盒在时间维度上扩展为 4D AABB 实现。更高效的方案是在构建时按时间片分割图元,每个图元存储起始和终止时刻的顶点位置,求交时根据光线时间戳插值顶点位置。
隐式曲面
对于 SDF(Signed Distance Field)定义的隐式几何体,BVH 叶子节点存储包围盒内的 SDF 采样网格。遍历到叶子后,使用 sphere tracing 或 ray marching 在局部空间进行精细求交。注意 SDF 的梯度计算需要中心差分,步长建议设为包围盒对角线的 1/1000。
动态场景的更新策略
完全重建 BVH 在动态场景下开销过高。可采用的优化方案包括:
- 局部更新:仅对发生变化的子树进行重构,保持其余部分不变
- 重构阈值:当变化图元数超过总图元数的 10%-20% 时触发完全重建
- 双缓冲结构:使用两棵 BVH 交替更新,避免遍历与构建的同步开销
实现检查清单
- 构建阶段使用 SAH + 距离混合启发式,采样 32 个候选分割平面
- 叶子节点最大图元数设为 4(GPU)或 8(CPU)
- 逆方向计算加入 1e-8 级别的 padding 防止除零
- Slab 求交使用 robust min/max 避免 NaN 传播
- 节点结构 32 字节对齐,使用静态栈(深度≤48)
- 实例化使用两层 BVH,注意光线变换的精度损失
- 动态场景设置 10%-20% 的重构阈值,考虑双缓冲方案
资料来源
- "An Improved Ray Tracing Acceleration Algorithm Based on Bounding Volume Hierarchies" (2022) - SAH 与空间距离混合启发式
- "Robust BVH Ray Traversal" (JCGT) - 数值鲁棒性与 padding 策略
- "A Survey on Bounding Volume Hierarchies for Ray Tracing" - BVH 技术综述
内容声明:本文无广告投放、无付费植入。
如有事实性问题,欢迎发送勘误至 i@hotdrydog.com。