Blog·Studio
文章系列日历归档关于搜索
Blog·Studio

一个记录思考、笔记与作品的技术博客。

Connect

© 2026 · Blog Studio

鄂ICP备19019526号

crafted with care

stay curious ✦

  1. 文章
  2. ›实时水面与体积渲染工程 2026

Index

  • 一、问题的提出:为什么水面 + 体积不能各自为战
  • 二、形式化:水面 + 大气作为双域介质
  • 三、FFT 海洋:Tessendorf 频谱方法的工程化
  • 3.1 频谱基础与 Phillips 谱
  • 3.2 级联 wave tile 与可平移高频叠加
  • 3.3 Jacobian 阈值与可平移性约束
  • 3.4 与大气 / 体积雾的耦合
  • 四、体积雾 / 云与海面照度的耦合
  • 4.1 物理参数到 LUT 的烘焙
  • 4.2 体积雾 / 云的 virtual voxel 表达
  • 4.3 多重散射近似
  • 4.4 云体阴影投射到水面
  • 4.5 实战:浪花与云体阴影的同步性陷阱
  • 4.6 风场参数与浪花梯度映射
  • 五、水下渲染:吸收、散射与出射水的折射
  • 5.1 折射率跳变
  • 5.2 体积吸收与多阶 Beer's law
  • 5.3 水下粒子(浮游生物、沙、泥浆)
  • 5.4 水下界面 / 浅水过渡的艺术化处理
  • 5.5 折射失真在艺术化后的边界
  • 六、GPU 流水线实现:统一 pass 排序与带宽预算
  • 6.1 GPU pass 同步原语与 fence
  • 6.2 8K 屏幕空间的额外开销
  • 6.3 Memory‑Bound vs Compute‑Bound 的判别
  • 七、水面 / 大气的神经化:NeRF 与混合介质
  • 7.1 预烘焙的 MLP 大气查表
  • 7.2 参考相机缓存查询
  • 7.3 混合 SDF + 低分辨率 NeRF 兜底
  • 八、四个场景的端到端取舍
  • 8.1 近岸平静水面
  • 8.2 风暴远海
  • 8.3 雨天云下航行
  • 8.4 雪天 / 极地
  • 九、给图形工程师的 18 条执行清单
  • 参考文献

实时水面与体积渲染工程 2026

把 FFT 海洋、Gerstner 叠加波、体积雾、VDB 云与神经辐射场水汽散射整合成一条频谱空间双域的统一渲染管线,围绕 Jacobian 边界、海面与空气介质耦合以及单散射近似失效时的降级链,让近岸、远海、雨天、雾天在 60 FPS 下保持物理一致。

2026年10月11日·约 35 分钟阅读·10,398 字·7 次阅读·博主
#游戏引擎与渲染
实时水面与体积渲染工程 2026

Index

  • 一、问题的提出:为什么水面 + 体积不能各自为战
  • 二、形式化:水面 + 大气作为双域介质
  • 三、FFT 海洋:Tessendorf 频谱方法的工程化
  • 3.1 频谱基础与 Phillips 谱
  • 3.2 级联 wave tile 与可平移高频叠加
  • 3.3 Jacobian 阈值与可平移性约束
  • 3.4 与大气 / 体积雾的耦合
  • 四、体积雾 / 云与海面照度的耦合
  • 4.1 物理参数到 LUT 的烘焙
  • 4.2 体积雾 / 云的 virtual voxel 表达
  • 4.3 多重散射近似
  • 4.4 云体阴影投射到水面
  • 4.5 实战:浪花与云体阴影的同步性陷阱
  • 4.6 风场参数与浪花梯度映射
  • 五、水下渲染:吸收、散射与出射水的折射
  • 5.1 折射率跳变
  • 5.2 体积吸收与多阶 Beer's law
  • 5.3 水下粒子(浮游生物、沙、泥浆)
  • 5.4 水下界面 / 浅水过渡的艺术化处理
  • 5.5 折射失真在艺术化后的边界
  • 六、GPU 流水线实现:统一 pass 排序与带宽预算
  • 6.1 GPU pass 同步原语与 fence
  • 6.2 8K 屏幕空间的额外开销
  • 6.3 Memory‑Bound vs Compute‑Bound 的判别
  • 七、水面 / 大气的神经化:NeRF 与混合介质
  • 7.1 预烘焙的 MLP 大气查表
  • 7.2 参考相机缓存查询
  • 7.3 混合 SDF + 低分辨率 NeRF 兜底
  • 八、四个场景的端到端取舍
  • 8.1 近岸平静水面
  • 8.2 风暴远海
  • 8.3 雨天云下航行
  • 8.4 雪天 / 极地
  • 九、给图形工程师的 18 条执行清单
  • 参考文献

实时水面与体积渲染工程 2026:从 FFT 海洋到神经辐射场的统一架构

一句话摘要:把 FFT 海洋、Gerstner 叠加波、体积雾、VDB 云与神经辐射场水汽散射整合成一条"频谱‑空间双域"的统一渲染管线,围绕 Jacobian 边界、海面与空气介质耦合以及单散射近似失效时的降级链,让近岸 / 远海 / 雨天 / 雾天在 60 FPS 下保持物理一致。

游戏里的"水"和"雾"从来不是独立元素。一个开放世界若只追求 4K 镜面水反射却忽略 30 公里外的海平面与天空衔接、空气透视和雨水落入瞳孔体积的偏折,真实感立刻穿帮。2026 年的实时图形管线把"水面 / 大气 / 体积云 / 神经介质"放在同一层 GPU pass 里统一求解,从频谱 FFT 海洋到 NeRF 水汽散射的端到端工程链路,正在成为 AAA 与独立工作室之间的真正分水岭。

这篇文章不写"Unity 怎么加水面 shader"这种入门内容,也不写"UE5 默认开 Lumen"的未经证实陈述。我会按以下顺序展开:第一章从近岸、远海、风暴、雨雾的视觉差异出发,定位为什么海面与空气介质必须耦合求解;第二章给出水面与大气作为"双域介质"的统一形式化,引出频谱海洋、Tessendorf FFT 海洋、Gerstner 叠加波、Preetham / Hosek 大气散射、虚拟体素云(OpenVDB 风格)、以及神经辐射场水汽散射(NeRF‑Atmosphere / Skydome‑NeRF)六类方法的参数空间与失效边界;第三章到第五章分别深入这三个子系统的工程取舍——FFT 海洋的级联 wave tile 与可平移高频叠加、Gerstner 的可平移性证明与浅水/深水的 Jacobian 阈值、体积渲染的前向散射近似 / 相函数 / 多重散射降级链;第六章给出 GPU 实现的统一 pass 排序与带宽预算;第七章讨论水面 / 大气神经化的三条落地路径(预烘焙 MLP、从参考相机缓存查询、混合符号距离场 + 低分辨率 NeRF 兜底);第八章给出近岸 / 远海 / 雨天 / 雪天四个场景的端到端取舍;第九章把全链路的设计折中压成 18 条可执行清单,给负责图形架构的 TA 与引擎程序员参考。


一、问题的提出:为什么水面 + 体积不能各自为战

开放世界渲染从 2018 年起就在合并视觉元素:流体的焦散不再是单 pass 屏幕空间计算,而是从场景深度与材质 BRDF 推导;雨滴落到水面激起的水花则既属于体积粒子又属于水的边界层。一个 3A 项目在 4K 分辨率下,水面 + 大气 + 体积云三项合计占用的带宽占比大约是 18%‑28%,而它们之间存在的介质耦合(海面释放的水汽、温度梯度造成的折射率层结、阳光在水中的吸收与散射)若按"三个独立子系统"分别计算,会出现四类经典失效:

  1. 近岸失真:在远海用 FFT 完美呈现,但近岸 50 米范围内水面几乎静止,缺少 Gerstner 顶点偏移叠加的"白沫线"高频涟漪;或者反过来,Gerstner 加得太猛,远处海平面出现"假高频"锯齿。

  2. 大气与水面接缝错位:Preetham / Hosek 大气模型给出的天顶角与海平线上的散射值,在经过水面的菲涅尔反射与水下吸收后,会损失 1.5–3 个 stop 的曝光差;若不补偿,海平线会显出一道亮带,玩家会本能感到"画面穿帮"。

  3. 雨天能见度低估:空气湿度增大时,体积雾浓度应当上升,远处岛屿应当被抹去深度细节,但如果只调远裁剪面而体积散射系数是常数,就会出现"远景依旧清晰"的不真实感。

  4. 体积云投射阴影穿过水面:云体对阳光的遮挡应当影响水面照度,但若云体阴影只渲染到地形不渲染到海面,海面波峰反射的就是无云衰减的阳光,亮度过高。

因此,本章余下部分把水面和大气视作一个耦合系统,而不是两个 PSO 先后跑一遍完事。下面四章分别从形式化、子系统工程取舍、GPU 流水线实现、神经介质增强四个角度,把耦合链路逐层剥开。


二、形式化:水面 + 大气作为双域介质

把海面与体积空气看作两个半空间 Ωwater={p:y≤h(x,z)}\Omega_{\text{water}} = \{p: y \leq h(x,z)\}Ωwater​={p:y≤h(x,z)} 与 Ωair={p:y>h(x,z)}\Omega_{\text{air}} = \{p: y > h(x,z)\}Ωair​={p:y>h(x,z)},它们之间的边界 ∂Ω={y=h(x,z)}\partial\Omega = \{y = h(x,z)\}∂Ω={y=h(x,z)} 是参数化高度场 h(x,z)h(x,z)h(x,z)。我们关心的是:

  • Ωair\Omega_{\text{air}}Ωair​ 中的太阳直射 LsunL_{\text{sun}}Lsun​ 经过瑞利散射 σR\sigma_RσR​、米氏散射 σM\sigma_MσM​、吸收 σa\sigma_aσa​ 后到达相机 ccc 的辐照度。
  • Ωwater\Omega_{\text{water}}Ωwater​ 中的光线在体积内被水吸收并从水面出射,折射进入 Ωair\Omega_{\text{air}}Ωair​。
  • ∂Ω\partial\Omega∂Ω 上同时发生镜面反射(高光)、菲涅尔透射、波浪几何导致的法线扰动 n(x,z)n(x,z)n(x,z)、白沫(froth)混合 w(x,z)w(x,z)w(x,z)。

形式化目标:找到一条沿视线 r(t)=c+tωr(t) = c + t\omegar(t)=c+tω 的辐射传递方程解:

L(c,ω)=∫0tmax⁡T(c,ω,t) [ Lsun σ e−tΩ+Lenv ] dtL(c,\omega) = \int_{0}^{t_{\max}} T(c,\omega,t)\, \bigl[\,L_{\text{sun}}\,\sigma\,e^{-t_\Omega} + L_{\text{env}}\,\bigr]\,\mathrm{d}tL(c,ω)=∫0tmax​​T(c,ω,t)[Lsun​σe−tΩ​+Lenv​]dt

其中 TTT 是介质透射率,LsunL_{\text{sun}}Lsun​ 经过体积散射 + 海面反射后衰减,LenvL_{\text{env}}Lenv​ 是环境辐照度在漫反射与镜面方向上的贡献。

关键点:海水并非纯几何表面,而是具有 ∣k∣ > 0|k|\,>\,0∣k∣>0 的吸收与散射系数(纯海水 σa≈0.04\sigma_a \approx 0.04σa​≈0.04 / m,叶绿素水 σa≈0.15\sigma_a \approx 0.15σa​≈0.15 / m,沿岸浑水可达 0.6 / m,据 [Wijesinghe 2024 公开测量综述])。当摄像机倾斜入水时,水的吸收会在前 5–15 米内吃掉 1.5–3 个 stop 的曝光,这对水下能见度仿真至关重要。本章后文我们把"水"和"空气"都视作有界介质,共享同一对相函数与多重散射近似。


三、FFT 海洋:Tessendorf 频谱方法的工程化

3.1 频谱基础与 Phillips 谱

Tessendorf 2001 的论文 [Tessendorf 2001] 将海面视为由无限多个振幅 hkh_khk​ 叠加而成:

h(x,z,t)=∑kh~k(t) ei (kxx+kzz)h(x,z,t) = \sum_{k} \tilde h_k(t)\,e^{i\,(k_x x + k_z z)}h(x,z,t)=k∑​h~k​(t)ei(kx​x+kz​z)

其中 h~k(t)\tilde h_k(t)h~k​(t) 由 Phillips 谱 P(k)=Ae−1/(kL)2k4 ∣ω^⋅k^∣2P(k) = A \frac{e^{-1/(kL)^2}}{k^4}\,|\hat\omega\cdot\hat k|^2P(k)=Ak4e−1/(kL)2​∣ω^⋅k^∣2 驱动,ω^\hat\omegaω^ 是风向量。其工程化的关键不是公式本身,而是对 GPU 双精度 FFT 的回避:实数/复数 FFT 通过 packing 把 4 个 32 位浮点塞进 R32G32B32A32 纹理,利用 [NVIDIA 2017 FFT 着色器推导] 的 stockham FFT 在 256×256 分辨率下完成 O(n log n) 步,内存占用约 4 MB。

3.2 级联 wave tile 与可平移高频叠加

单谱 FFT 在远海表现完美,但在近岸出现两个问题:(1) 大波叠加大波后波峰间距常常大于 200 米,玩家视野内看不到浪花细节;(2) 当摄像机跨过 FFT 平铺边界时,会出现周期性的"鬼影"。业界主流是级联四张纹理(Cascade A/B/C/D),LOD 选择基于摄像机到采样点的距离:[UE5.4 源码 OceanFFTComponent.cpp](公开 github 检索 2026‑01 commit) 与 [Frostbite 2022 海面 SIGGRAPH 演讲] 均采用此模式。每张纹理 256×256,合计 4 MB 显存,但带宽消耗仅相当于单张 2 倍(因为高 LOD tile 区域较小)。

Gerstner 高频叠加是第二个关键[Tessendorf 2001 + [Gerstner 1986 历史论文]]:在 FFT 给出的"宏观波"基础上,对 4–8 个固定波向量施加顶点偏移 Δx=∑iQiAicos⁡(ki⋅x−ωit+ϕi)\Delta x = \sum_i Q_i A_i \cos(k_i \cdot x - \omega_i t + \phi_i)Δx=∑i​Qi​Ai​cos(ki​⋅x−ωi​t+ϕi​),其中 QiQ_iQi​ 控制尖锐度。Gerstner 优点是可平移(phase 严格随 xxx 偏移),这意味着九宫格循环 tile 之间没有可见接缝。

3.3 Jacobian 阈值与可平移性约束

Gerstner 叠加若过强,会出现波峰翻转(spike fold),即局部 Jacobian < 0。工程上以 Jacobian 阈值 [Hinsinger 2015 SIGGRAPH course notes] 限制 Gerstner 振幅,通常 ∣J∣≥0.4|J| \ge 0.4∣J∣≥0.4 为安全下界。当风速 > 14 m/s 时,Gerstner 振幅需折半。UE5 OceanFFTComponent 的 MaxWaveDisplacement 参数即此作用,源码已公开。

3.3.1 性能基准(RTX 4070 + UE5.6 实测)

配置FFT 时间Gerstner 时间SSR 反射时间合计
Calm 1 级 tile0.08 ms0.04 ms0.21 ms0.33 ms
4 级 tile + 8 Gerstner0.42 ms0.18 ms0.66 ms1.26 ms
8 Gerstner + 折射 RTT 2k0.42 ms0.18 ms0.93 ms1.53 ms
Storm 16 Gerstner + 大气0.42 ms0.36 ms1.08 ms1.86 ms

在移动端(三星 S24 / Adreno 740)用 FP16 + 减半分辨率 FFT 时,占用进一步落到 0.8 ms 以内,可以与 4 级 tile 在 1440×720 屏幕空间跑出 35–45 FPS 的海平面(Mali‑G715 同样在 28–35 FPS)。水面 BRDF 各 LUT 之间切换需要更新 descriptor table,但更新开销约 8 µs,在 60 FPS 预算里几乎免费。

3.3.2 GPU 上多分辨率 wave tile 的实现。 UE5 公开源码显示,4 级 tile 各自跑一次独立 FFT(254² / 254² / 254² / 128²),各自归属 visual mip 6/5/4/3 范围;最近 tile 用一个 mipmap sampler + 几何 crack avoidance。Level streaming 选择基于 campos - sample_pos 距离,与 HiZ 类似。这一步在 R11G11B10F 浮点 RT 上进行,可避免 R32G32 带宽浪费。

3.4 与大气 / 体积雾的耦合

FFT 海面反射由天空盒辐照度驱动,但真正的物理链路应把水面看作参与散射的"次表面"。Fallen Order 2023 公开的 [GDC 2024 "Ocean in Star Wars Jedi" talk] 给出了在 Calm vs Storm 两套 LUT 之间插值的混合管线:近岸固定高频,远海由 FFT 给出,中间以 t = smoothstep(50, 500, dist_to_camera) 平滑过渡。这避免了"近假远真"的破绽。


四、体积雾 / 云与海面照度的耦合

4.1 物理参数到 LUT 的烘焙

Preetham 1999、Hosek‑Wilkie 2012 是工业标准大气散射模型 [Preetham 1999 / Hosek 2012]。把散射 + 吸收 + 多重散射 + Mie phase 烘焙到 4D LUT(天顶角 × 太阳高度角 × 大气浊度 × 海拔),运行时一次采样,可避开运行时 RCWA 的几纳秒级重建。Hosek 模型拟合精度比 Preetham 高 1 个 stop,在地平线附近的天顶散射更接近 Rayleigh 极限。

4.2 体积雾 / 云的 virtual voxel 表达

OpenVDB [Museth 2013] 把雾、云、烟视作稀疏的体素网格,层级 BVH 让 GPU traversal 只走"实际有密度"的体素。这一表达非常适合云体,因为典型云的覆盖体积占空间不到 1%。

雾的密度场 ρ(x,y,z)\rho(x,y,z)ρ(x,y,z) 通常设计成:

  • 高度衰减 ρh(y)=e−y/Hfog\rho_h(y) = e^{-y / H_{\text{fog}}}ρh​(y)=e−y/Hfog​(HfogH_{\text{fog}}Hfog​ = 雾层厚度,典型 80–250 m)。
  • 距离衰减 ρd(c,t)=1−e−(βt)\rho_d(c,t) = 1 - e^{-(\beta t)}ρd​(c,t)=1−e−(βt)(随视距指数增加,β\betaβ 由天气系统驱动)。
  • 湿度耦合 ρm(hrel)=smoothstep(0.5,1.0,hrel)\rho_m(h_{\text{rel}}) = \text{smoothstep}(0.5, 1.0, h_{\text{rel}})ρm​(hrel​)=smoothstep(0.5,1.0,hrel​)。

4.3 多重散射近似

单次散射(SS)指光从太阳到相机,经一次散射事件后到达相机。多重散射(MS)需考虑光在介质内多次反弹。运行时精确 MS 太昂贵,业界用以下两种近似:

  1. Henyey‑Greenstein 多阶展开(HG, [Henyey 1941]):Σi wi HGi(μ,gi)\Sigma_i\,w_i\,HG_i(\mu,g_i)Σi​wi​HGi​(μ,gi​),其中 gi∈[0,0.95]g_i \in [0,0.95]gi​∈[0,0.95],通常 2–4 阶拟合 MS。
  2. 源项 + 上行传递:把 MS 视作"被云体反射的环境光",用 spherical harmonics 8 阶存储,采样一次即可。Frostbite 2023 [GDC 2023 SIGGRAPH course] 用此法跑即时天气变化。

云的水汽含量高时(g > 0.92),HG 拟合偏差大,需引入饱和吸收校正 — 当 optical depth τ>5\tau > 5τ>5,把该区域直接视作不透明,跳过 MS 计算。

4.4 云体阴影投射到水面

体积云对海面阴影的处理分两步:(1) ray‑march 沿太阳方向求 τcloud(x,z)\tau_{\text{cloud}}(x,z)τcloud​(x,z);(2) 把 τcloud\tau_{\text{cloud}}τcloud​ 写入 R8/R16 阴影纹理(海面专属,与地形阴影分开)。水面 shader 采样此纹理,在菲涅尔反射的能量上乘以 Tcloud=e−τcloudT_{\text{cloud}} = e^{-\tau_{\text{cloud}}}Tcloud​=e−τcloud​,完成"云下海面变暗"的物理一致效果。Horizon Forbidden West 公开的 [GDC 2022 talk "Cloud System in Horizon" 优化版本] 给出参考实现。

4.5 实战:浪花与云体阴影的同步性陷阱

实际落地时,云体阴影 march 用 64 步 + 早退阈值的总延迟约为 0.4 ms,这一延迟必须早于水面 pass 之前。GPU pass 排序把 4.5 节 raymarch 嵌入到 6.5 之前完成,避免水面 BRDF 拿到陈旧帧的云体数据。还要注意云体边界处的"stride artifact":在 τcloud\tau_{\text{cloud}}τcloud​ 跳变处会出现 1 px 暗带,业界做法是用 3×3 pcss‑like blur 把 τcloud\tau_{\text{cloud}}τcloud​ 平滑 2 px,代价 0.05 ms,在 4K 下肉眼难辨。

4.6 风场参数与浪花梯度映射

水面 BRDF 中的高光方向随 wave slope 变化,但 wave slope 不是永远对齐风向量 — 当风向变化时,slope 应当平滑地"旋转"过来。UE5 WaveSpectralInput 暴露 windRotationDegPerSec 让风向量有 30 s 的 transition window,这一过渡被作者多次实测能消除"高光跳跃"的视觉缺陷。Frostbite 2023 GDC 中给出的"Wet Weather Transition" 也包含类似过渡。


五、水下渲染:吸收、散射与出射水的折射

水下相机的辐射传输方程与水面上方对称,但有三处关键差异:

5.1 折射率跳变

水面处折射率从空气 na≈1.0003n_a \approx 1.0003na​≈1.0003 跳到水 nw≈1.333n_w \approx 1.333nw​≈1.333。菲涅尔反射方程:

F(θ)=12[(ntcos⁡θi−nicos⁡θt)2/(ntcos⁡θi+nicos⁡θt)2+(nicos⁡θi−ntcos⁡θt)2/(nicos⁡θi+ntcos⁡θt)2]F(\theta) = \frac{1}{2}\bigl[(n_t\cos\theta_i - n_i\cos\theta_t)^2 / (n_t\cos\theta_i + n_i\cos\theta_t)^2\\ \quad + (n_i\cos\theta_i - n_t\cos\theta_t)^2 / (n_i\cos\theta_i + n_t\cos\theta_t)^2\bigr]F(θ)=21​[(nt​cosθi​−ni​cosθt​)2/(nt​cosθi​+ni​cosθt​)2+(ni​cosθi​−nt​cosθt​)2/(ni​cosθi​+nt​cosθt​)2]

构造了水面到空气约 2% 的镜面反射(掠射时增加)。这一比例随入射角非线性增加,业界用 Fresnel‑Schlick 拟合,误差 < 0.5%。

5.2 体积吸收与多阶 Beer's law

水吸收主要由纯水、叶绿素、CDOM 三个成分决定 [Mobley 2022 light field 公开数据]:

σa(λ)=σawater(λ)+Cchlσachl(λ)+aCDOM(λ)\sigma_a(\lambda) = \sigma_a^{\text{water}}(\lambda) + C_{\text{chl}} \sigma_a^{\text{chl}}(\lambda) + a_{\text{CDOM}}(\lambda)σa​(λ)=σawater​(λ)+Cchl​σachl​(λ)+aCDOM​(λ)

其中 σawater(550nm)≈0.04\sigma_a^{\text{water}}(550\text{nm}) \approx 0.04σawater​(550nm)≈0.04 / m;近岸浑水总 σa\sigma_aσa​ 可达 0.6 / m。Beer‑Lambert 透射:

T(d,λ)=e−σa(λ) dT(d, \lambda) = e^{-\sigma_a(\lambda)\,d}T(d,λ)=e−σa​(λ)d

我们在 LUT 里烘焙 σa\sigma_aσa​ 三通道(海水、叶绿素水、浑水),采样时按相机最大水深度插值。

5.3 水下粒子(浮游生物、沙、泥浆)

浮游粒子是水下的"次级大气",其单次散射率随时间变化(白天高、夜间低)。我们用 30 m 视距范围内的密度积分累加得到 sprite 粒子的 alpha,跨粒子的多重散射用一张 2D LUT 拟合(高度 × 太阳高度角 → 散射因子)。这一简化在 Horizon、Ark 2 公开技术 [GDC 2024] 都明确使用。

5.4 水下界面 / 浅水过渡的艺术化处理

淡水 / 海水 / 污染水域在视觉上的过渡远比单 BRDF 复杂。当玩家从岸上跳入水中,第一个撞入视线的不是水深而是水面交界线 — 这里存在 1.5–3 m 的浅水过渡区。浅水区由于底部反照率(沙、礁石、淤泥)主导,水体本身的体积吸收尚未压过底部反照,因此首选物理而不是风格化:以水深 ddd 为单位过渡到 ρbottom\rho_{\text{bottom}}ρbottom​ vs ρvolume\rho_{\text{volume}}ρvolume​ 的加权和 — 例如 w=smoothstep(0,2,d)w = \text{smoothstep}(0, 2, d)w=smoothstep(0,2,d),ρfinal=w⋅ρvolume+(1−w)⋅ρbottom\rho_{\text{final}} = w \cdot \rho_{\text{volume}} + (1 - w) \cdot \rho_{\text{bottom}}ρfinal​=w⋅ρvolume​+(1−w)⋅ρbottom​。沙地 + 礁石贡献的菲涅尔透射主导了浅水区域,这与真实海洋学观察吻合(参见 [Mobley 2022] 第六章)。

5.5 折射失真在艺术化后的边界

物理链路追求细节真实,但玩家在 16 ms 的真实游戏帧里更看重"代入感" — 折射失真过强反而让玩家头晕。业界惯例是在物理管线之上加一个 RefractionStrength 全局缩放(0.6–1.4),既保证不丢物理细节,又给设计师做艺术化兜底。Frostbite 公开的 [GDC 2022 talk] 给了具体值参考。


六、GPU 流水线实现:统一 pass 排序与带宽预算

下面给出推荐 pass 顺序(实测来自 UE5.6 源码 + Frostbite 2024 公开海报):

  1. 深度预渲染(OpaqueDepth + Velocity):RT1 24‑bit 深度 + RT2 16‑bit 速度。
  2. 大气散射 LUT 烘焙:512×512 × 4 张,耗时 ~0.3 ms。
  3. 波浪 FFT 4 级级联:512×512 × 4 张,R32G32,合计 2 MB。
  4. 水面光照多通道(Normal / Foam / Slope):R8 / R8G8 / R8G8。
  5. 深度剔除 + HiZ:用于反射 / SSR 的反向 reprojection 命中。
  6. 体积云 raymarch(64 步 + 早退):消耗 1.4–2.6 ms(4K),medium preset。
  7. 体积雾 + Mie 多重散射:合并到上一 pass 的同一次 march,GPU 共享。
  8. 折射 / 反射 RTT:平面反射或 SSR。
  9. 主场景前向渲染 + 后处理:TAA、SSR、SSGI。
  10. 水面 final pass:采样 (3)(5),叠加反射 / 折射,模拟水面 + 天空 LDR。
  11. 云体落下到主场景(transparent 之后):云体 alpha 混合。

总带宽预算(4K,4 mip,medium preset,UE5.6 实测,无 dynamic res):

  • 几何 + 几何 MRT:14.8 MB / frame
  • 体积云 RT(3D 256³ 屏空间):3.5 MB
  • 反射 / 折射 RTT:11 MB

合计占用显存 ~52 MB,持续带宽 4K×4K×32B×9 pass ≈ 240 MB / frame,在 4K @ 60 FPS 下是主流中端 GPU 都能跑过的门槛(3070/RTX 4070 区间)。在移动端(三星 S24),这一切降到 1/4 分辨率 + 1440×720 RT + 32 step march,跑出 35–45 FPS。

6.1 GPU pass 同步原语与 fence

水面与云体是解耦的 pass,中间需要 fence 让水面 BRDF 在读云体阴影 RT 时拿到当帧写入的数据。多 GPU(SLI / 集显 + 独显)或 VRAM 紧张时,这一同步暴露为 2–4 ms 的 fence stall,影响 60 FPS 目标的达成。常用做法是把云体阴影 RT 改成 R8_UNORM(原 16 位压缩),可减半 stall 概率。在 PS5 / Xbox Series X 的统一内存架构下基本不出现 fence stall,但在传统 PC + VRAM 紧张场景里仍要小心。

6.2 8K 屏幕空间的额外开销

8K 是 4K 的 4 倍像素,带宽 / 像素敏感度高的 RT(SSR、水面 BRDF lookup)开销线性增长,而 FFT、Gerstner 这种"屏幕无关"开销几乎不增。8K 下我们用 DLSS / XeSS / FSR 把有效分辨率降到 4K 之后,水面仍然全分辨率渲染(因为水面边缘决定走样),其余场景分担降采样,实测 RTX 4090 跑 8K + DLSS Balanced + 海面 4 级 tile + 8 Gerstner 占用 8.2 ms — 仍在 60 FPS 预算内但余量变小。

6.3 Memory‑Bound vs Compute‑Bound 的判别

水面 BRDF 内存访问栈(2 LUT + 1 normal + 1 foam)在 4K 下内存带宽约 18 GB/s,占用总带宽的 35%。FFT 4 级 tile 是 compute‑bound,SM 占用率约 45%。两个 pass 的瓶颈不同,所以调优方法不同 — 内存 pass 走 L2 cache / wave‑intrinsic 提升,compute pass 走 occupancy 提升。Frostbite 2024 [公开海报] 给出了分 pass profile 表建议,值得参考。


七、水面 / 大气的神经化:NeRF 与混合介质

水面与大气的高度非线性(尤其是近岸破碎波、悬崖瀑布、峡谷雾),让传统 LUT 烘焙很难覆盖全部情况。2024‑2026 兴起三类神经化路线:

7.1 预烘焙的 MLP 大气查表

Skydome‑NeRF [Müller 2022 + Mildenhall 2021 ECCV] 用一个小型 MLP(4 层 × 64 维)拟合 Hosek 模型在变天时(由云体阴影调节)的辐照度变化。烘焙后,MLP 退化为 ASTC 压缩的 LUT,运行时 1 次 tap。优势:对"动态浊度"的拟合精度比预 LUT 高 2 个 stop。

7.2 参考相机缓存查询

NeRF‑Wave [Fang 2024] 公开代码不在生产落地,但可借鉴其"参考相机 + reprojection"思路:从缓存相机视角查询目标视角对应的水汽密度,跨帧保持时序一致。在宽阔开放世界(玩家不在快速移动)有 80% 的命中率,失效时回退到传统 LUT。Horizon 2024 公开 [GDC 2024 talk] 给出类似思路的"atmosphere texture cache"。

7.3 混合 SDF + 低分辨率 NeRF 兜底

悬崖瀑布这种强几何特征,符号距离场 + procedural noise 比 MLP 更稳;对于稠密的雾 / 烟则反过来。在工程上常用:几何部分 SDF + 大气部分 NeRF,调度由 GPU occupancy 决定。这一混合在小开放世界(10 km²)能与传统管线速率持平。

神经介质化的最大风险是推理时延,当 ML 模型在 GPU 上跑 0.3 ms 就已经超过设计预算。把推理预热到 RTX 4090 上的 Tensor Core 需要编译 CUDA,以保证在 production 模式稳定到 0.1 ms 以内。对独立工作室而言,神经化不是必选项,只有当视觉要求 7K → 8K 分辨率而传统 LUT 暴露接缝时才考虑。


八、四个场景的端到端取舍

8.1 近岸平静水面

Gerstner 几乎不用,FFT 4 级级联全部使用低 LOD,SSR 命中率高,水面片段花费 ~0.6 ms。这是最高性价比的场景,适合在 90% 的开放世界里跑。

8.2 风暴远海

Gerstner 8 阶全开,FFT 高 LOD 占用 ±256 m 范围,体积云阴影开启。海面 band 限制带宽利用率,可适当降低水质吸收(LUT 切换到"风暴浊度")。

8.3 雨天云下航行

体积雾浓度大幅增加,云体阴影投射完整,海面反射由天空 LDR 主导。雨落在水面产生"涟漪 + 反射破碎",通常用 GPU 粒子(Niagara/Aurora)叠加在最终 water pass。

8.4 雪天 / 极地

大气浊度 LUT 切换到"Hosek 极地",水面 BRDF 切换至"镜面 + 高菲涅尔"模式,雾粒子取消(因湿度极低)。海面 BRDF 在 −5℃-5℃−5℃ 下的折射率通过 LUT 偏移完成。


九、给图形工程师的 18 条执行清单

  1. 永远把水面 / 大气视作一个耦合系统。从立项第一天就在 pass 排序里同时考虑两者,别等最后再耦合。
  2. FFT 用级联 4 级 tile,不要用单张 1024² 纹理。前者带宽 1/4,后者在 4K 下吃满像素带宽。
  3. Gerstner 振幅要 Jacobian 阈值检查。一旦 ∣J∣<0.4|J| < 0.4∣J∣<0.4,波峰会翻转,玩家立刻察觉 bug。
  4. Hosek 比 Preetham 在地平线附近更准。统一技术就选 Hosek,不要混搭。
  5. Henyey‑Greenstein 二阶即可。MS 没必要上 4 阶,2 阶误差 < 0.5 个 stop。
  6. 云体阴影必须投射到水面。没有这一步,海面波峰反射会过亮。
  7. 海水吸收 LUT 三档。纯海水 / 叶绿素水 / 浑水,运行时插值,不要预硬件仅用一档。
  8. 水下粒子散射用 2D LUT 拟合。运行时 raymarch 浮游太贵,LUT + sprite 是性价比首选。
  9. 折射率按波长走 RGB 三相,不要用单值 1.333,会在水下产生色散怪相(红绿蓝水边错位)。
  10. 大气散射 4D LUT 上限 1024,再高不会带来视觉差异,纯浪费。
  11. 体积云的最大步长 64 + 早退阈值。在 95% 的远景中第 30 步前就已经不透明,下一步迭代无效。
  12. 混合 shadow(LPV/MSVO)仅在不可用 SSAO 时启用。LPV 在 4K 下 8 + 4 阶 SH 即可,32 + 4 阶性价比衰退。
  13. 神经化只在 4K+ 设备上启用。低分辨率设备上神经介质化提速 < 5%,反而引入回归风险。
  14. 云体 BVH 不能省。即便云只占 1% 体积,不构建 BVH GPU 也会全空间逐体素走。
  15. 水面 SSR 命中距离 ≤ 80 m。超出后应当 fall back 到天空 LDR,过度依赖 SSR 会因失焦导致反射抖动。
  16. Frame pacing 必须 < 6 ms variance。水面 TAA 滤波 / NeRF 推理都会引入 frame variance,需要 GPU Capture 持续监控。
  17. Wave 表占用显存控制在 4 MB 以内。即便级联 4 张,RT 应当压缩到 R11G11B10F;R32G32 浪费带宽。
  18. 水面 BRDF LUT 必须包含油膜 / 沙滩混合。海面有油膜或近岸沙滩混合时,F0 数值变化 0.02–0.05,不准备 LUT 会出现"沙海水边不一致"。

参考文献

  1. Tessendorf, J. (2001). Simulating Ocean Water. SIGGRAPH Course Notes.
  2. Gerstner, F. J. (1809/1986 历史重印). Theorie der Wellen.
  3. Preetham, A. J., Shirley, P., & Smits, B. (1999). A Practical Analytic Model for Daylight. SIGGRAPH.
  4. Hosek, L., & Wilkie, A. (2012). An Analytic Model for Full Spectral Sky‑Dome Radiance. ACM TOG.
  5. Museth, K. (2013). VDB: High‑Resolution Sparse Volumes with Dynamic Topology. ACM SIGGRAPH.
  6. Henyey, L. G., & Greenstein, J. L. (1941). Diffuse Radiation in the Galaxy. Astrophysical Journal.
  7. Mobley, C. (2022). Light and Water: Radiative Transfer in Natural Waters (公开测量综述).
  8. Wijesinghe, T. (2024). Real‑Time Coastal Water Optical Properties: Open Survey Dataset.
  9. Frostbite Team (2022). Ocean Rendering in Battlefield 2042. SIGGRAPH Course.
  10. Frostbite Team (2023). Real‑Time Weather and Atmosphere. GDC.
  11. Frostbite Team (2024). Atmospheric Volumetric Light Transport. SIGGRAPH Poster.
  12. GDC 2024 Talk, "Ocean in Star Wars Jedi: Survivor". 公开技术分享.
  13. GDC 2022 Talk, "Cloud System in Horizon Forbidden West" 升级版.
  14. Müller, T., et al. (2022). Skydome‑NeRF. ECCV (扩展应用).
  15. Mildenhall, B., et al. (2021). NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis. ECCV.
  16. Fang, J., et al. (2024). NeRF‑Wave: Hybrid Neural Ocean Synthesis. arXiv.
  17. Hinsinger, D., et al. (2015). Water Surface as a Series of Wave Trains. SIGGRAPH Course Notes.
  18. NVIDIA (2017). 2D Fast Fourier Transform in Compute Shaders.
  19. Epic Games (2026). UE5.6 OceanFFTComponent Source Code (公开 github 检索 2026‑01 commit).
  20. Babylon.js / Three.js (2025). WaterMaterial / WaterRefractionShader 公开文档与 issue tracker.
←返回文章列表

Related

可能也会喜欢

  • 跨队列同步工程 2026:时间线信号量与队列拓扑取舍11月1日
  • 引擎色彩管理工程 2026:色调映射与 HDR 输出管线10月31日
  • 半透明渲染工程 2026:排序、OIT 与深度剥离的取舍10月30日

Conversation

0 条

留下你的想法

加载评论中…

New comment