Skip to content

GPU 风粒子:让矢量场流动起来 ​

风粒子把矢量场(vector field,每个位置一个速度向量)的局部方向和速度变成可追踪的运动。粒子通常只是可视化采样点,不是实际空气分子的追踪记录。固定高度上的 U/V 也只描述水平流动,不能因为画在三维地球上,就称为完整三维大气运动。

不熟悉速度分量时先读向量;Euler 与 RK2 的手算例子见数值积分。本页再把这些步骤放回地球与 GPU。

速度与坐标不能直接相加 ​

若 U/V 单位是 m/s,经纬度 lon/lat 使用弧度(radian),在半径 R(米)的球面近似下,角速度(angular velocity)为:

text
dLon/dt = U / (R × cos(lat))
dLat/dt = V / R

dLon/dt 读作“经度对时间的导数(derivative)”,单位 rad/s,表示每秒改变多少弧度;纬度同理。乘以秒数 dt 后得到角位移,cos(lat) 是纬度的余弦。赤道附近向东 10 m/s,60 秒大约走 600 m,而不是 600°。接近极点时 cos(lat) 很小,经度参数本身退化。简单把分母夹到某个值只是一种数值保护,不是完整的极区积分方案;可使用局部切平面或三维位置与切向矢量推进,再投影回参考表面。

RK2 用中点改善方向估计 ​

欧拉法(Euler method)只使用起点速度。二阶龙格–库塔法(second-order Runge–Kutta,RK2)的中点形式先用起点速度预测半步位置,再在该位置采样速度完成整步:

text
k1 = velocity(position, time)
mid = advance(position, k1, dt/2)
k2 = velocity(mid, time+dt/2)
next = advance(position, k2, dt)

k1、k2 是两次采样得到的速度向量(m/s),mid 是半步预测位置,dt 是模拟秒数;它们不是新的预报帧。这里的 advance 必须与坐标系统匹配,不能把角速度和米每秒混用。时间变化的场还要在中间时刻采样 U/V。步长过大时,再好的积分法也可能跳过狭窄锋区;可限制最大步长并用解析恒定风作对照。

GPU 状态与轨迹 ​

每颗粒子状态存入纹理,通过 ping-pong 从旧状态生成新状态,再绘制点或线段。寿命到期、出区域或进入缺测区时重新播种。种子决定初始分布,固定种子方便比较算法;绘图粒子密度不等于真实空气密度。

轨迹可以保留位置历史,也可以用屏幕累积衰减。前者跟随地球稳定,后者在旋转相机时需要特别处理。若数据时间跳变,旧轨迹继续残留可能暗示不存在的连续历史,应选择清空或明确标识。

本页实际实现区域静态 U/V 场的球面局部 Euler 推进:浮点速度纹理 → 双线性采样 → 状态 ping-pong → 点粒子。可调数量、模拟时间倍率并冻结积分。RK2 与轨迹历史在上文作为后续算法扩展讲解。

风的运动EXPERIMENT 09 · CESIUM 1.145.0

风的运动

观察 GPU 更新粒子状态与在地球上的运动。

在浏览器本地运行 · 无需账号 · 鼠标拖动旋转,滚轮缩放

教学合成数据,不代表真实观测或天气预报。规则场用于验证,拟真形态用于观察复杂结构。 数据说明
查看运行源码

此代码直接读取实际运行的实验模块。按 kind 分支定位当前实验,也可查看数据公式和 GLSL。

读取源码…

观察任务 ​

比较规则风与包含涡旋、多尺度扰动的拟真风。观察涡旋中心与区域边缘,粒子是否异常加速、跳变或堆积?随后思考:把粒子总数翻倍,会让“风速”翻倍吗?

展开答案

粒子数改变采样密度与 GPU 成本,不应改变每颗粒子的积分速度。中心与边缘问题可来自坐标退化、过大步长、采样或播种策略。拟真合成风用于暴露复杂边界,不保证满足真实气象约束;需要另外用零风、恒定东风、反向两帧等小场验证数值。

阅读依据:Cesium 1.145 ComputeCommand 源码(internal)、Cesium 1.145 Ellipsoid 源码。

气象学 · 数学基础 · 地理可视化