Nonlinear Ray Tracing for Displacement and Shell Mapping
ZOZO
一句话总结
把 shell 空间里的直线光线在纹理空间里表示成一条二次有理函数曲线,从而直接在纹理空间中解析地做加速结构遍历与微三角形求交,统一且高效地实现了免细分的置换贴图(displacement mapping)和平滑壳映射(shell mapping)。
研究背景
- 领域现状:置换贴图和壳映射都是在基网格(base mesh)与其偏移网格之间的一层”壳”里生成精细几何的技术。置换贴图生成高度场,壳映射更通用,可在壳内实例化任意物体(如编织线、羽毛)。实现路线大致两类:一类在世界空间里追直线光线(需预细分或在世界空间做求交),另一类在纹理空间里做 ray marching。
- 核心痛点:壳空间到纹理空间的映射是非线性的,所以壳空间里的直线光线到了纹理空间就变成了曲线,这使得”同时兼顾高性能、低内存、可交互、易实现”很难。预细分性能高但内存爆炸且无法交互编辑;免细分方法(Thonat 等)用 minmax mipmap 加仿射算术在线生成包围盒,省内存但生成的包围盒在世界空间中互相重叠、需要在世界空间做求交(要矩阵求逆),当基网格三角形在 \(uv\) 空间退化成点或线时会直接失败;壳映射的传统做法依赖四面体化 + ray marching + 距离图,初始化开销大、分段线性近似带来走样,且几何复杂度受三维距离图分辨率限制。
- 本文 idea:不再追直线光线,而是把非线性光线显式写成一个分子分母都是二次多项式的有理函数(以高度参数 \(h\) 为自变量),把包围盒求交和微三角形求交全部搬到纹理空间里解析求解。这样既避免了仿射算术,也避免了世界空间求交所需的矩阵求逆,还去掉了壳映射的四面体化和 ray marching。
方法
整体框架:光线在世界空间中是直线 \(I(t) = \boldsymbol{o} + \hat{\boldsymbol{\omega}} t\),但沿壳内前进时,其在规范空间坐标 \((\alpha, \beta, h)\) 和纹理空间坐标 \((u, v, h)\) 下都是关于 \(h\) 的二次有理曲线。方法用两级加速结构:顶层 BVH(TLAS)用直线光线遍历壳的棱柱(prism),命中棱柱后转入底层结构(BLAS),在纹理空间里用非线性光线遍历——置换贴图用 minmax mipmap,壳映射用隐式四叉树。
flowchart LR
A["世界空间直线光线"] --> B["TLAS: BVH 遍历棱柱"]
B -->|命中 prism| C["构造纹理空间非线性光线 (二次有理函数)"]
C --> D["BLAS: minmax mipmap / 四叉树"]
D --> E["非线性光线-AABB 求交 (解二次方程)"]
E --> F["非线性光线-微三角形求交 (解三次方程)"]
F --> G["求 t、法线, 着色"]
关键设计:
-
把非线性光线写成二次有理函数。对求交方程两边点乘两个垂直于光线方向的向量 \(\boldsymbol{e}_0, \boldsymbol{e}_1\),消去 \(\hat{\boldsymbol{\omega}} t\),得到关于 \(\alpha, \beta\) 的线性方程组;解出后可证明 \(\alpha\) 和 \(\beta\) 都是 \(h\) 的二次有理函数,因此光线在规范空间可写成 \(I_{\alpha\beta h}(h)\),分母是同一个 \(d_2 h^2 + d_1 h + d_0\)。再把 \(\alpha, \beta\) 线性映射到纹理 \(uv\),得到纹理空间光线 \(I_{uvh}(h)\),分母保持不变。作者对比了另一种”用有理圆锥曲线参数化”的表示,但那会让 \(h\) 也变成有理函数、计算更繁,故选择直接以 \(h\) 参数化。
-
纹理空间里的解析求交。微三角形求交:把纹理空间光线代入微三角形所在平面方程、清分母,得到关于 \(h\) 的三次方程;解出 \(h\) 后再求 \(\alpha, \beta\)。但只用前面那组方程求 \(\alpha, \beta\) 在行列式接近 0 时(例如入射高度 \(h_{in}\) 等于出射高度 \(h_{out}\))不稳健,会出现求交失败的白点。方法把平面从纹理空间转换到规范空间,额外得到一个关于 \(\alpha, \beta\) 的线性方程,凑成三个方程,从中挑行列式绝对值最大的两个来解,显著提升鲁棒性。AABB 求交则是把光线分别代入六个面:\(u, v\) 面各解一个二次方程,\(h\) 面无需解方程(直接由 \(I_{uvh}\) 读出)。
-
世界空间法线的稳健计算。纹理空间法线不能直接用于着色,需通过线性变换 \(\boldsymbol{n} = \boldsymbol{M}^{-T} \boldsymbol{n}_{\alpha\beta h}\) 转回世界空间。由于着色前会归一化,作者用伴随矩阵 \(\boldsymbol{n} = \mathrm{adj}(\boldsymbol{M}) \boldsymbol{n}_{\alpha\beta h}\) 代替逆转置以避免除以行列式,即便棱柱退化成平面也能算出法线。文中还分析了法线无法确定的两种退化情形,并说明它们对应光线与微三角形不相交。
-
两级遍历与工程优化。TLAS 是用表面积启发式构建的 4 叉 BVH,棱柱侧面是双线性面片、用 Reshetov 的方法求交;BLAS 是隐式的 4 叉结构或四叉树(四叉树不占内存,用于沿表面平铺同一物体,方便生成织物、针织)。三次方程用 Yuksel 的求解器(改成显式 FMA)。优化包括:根节点选择与空 texel 丢弃(沿用 Thonat 等)、按命中距离递增排序子节点、用 TLAS 记录的 \(t_{in}, t_{out}\) 与 \(h_{in}, h_{out}\) 做区间裁剪、以及当 texel 的 min/max 相等或微三角形三顶点 \(h\) 相同时退化为标准的直线-平面求交。
实验结果
在 Apple M1 Ultra 20 个 CPU 核上实现于自研渲染器。对置换贴图,作者把自己的方法与预细分(pre-tessellation)在相同场景上对比,重点看内存与光线追踪性能:
| 场景 | 方法 | 内存 | 性能 (M rays/s) |
|---|---|---|---|
| Mountain | 预细分 | 2.6 GB | 24.92 |
| Mountain | 本文 | 42.7 MB | 7.74 |
| Cylinder | 预细分 | 2.6 GB | 23.64 |
| Cylinder | 本文 | 42.7 MB | 5.00 |
| Torus (Fur) | 预细分 | 0.7 GB | 0.49 |
| Torus (Fur) | 本文 | 0.7 MB | 1.09 |
对平坦几何(Mountain、Cylinder),本文方法达到预细分约 20~30% 的速度,但内存降低约两个数量级。对高频毛发几何(Torus Fur),本文只用约千分之一的内存,且速度反而快一倍以上——因为纹理空间的 AABB 在世界空间里表现得像有向包围盒(OBB),包裹更紧。壳映射场景(羽毛、鳞片、裙子、Cornell box、金属兔子)性能在 1.00~9.60 M rays/s,内存均在几十 MB 以内。此外方法能渲染基网格在 \(uv\) 空间退化成点/线的场景,这是最先进的 Thonat 等方法做不到的;壳映射因为直接用 BVH 作加速结构,可复用时空 BVH、可编程实例等成熟技术。
亮点与局限
- 亮点:
- 用一个二次有理函数统一表达非线性光线,把遍历和求交全放到纹理空间解析求解,同时干掉了仿射算术、矩阵求逆、四面体化与 ray marching,思路直观、易实现。
- 内存开销极低(相比预细分降低 2~3 个数量级),对毛发这类高频几何甚至比预细分更快。
- 天然支持基网格在 \(uv\) 空间退化的病态情形,鲁棒性优于此前最先进方法;壳映射端可直接嫁接 BVH 生态的各种技术。
- 局限:
- 因数值误差不完全 watertight,单精度下会有光线穿过几何的漏光,需双精度缓解但仍无保证。
- 不支持向量置换贴图(vector displacement);求置换后表面的面积困难(需算积分)。
- 平滑壳映射在棱柱内 \(C^1\)、棱柱间仅 \(C^0\),在 \(uv\) 不连续处会产生裂缝;论文只在自研 CPU 渲染器上验证,未做与已有方法的定量性能对比。
延伸思考
- 把非线性光线显式写成低次有理函数、从而”化 marching 为解方程”的思路,与用圆弧/抛物线光线做非线性介质传播的工作一脉相承,值得思考能否推广到折射介质、引力透镜等其他非线性光线场景。
- 方法把求交搬进纹理空间以获得类 OBB 的紧包围盒,这与并行把 BVH 转成 OBB 树的工作在动机上相通;若能把该表示适配到硬件光追(避免 intersection shader 造成的性能鸿沟),有望缩小与预细分的差距。
- watertight 与自相交处理是留白最大的方向,结合 watertight 光线-三角形求交、鲁棒 BVH 遍历以及光线原点偏移等已有技术,或可让该方法真正进入产品级渲染管线。