Tidewater海洋渲染原理:四重级联FFT(Tessendorf)在WebGPU Compute上的快速实现
【免费下载链接】tidewaterCoastal town built with Opus 5.5项目地址https://gitcode.com/gh_mirrors/ti/tidewater点击查看免费下载Tidewater 是一个直接在浏览器运行的海岛钓鱼游戏它用 WebGPU WGSL 手写了一套渲染引擎海洋渲染部分实现了经典的 Tessendorf 随机波谱方法四重级联cascade256×256 FFT 海面每帧仅用极少的 compute dispatch 就能同时驱动 700 米尺度的涌浪和厘米级的碎浪细节。 这篇文章拆解它的原理、工程实现与性能技巧。一、FFT海洋为什么是标准答案Tessendorf波谱原理传统逐波求和或Gerstner波很难同时表现远处涌浪和近处碎浪。Tessendorf 在 1997 年提出的方法是把海面看作大量随机相位的正弦波叠加每道波的振幅由物理波谱如 JONSWAP 谱决定随机化波场对每个波数 k从波谱 S(k) 中计算振幅再用 Box-Muller 生成随机相位得到初始谱系数 h0(k)——这一步只在海况变化时执行一次initSpectrumKernel用 PCG hash 作随机源解析时间演化每个波包按频散关系ω sqrt(k·g·tanh(k·h))有限水深色散dispersion随时间旋转相位h(k,t) h0·e^{iωt} conj(h0(−k))·e^{−iωt}。每一帧对每个谱系数只需要两次三角函数加几次乘加无需重新模拟谱逆FFT回空间域把谱系数 IFFT 回网格得到海面位移场。Tidewater 在此基础上叠加了两个波系统——近海风浪和长周期涌浪均使用带 TMA 修正的 JONSWAP 谱jonswap / directionSpectrum并各自带独立的峰值增强因子 γ 与方向扩散这正是 CREDITS.md 中引用的 J. Tessendorf《Simulating Ocean Water》与 Horvath 的改进谱。问题在于单一平铺贴图要么太大重复周期肉眼可见要么太小无法容纳涌浪。解法就是级联。二、四重级联如何划分700米海面256×256网格的参数设计Tidewater 使用 4 个级联每个都是独立的 256×256 FFT 网格平铺尺寸分别为733 m、157 m、33.3 m、7.1 mDEFAULT_CASCADE_SIZES。注意这些尺寸是刻意取的非整数比——整数倍平铺会让波峰出现周期性网格锁定非整数比可让重复纹理互相错位、几乎不可见。每个级联只负责一段波数区间由cutsuniform 控制updateSpectrumUniforms各频段首尾相接、交接点取在下一级基频的 6 倍处平滑过渡级联平铺尺寸纹素分辨率覆盖波长视觉作用0733 m≈ 2.9 m733 m → 25 m大涌浪、远处起伏1157 m≈ 0.61 m25 m → 5.4 m中浪233.3 m≈ 0.13 m5.4 m → 1.2 m短浪、船体附近细节37.1 m≈ 2.8 cm1.2 m → 约 5 cm毛细碎浪、接触细节输出是两张rgba16float的 2D 数组纹理256×256×4 层纹理分配位移场(Dx, Dy, Dz, foam)导数场(dDy/dx, dDy/dz, dDx/dx, dZ/dz)存解析导数是关键技巧之一法线直接从导数场计算不用textureGrad差分避免法线噪声。mipmap 链9 级也在 GPU 上由 compute kernel 通过 workgroup 归约生成mipKernels替代了几十条 mip 渲染 pass。三、每帧仅2次FFT dispatch行列双通道复数打包技巧这是整个实现最有含金量的部分。OceanFFT 的头部注释 概括了核心每一帧对所有 4 个级联恰好执行 2 个 IFFT dispatch另有 4 个 mip dispatch。第 1 步 · 行通道rowKernel每个 128 线程的 workgroup 负责一个级联的一行 256 个点完成三件事按e^{iωt}把 h0 演化成当前时刻的谱系数同时构建4 个复数场并打包成 2 个 vec4fc0 Dx i·Dz、c1 Dy i·dDx/dz、c2 dDy/dx i·dDy/dz、c3 dDx/dx i·dDz/dz在 workgroup 共享内存里做一次 256 点 radix-2 IFFT8 级蝶形bit-reversal 与蝶形展开。由于 4 个复数场共用同一次 bit-reversal 和同一套蝶形索引一次 IFFT 同时算出 4 个实数场位移的三个分量 部分导数计算量直接摊薄到 1/4。第 2 步 · 列通道columnKernel按列再做一遍 IFFT加上奇偶符号修正后得到最终网格值顺便做两件事Jacobian 白浪检测由导数构造 JacobianJ (1λ·Dxx)(1λ·Dzz) − (λ·Dxz)²当 J 低于阈值foamBias时说明波面正在压缩——正是白浪whitecap生成的位置。泡沫以缓慢衰减的持久量累积所以浪头会拖着一条泡沫尾迹泡沫累积把位移/导数textureStore进两张数组纹理的 0 级 mip。4 个级联通过 dispatch 的z 维同时处理dispatch([256, 4, 1])update因此整片海洋每帧总共只有6 次 dispatch无渲染目标 ping-pong、无 CPU 往返。仓库自带 headless 计时测试test/ocean-fft.mjs可以打印FFT update: x.xx ms/frame验证这条 compute 链路的开销。四、CDLOD网格按级联选mipmap采样端的LOD策略有了高频网格还得解决远处的海面不该用 2.8 cm 纹素的问题。Tidewater 的水面网格用的是CDLODStrugar 2010 连续距离相关 LODCDLOD.js12 级四叉树网格相邻 LOD 边界做形变morph过渡永远不会出现裂缝或跳变。采样分两级顶点阶段WaterSurface 顶点采样对每个级联按网格间距做带限采样——mip log2( spacing / texel ) 0.7保证不采到网格无法承载的高频避免锯齿和游泳效应同时按水深衰减各级联振幅长波在浅水先消失长周期波最先摸底片元阶段用 4× 各向异性过滤采样导数场求法线对于相机脚边几米内的近景还会把最细级联旋转后按约 1 m 和 2.3 m 的平铺重采样补偿近处像素覆盖小于 2.8 cm 纹素造成的玻璃水面近景毛细波。五、海况预设与白色浪花在游戏里亲手调一片海以上所有参数都暴露在设置面板游戏中按H打开里。AppUI.js 内置了 4 个海况预设以及风速、风向、有效波面fetch、浪陡度choppiness、涌浪、白浪密度等滑块预设风速fetch浪陡度涌浪白浪Calm3.5 m/s40 km0.750.2820%Breezy7 m/s120 km0.900.4850%Choppy12 m/s300 km1.050.6875%Storm20 m/s900 km1.201.00100%修改风速/fetch/涌浪会重新触发一次谱初始化CPU 端只是重传 uniformGPU 端重跑三个初始化 kernel而 choppiness水平位移强度制造尖峰宽谷的陡浪外形是逐帧参数实时生效。配合世界空间的不重复细节阵风、油膜、风排线SeaDetail和浅水推进模拟整片海的状态可以随手拨动、即时生效。六、本地运行与动手验证git clone https://gitcode.com/gh_mirrors/ti/tidewater cd tidewater npm install npm run dev # http://127.0.0.1:5189打开后按H切到 Storm 预设感受白浪按F进入自由相机俯视级联边界非整数平铺比的效果肉眼可见。也可以只跑无头测试node test/ocean-fft.mjs会输出各帧 FFT 耗时和位移/导数纹理的 PNG 可视化。核心文件索引FFT 海洋核心src/ocean/OceanFFT.js水面组合与采样src/ocean/WaterSurface.js连续 LOD 网格src/core/CDLOD.js场景组装入口src/App.js海况预设 UIsrc/ui/AppUI.js特性总览README.md一句话总结Tessendorf 波谱负责物理正确非整数比的四重级联负责看起来不重复行/列双 dispatch 四路复数打包负责60 fps 跑得动——三者叠加才让一个纯浏览器 WebGPU 应用拥有了电影级的海面。赞分享【免费下载链接】tidewaterCoastal town built with Opus 5.5项目地址https://gitcode.com/gh_mirrors/ti/tidewater点击查看免费下载相关推荐three.js TSL AtomicFunctionNode在 WebGPU Compute Shader 中实现 GPU 原子操作three.js TSL AtomicFunctionNode在 WebGPU Compute Shader 中实现 GPU 原子操作 AtomicFunct前端3D渲染图形学Fantasy Map Generator v1.96.0 海洋高度图渲染与比例尺样式重构从操作到源码级原理Fantasy Map Generator v1.96.0 海洋高度图渲染与比例尺样式重构从操作到源码级原理 本篇文章基于 Fantasy Map Gener前端图形学3D渲染探索Crest Ocean SystemUnity高级海洋渲染的技术革命探索Crest Ocean SystemUnity高级海洋渲染的技术革命 还在为Unity中实现逼真海洋效果而头疼Crest Ocean System用技术图形学3D渲染游戏开发创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

软件测试全栈知识库:9大领域与成长路线指南

软件测试全栈知识库:9大领域与成长路线指南

最近翻团队内部的简历池,发现一个普遍现象:很多同学写“熟悉软件测试”,但若细问AI测试怎么做、性能分析从哪个指标开始看,往往就只剩下一句“了解一点”。测试岗位发展到今天,“软件测试全栈知识库”已经不是培训机构…

2026/10/14 23:45:59 阅读更多 →
单目3D目标检测实战:ROI-10D的6D位姿与度量形状回归

单目3D目标检测实战:ROI-10D的6D位姿与度量形状回归

1. 项目背景与核心问题拆解1.1 单目3D目标检测到底难在哪做自动驾驶感知或者机器人抓取方向的朋友,大概率都碰过这样一个问题:手头只有单目RGB相机,却想拿到目标物体的完整6D位姿和真实尺寸。这件事的难度,不在于“检测”本身&…

2026/10/14 23:45:59 阅读更多 →
Claude Code Skill 生态实战:从开源项目到自动化视频生产

Claude Code Skill 生态实战:从开源项目到自动化视频生产

最近这个圈子有个很有意思的现象:很多人对 Claude Code 的印象还停留在“用它写代码、改 bug、跑测试”,但真正把它用到极致的人,早就不满足于这一亩三分地了。我这次专门花了两天时间,把 GitHub 上开源的 Claude Code Skill 生态…

2026/10/14 23:45:59 阅读更多 →

最新新闻

ECharts柱状图配置全解析:从基础到动态排序与性能优化

ECharts柱状图配置全解析:从基础到动态排序与性能优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 1:57:11 阅读更多 →
LVGL 图像按钮(lv_imgbtn)实战指南:Simple Image button 示例全解与源码原理

LVGL 图像按钮(lv_imgbtn)实战指南:Simple Image button 示例全解与源码原理

嵌入式物联网智能硬件嵌入式GUI硬件开发 【免费下载链接】HoloCubic 带网络功能的伪全息透明显示桌面站 项目地址: https://gitcode.com/gh_mirrors/ho/HoloCubic 点击查看 免费下载 本篇文章围绕 HoloCubic 固件所采用的 LVGL 图形库中的 lv_imgbtn(图…

2026/10/15 1:57:11 阅读更多 →
深入解析 LAMMPS `compute msd/chunk`:逐块均方位移的计算原理与实战配置

深入解析 LAMMPS `compute msd/chunk`:逐块均方位移的计算原理与实战配置

科研科学计算高性能计算 【免费下载链接】lammps Public development project of the LAMMPS MD software package 项目地址: https://gitcode.com/gh_mirrors/la/lammps 点击查看 免费下载 导读 compute msd/chunk 是 LAMMPS 中用于按 chunk(原子分组…

2026/10/15 1:57:11 阅读更多 →
车机双系统下用ASAN抓内存踩踏:8155p上Android.mk与Android.bp配置实战

车机双系统下用ASAN抓内存踩踏:8155p上Android.mk与Android.bp配置实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 1:57:11 阅读更多 →
Go 1.27.1 内存局部性调优实录:压榨 CPU 缓存行命中率的工程实践

Go 1.27.1 内存局部性调优实录:压榨 CPU 缓存行命中率的工程实践

在微服务吞吐量达到数万 QPS 的高性能网关或高频事件调度引擎中,单纯依赖算法时间复杂度(如将 $O(N)$ 降为 $O(1)$)已经无法进一步带来数量级的性能突破。很多底层服务开发者发现,即便 CPU 利用率跑满了 100%,服务处理…

2026/10/15 1:57:11 阅读更多 →
Start Bootstrap 主题 One Page Wonder 详解:基于 Bootstrap 4 快速构建单页网站

Start Bootstrap 主题 One Page Wonder 详解:基于 Bootstrap 4 快速构建单页网站

前端文档 【免费下载链接】startbootstrap A library of free and open source Bootstrap themes and templates 项目地址: https://gitcode.com/gh_mirrors/st/startbootstrap 点击查看 免费下载 One Page Wonder 是 Start Bootstrap 开源仓库中的一款经典单页主题…

2026/10/15 1:56:09 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →