mcpField
T
threejs-rain-snow-and-wet-surfaces

threejs-rain-snow-and-wet-surfaces

github.com/linegel创意与媒体11129 次安装5 周前更新
代码仓库

关于 threejs-rain-snow-and-wet-surfaces

面向 Three.js 天气效果开发的技能,覆盖雨雪运动、沉积以及湿润表面的呈现。它将视觉粒子与接收表面的持久液体或积雪状态分开,并以明确的物理量和状态所有权连接各阶段。

主要功能

  1. 01规划天气状态所有权与单位
  2. 02选择解析式或递归粒子运动
  3. 03按接收面积积分雨雪沉积
  4. 04按顺序执行天气与接收面更新
  5. 05从已提交状态呈现积雪和湿润效果
  6. 06提供诊断并验证资源清理

适用场景

  1. 01实现相机移动时保持稳定的降雨
  2. 02计算与视觉粒子数量无关的积雪
  3. 03为湿润表面添加水膜、涟漪和飞溅

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/linegel/threejs-complete-set-of-skill --skill threejs-rain-snow-and-wet-surfaces

安装后在 Claude Code 中输入/threejs-rain-snow-and-wet-surfaces确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE
agents/
openai.yaml
examples/
physical-area-deposition.mjs
references/
precipitation-motion.md
receiver-weathering.md

详细介绍

雨、雪与湿润表面

让外观与成因相对应:一个时间源和风场驱动空中降水,而每个接收器由一个所有者负责积分沉积的雨或雪。融化/再冻结只在液体和雪之间转移等量质量;两者都不会产生库存。可视粒子数量用于采样天气,绝不决定沉积质量。

使用 Three.js r185 WebGPURenderer、TSL、存储节点、节点材质和节点后处理栈。分配计算或存储资源前,先初始化渲染器:

await renderer.init();

if (renderer.backend.isWebGPUBackend !== true) {
  throw new Error('This weather path requires the WebGPU backend.');
}

对于跨系统的降水或接收器状态,需声明其单位、坐标系、时间间隔、权威来源/版本、作用范围、有效性和重置语义;当所有权跨越多个技能时,调用 $threejs-choose-skills。

构建顺序

1. 明确所有者和单位

声明:

  • 一个按秒计、单调采样的时间源和更新间隔;
  • 一个以世界米/秒为单位的空气速度场,并注明其坐标系、作用范围、更新频率和有效性;
  • 当相态、融化或蒸发依赖温度或湿度时,使用开尔文温度和明确指定的湿度惯例;
  • 以 kg m^-2 s^-1 表示的降水驱动通量,即在物理接收器作用范围内的液体/冰质量面通量;
  • 每种液体或雪库存各自唯一的接收器状态所有者;
  • 唯一的 HDR 呈现、色调映射和输出转换所有者。

将云层外观和因果降水视为不同分支。仅用于外观的云层可以协调美术方向。因果云层源发布质量通量或带有下落延迟/传输模型的空中库存;雨水则在后续有序阶段将其输送到接收器。

当每个成因和持久状态都有且仅有一个所有者、每个交换量都明确标注单位和坐标系,并且每个生产者都在其声明的有效期内被采样时,此步骤即告完成。

2. 分配状态前先选择运动方式

当位置可精确表示为种子、时间和累积风场的函数时,使用不可变种子和解析顶点运动。当湍流、碰撞、反馈或路径历史会影响下一状态时,使用 GPU 常驻的循环状态。只有在可以获得位移积分时,随时间变化的手动风场才能保持解析形式;将当前风速乘以总经过时间,会导致风场变化时所有粒子突然跳变。

对于无界视觉天气,使用以摄像机为中心的单元流式处理,并在稳定的世界空间中对单元标识、生成相位和轨迹进行哈希。对于局部天气,使用锚定于世界空间、边界明确且经过刻意设计的有界体积。撞击和积累始终使用独立于视觉粒子池、稳定于世界空间的接收器单元。

选择解析运动还是循环运动、实现计算更新、生成物理撞击或估算降水工作量时,请阅读降水运动。

当每个所需力或碰撞都对应一个精确的解析项或循环状态字段,并且摄像机平移测试只改变可见单元集合,不改变粒子相位、撞击位置或接收器累积状态时,此步骤即告完成。

3. 将沉积与视觉采样分离

使用物理面积求积对通量进行积分:

sum_i A_i = represented receiver area
deltaMass = deltaTime * sum_i(massFlux_i * A_i)

每个 A_i 都包含以平方米为单位的物理接收面雅可比。将水平面/源面积通量转换为相对于接收面的表面到达通量时,只转换一次;参考资料区分了这种投影与已沿法线方向的到达通量。当稀疏撞击代表已积分的传递量时,将该广延质量和动量分配到各次撞击中,使其总和恰好等于父级传递量。将渲染条纹/雪花密度、精灵尺寸和视觉 LOD 排除在此计算之外。

实现或独立审查此物理沉积分支时,请阅读或复制 物理面积沉积预言机。它接受变化的求积面积,不会对撞击分配进行归一化,并会检查接收方所有者的广延质量账本。它是 CPU 预言机,不是运行时状态所有者。

满足以下条件时,此步骤即告完成:在相同强迫轨迹下改变视觉粒子数量和视觉 LOD,不会改变沉积的质量和动量;改变接收器更新频率时,时间积分在指定数值容差内保持不变。

4. 按顺序更新整个网格

采用以下因果顺序:

latch time, wind, and precipitation forcing
  -> advance analytic or recurrent airborne precipitation
  -> resolve and bin impacts
  -> publish deposition/impact transfer
  -> integrate receiver liquid and snow state
  -> commit receiver state
  -> build render projection

如果后续阶段会使用先前阶段生成的整个网格结果,请将求解器、碰撞/分箱、扫描/压缩、间接参数和接收器通道拆分为按顺序执行的调度。工作组屏障只对一个工作组进行排序;要对整个网格进行排序,必须使用显式通道或队列依赖。将 r185 computeAsync() 视为初始化/入队便利方法,而不是 GPU 完成栅栏。将稳定帧状态保留在 GPU 上;仅在帧关键执行之外从主机读取数据。

满足以下条件时,此步骤即告完成:每次读取都注明生成它的调度或已提交快照;接收器在沉积结果确定后进行积分;固定强迫重放在所有受支持的更新频率下都会产生相同的已提交存量。

5. 投影单一的已提交接收器状态

实现积雪、湿润度、积水、波纹法线、飞溅或其材质响应时,请阅读接收器风化。

从已提交的接收器快照构建所有表面效果:

  • 从同一高度场推导积雪位移和积雪法线;
  • 在稳定的模型空间中采样物体积雪,并使用变换后的世界空间支撑法线对其进行门控;
  • 在启用强降雨波纹法线之前,先应用早期湿润度响应;
  • 使用同一个湿润度/积水遮罩来控制粗糙度、吸收、波纹适用性、飞溅强度和遮罩诊断;
  • 根据世界空间接收器法线确定飞溅方向,并剔除朝下、缺少支撑或按照所选可见性策略被遮挡的候选点。

满足以下条件时,此步骤即告完成:积雪位置与积雪法线诊断结果一致;禁用波纹时仍能看到湿润效果;经过变换或被遮挡的接收器测试只会接受具有世界空间支撑的飞溅候选点。

6. 呈现并验证

使用 MeshStandardNodeMaterial 或 MeshPhysicalNodeMaterial 的插槽来设置颜色、 粗糙度、法线、不透明度和位移。通过一个 RenderPipeline 进行呈现。将编码后的基色纹理标记为 SRGBColorSpace;将法线、粗糙度、遮罩、噪声、LUT、涟漪和天气场视为数据。保持 HDR 缓冲区为线性,直到唯一的色调映射/输出转换负责人执行转换。

提供诊断功能,用于强制指定版本和时效、运动/单元、冲击、沉积质量、接收面项、雪的高度/法线、湿润度/涟漪、飞溅朝向/可见性、数据纹理解释方式和最终输出。针对指定目标测量全帧以及天气开启/关闭对比时的 CPU/GPU p50/p95、透明过度绘制、每帧热数据字节数、活动冲击瓦片数和峰值实时存储量。

当最终视图和诊断视图通过以下可观察检查时,此步骤即告完成:旁路诊断渲染后能够恢复基线而不清除已沉积的库存,停止降水只会停止新的输入,调整大小/重建会保留所有者并仅重置受影响的瞬态历史记录,且释放时会清理天气拥有的每个缓冲区、纹理、材质和渲染通道。

可观察检查

可观察项失败特征及可能原因
相机平移后,降水相位和冲击保持不变单元标识或冲击支撑范围相对于相机。
风力变化会改变后续运动的方向,而不会平移整个场当前风力乘以了经过时间,而不是进行积分。
条状效果的长度随下落速度/曝光时间变化,漂移随共享风力变化精灵几何或某个表面分支使用了不同的时钟或风力。
无界天气没有发射器接缝;局部天气有明确的边界所选视觉域约定不完整。
雪的轮廓和光照同步变化位移和法线来自不同的场。
动态物体上的积雪始终贴合其表面覆盖率是在世界空间而非稳定的模型空间中采样。
湿润表面在强降雨涟漪出现前就发生变化粗糙度受涟漪遮罩控制,而不是受接收面湿润度控制。
变换后,飞溅仍位于受支撑且可见的表面上候选法线或可见性是在局部空间/不稳定空间中计算的。
密集的循环天气没有逐滴对象循环,也没有全量热缓冲区上传状态或呈现已离开 GPU 驻留分支。
数据场保留原始值,最终颜色只进行一次显示变换数据纹理被解码为颜色,或输出转换执行了两次。

路由边界

对于有界水体、折射、焦散和 Beer-Lambert 厚度,使用 $threejs-water-optics。对于 非天气粒子系统,使用 $threejs-particles-trails-and-effects。对于 屏幕空间触摸或清除历史记录,使用 $threejs-dynamic-surface-effects。对于 全场景 HDR/后期处理所有权,使用 $threejs-image-pipeline;对于 大型场景的阴影分配,使用 $threejs-scalable-real-time-shadows。此技能负责降水输运和天气专用的接收面投影;由路由选定的接收面所有者负责持久的液体或积雪库存。

评论

支持 Markdown