SVGF

28 Jul 2026

Reading time ~1 minute

…

Ray Tracing Gems: A Fast and Robust Method for Avoiding Self- Intersection

在光线追踪中,从表面交点继续发射阴影、反射或折射光线时,新光线有时会立刻再次命中当前表面,从而产生异常黑斑、条纹等自遮挡现象。这通常不是真实的遮挡,而是浮点数误差引起的自相交(Self-Intersection):自相交是原因,自遮挡是最终表现。

光线与三角形求交后,我们会根据交点参数或重心坐标重建交点位置 $p$。在精确数学中,$p$ 应当位于三角形平面上;但受浮点数精度限制,计算结果可能略高于或略低于真实表面。如果交点落在表面下方,从该点发射的次级光线就可能再次命中当前三角形或相邻三角形。

常见方法及其局限

1. 忽略当前三角形

记录当前命中的三角形 ID,并在次级光线再次命中相同 ID 时忽略该交点。这种方法实现简单,但存在以下问题:

  • 在掠射角(Grazing Angle)下,光线可能命中相邻三角形,而不是原三角形;
  • 无法正确处理重叠、共面或距离非常近的几何体;
  • 某些情况下,光线本来就应该再次命中同一个三角形。

2. 设置固定的 tMin

将光线的有效区间设置为 $t \in [\varepsilon, t_{\max}]$,忽略距离原点小于 $\varepsilon$ 的交点。

固定的 $\varepsilon$ 不具备尺度不变性:对于大型或远离原点的场景,它可能太小;对于微小、紧密的几何结构,它又可能太大。此外,在掠射角下,光线沿几何法线方向产生的实际位移很小,因此光线仍可能位于表面下方。

3. 沿着色法线偏移

着色法线(Shading Normal)通常由顶点法线插值得到,主要用于获得平滑的光照效果。它不一定与真实三角形平面正交,因此沿着色法线偏移,可能无法以最短距离离开表面,甚至可能把交点移动到几何体内部。

沿几何法线进行自适应偏移

几何法线(Geometric Normal)始终垂直于三角形平面。与其他方向相比,沿几何法线偏移能够以更小的位移离开表面,因此更适合用来修正次级光线的起点。

这里不能简单地使用固定偏移。浮点数保持的是近似固定的相对精度,而不是固定的绝对精度:坐标的绝对值越大,相邻可表示浮点数之间的间隔也越大。因此,交点离世界坐标原点越远,重建交点时的绝对误差通常越大;三角形尺寸越大,参与计算的数值越大,也可能进一步放大误差。

换句话说,可靠的偏移量应当同时适应交点坐标和几何尺寸的数量级,而不能依赖一个对所有场景都相同的固定 Bias。

图片占位符

实现时,我们不直接给交点坐标加上固定的小数,而是将每个浮点分量的二进制表示重新解释为整数,再根据几何法线的方向移动若干个浮点刻度,也就是 ULP。

浮点数相邻刻度的间隔会随着数值大小自动变化,因此,同样的整数刻度偏移会产生不同的实际位移:

  • 坐标较小时,实际偏移较小;
  • 坐标较大时,实际偏移也会相应增大。

这样,偏移量便能自动适应交点坐标的数量级,无须针对不同场景手动调整参数。

接近零的位置需要单独处理。此时,通过整数表示移动若干刻度产生的位移可能小得不足以覆盖求交误差。因此,对于绝对值小于阈值的坐标分量,代码会直接沿几何法线增加一个很小的固定浮点偏移。三个坐标分量需要分别判断,因为同一个交点可能同时包含接近零和数值很大的分量。

下面代码中的常量来自实验测得的最大误差,并额外保留了一定的安全裕度:

constexpr float origin()      { return 1.0f / 32.0f; }
constexpr float float_scale() { return 1.0f / 65536.0f; }
constexpr float int_scale()   { return 256.0f; }

// n 为朝向次级光线发射侧的几何法线
float3 offset_ray(const float3 p, const float3 n)
{
    int3 of_i(
        int_scale() * n.x,
        int_scale() * n.y,
        int_scale() * n.z
    );

    float3 p_i(
        int_as_float(float_as_int(p.x) + ((p.x < 0) ? -of_i.x : of_i.x)),
        int_as_float(float_as_int(p.y) + ((p.y < 0) ? -of_i.y : of_i.y)),
        int_as_float(float_as_int(p.z) + ((p.z < 0) ? -of_i.z : of_i.z))
    );

    return float3(
        fabsf(p.x) < origin() ? p.x + float_scale() * n.x : p_i.x,
        fabsf(p.y) < origin() ? p.y + float_scale() * n.y : p_i.y,
        fabsf(p.z) < origin() ? p.z + float_scale() * n.z : p_i.z
    );
}

方法的边界

自适应几何法线偏移可以显著降低自相交的概率,但仍然无法覆盖所有极端情况。

例如,对于又深又窄的缝隙,如果缝隙宽度小于偏移距离,那么沿几何法线移动光线原点时,可能直接越过对面的表面,或者把新的光线原点移动到同一物体或相邻物体内部。

图片占位符

这种问题体现了偏移策略本身的取舍:

  • 偏移太小,无法可靠避开自相交;
  • 偏移太大,又可能跳过非常细小的几何结构。

因此,该方法不能保证所有场景都绝对正确,但相比固定 tMin、忽略当前三角形或沿着色法线偏移,它具有更好的尺度适应性和稳定性。



Share Tweet +1