Files
MapLibreParticleLab/docs/40_任务/STEP-068_MapLibreParticleLab_V3-04_DIRECTION粒子推进_Codex任务_v1.md
OpenAI Codex f3c33c6727
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
feat: add direction particle advection
2026-09-11 08:27:28 +08:00

11 KiB
Raw Blame History

STEP-068 MapLibreParticleLab V3-04 DIRECTION 粒子推进 — Codex 任务 v1

执行状态(2026-09-11):IMPLEMENTED / WAITING_VALIDATION。C++/shader scoped 实现与 shader generator 已完成;本沙箱对最终含新增 source test 的精确编译连续在单次 30 秒终端上限前中止,未将其或全量 Ninja 写为 PASS。详见同编号 Step 记录与完成报告。

0. 任务定位

本任务承接已关闭的 STEP-065/066/067,在 MapLibreParticleLab V3 Core/GPU 中实现第二种通用 VectorSemantics:DIRECTION。

目标不是 Wave 业务实现,而是让任意 canonical direction-only vector field 可以驱动 RasterParticleLayer。Core/renderer 仍不得理解 WIND/WAVE/RAIN/TIDE、WeatherV2、NSFT 或 provider。

本任务只做到 C++/shader/Linux OpenGL 可验证闭环;不得进入 Android/JNI/RN v2 ingress,不执行 Android Gradle/AAR/APK/ADB,不加入或执行 Jest。

1. 仓库与基线

仓库:/mnt/sda1/MapLibreParticleLab 分支:particle/main 任务书编写时 HEAD:89c72554c5fb5cd469bdd8ba06ff4b03a1a67ff9 该 HEAD 已等于 origin/particle/main,STEP-067 为 CLOSED / PASS。

开工时必须重新确认 branch / HEAD / origin / git status --short。若远端已合法推进,先阅读新增提交,不得 reset。

当前工作区仍有 STEP-062 两处用户修改和历史 untracked/build/cache/tgz。全部保留;禁止 git add . / git add -A,禁止恢复、删除、覆盖或提交无关内容。

2. 必须阅读

至少阅读:

  • AGENTS.md
  • PARTICLE_BASELINE.md
  • docs/00_项目规范/*.md
  • docs/30_设计/MapLibreParticleLab_V3通用ScalarVectorField运行时架构设计_v1.md
  • docs/50_Step记录/STEP-065_MapLibreParticleLab_V3通用ScalarVectorField架构冻结_v1.md
  • docs/50_Step记录/STEP-066_MapLibreParticleLab_V3-02_CoreContract与ScalarSnapshotAdapter_v1.md
  • docs/50_Step记录/STEP-067_MapLibreParticleLab_V3-03_ScalarGPU与GenericFieldRenderer_v1.md
  • include/mbgl/particle/field/field_data_adapter.hpp
  • src/mbgl/particle/field/field_data_adapter.cpp
  • src/mbgl/renderer/layers/render_particle_validation_layer.cpp
  • include/mbgl/style/layers/raster_particle_layer.hpp
  • src/mbgl/style/layers/raster_particle_layer.cpp
  • src/mbgl/style/layers/raster_particle_layer_impl.hpp
  • src/mbgl/style/layers/particle_render_layer_properties.hpp
  • shaders/particle_gpu_validation.vertex.glsl
  • shaders/particle_gpu_validation.fragment.glsl
  • include/mbgl/shaders/particle_gpu_validation_ubo.hpp
  • 对应 generated OpenGL shader header 与现有 layer/source tests。

实现必须以实际源码为准,不得按任务书示例猜接口。

3. 冻结语义

V3 vector semantics 只有:

  • VELOCITY:canonical U east / V north,物理速度,保持现有 m/s Web Mercator 推进路径。
  • DIRECTION:canonical U east / V north,只表达方向;输入通常为单位向量,但 GPU 不可假设时间插值后仍为单位长度。

DIRECTION 的 GPU 规则必须是:

  1. 分别解码 T0/T1 vector;
  2. 按当前 timeMix 对 U/V component-wise 插值;
  3. 检查 finite;
  4. 对插值结果求长度;
  5. 长度 <= epsilon 时 fail-closed;
  6. 否则 normalize;
  7. 乘独立的 renderer advectionScale;
  8. 再进入现有 Web Mercator displacement 计算。

严禁:

  • 先分别 normalize T0/T1 再做最终不归一化 mix;
  • 使用 scalar height、period 或 vector 原 magnitude 决定推进速度;
  • 将 DIRECTION 当 m/s;
  • 在 Core 中出现 Wave 分支。

反向方向示例:T0=(1,0)、T1=(-1,0)、MIX=0.5,插值向量长度近零,必须 invalid/fail-closed,不得任意选择东或西。

4. VELOCITY 回归保护

VELOCITY 是已通过 Android 的旧正式路径。本任务必须保持默认行为:

  • 不 normalize VELOCITY;
  • T0/T1 仍 component-wise mix;
  • 默认参数下 displacement 公式不变;
  • U east / V north 与 world-y southward 的符号不变;
  • latitude/cos(latitude)/Earth circumference 计算不变;
  • lifecycle、respawn、Trail、T0/T1/MIX、pause、cadence、window rollover 不重写。

允许为共享 helper 重构 shader,但必须证明 VELOCITY 结果等价。

5. advectionScale

为 DIRECTION 增加 business-neutral renderer 控制 advectionScale。

优先以 RasterParticleLayer 的 C++ Core style/control property 实现,建议属性名:raster-particle-advection-scale,C++ API 为 getAdvectionScale()/setAdvectionScale();最终命名需与现有 property 体系一致。

冻结要求:

  • 默认值 1.0,确保不隐式引入产品级速度偏好;
  • 必须 finite 且 > 0;需要上限时根据现有数值安全给出保守、文档化的界限,不得随意设为天气业务值;
  • V3-04 中 advectionScale 只改变 DIRECTION 的推进 magnitude;VELOCITY 默认/现有运动数学不因该属性变化而改变;
  • 不从 scalar、fieldId、fieldType、displayDomain 推导该值;
  • RN 公共 API 暂不增加,留给 V3-05 一并接线。

如果当前 CoreOnly layer property 机制不适合新增 serialize property,Codex 可采用最小等价 C++ renderer config,但必须在报告解释原因;不得因此提前改 Android/JNI/RN。

6. Shader/UBO 一致性

当前 State fragment shader 和正式 particle line vertex shader都会独立读取 u_field_texture/u_next_field_texture。

两者必须使用相同 semantics:

decode T0/T1 -> mix -> resolve VELOCITY or DIRECTION -> validity

不得出现 State 按 Direction 推进、但 line vertex 仍把 raw mixed direction 当 velocity 的不一致。

建议增加明确的 UBO advection/semantics 参数,例如独立 vec4,避免挤占已有字段导致语义混乱。若修改 UBO:

  • 同步 vertex GLSL;
  • 同步 fragment GLSL;
  • 同步 C++ UBO struct/static_assert;
  • 运行官方 shader generator 更新 generated OpenGL header;
  • 不手工只改 generated header。

helper 命名应从 fieldVelocityAt 收敛为 generic advection/vector 语义;不得继续用 velocity 名称表达 DIRECTION 分支。

7. Renderer acceptance

STEP-067 当前主动拒绝 VectorSemantics::Direction。本任务需改为:

  • scalar-only:Particle unavailable/fail-closed;
  • vector VELOCITY:允许;
  • vector DIRECTION:允许;
  • T0/T1 semantics 不一致:继续 fail-closed(正常应已被 Timeline compatibility 拦截,但 renderer 仍防御);
  • invalid/NaN/near-zero mixed direction:该 sample invalid,按既有 lifecycle/respawn 安全处理;不得产生 NaN position。

切换 semantics/window 时不得错误复用与新 semantics 不兼容的 GPU resource。既有 sameFieldGpuContent/Timeline compatibility 的 semantics 保护必须保留。

8. Trail 与粒子线段

正式 particle line 必须与 State 实际位移一致:

  • line segment 继续连接 previousState -> currentState;
  • vertex shader 用于 v_particle_velocity/颜色判断的向量必须使用与 State 相同的 resolved advection vector;
  • DIRECTION 下可把 length(resolvedAdvection) 作为纯视觉强度输入,但不得声称它是原始物理 speed;
  • 不允许用 scalar 驱动 particle color;
  • 本任务不重新设计 speedColorEnabled 公共能力,若命名仍带历史 speed,可记录技术债,避免扩大范围。

9. Timeline / GPU reuse 硬保护

不得破坏:

  • Source-owned Timeline;
  • T0/T1/MIX;
  • PAUSE;
  • 连续 MIX 时零 field upload;
  • OLD_T1 -> NEW_T0 reuse;
  • 正常 rollover 只上传 NEW_T1;
  • window overlap 时 simulationRebuild=false、trailCleared=false;
  • style/context loss 的既有重建规则;
  • invalid/gap fail-closed。

改变 advectionScale 不应重新上传 field texture。是否清 trail/simulation 必须依据当前生命周期设计最小化,默认不允许为了纯 renderer 参数变化重新提交 field。

10. 必须补的验证

本任务需新增/调整最小测试,至少覆盖:

  1. RasterParticleLayer advectionScale 默认值与 set/get/非法值策略;
  2. VELOCITY 与 DIRECTION renderer eligibility;
  3. scalar-only 仍 fail-closed;
  4. T0/T1 semantics mismatch fail-closed/不绘制;
  5. shader/UBO semantics 参数正确传递;
  6. DIRECTION 数学:east、north、斜向;
  7. T0 east + T1 north + MIX=0.5 -> normalize 后 northeast;
  8. T0 east + T1 west + MIX=0.5 -> near-zero invalid;
  9. advectionScale 改变 magnitude、不改变 direction;
  10. VELOCITY 路径不 normalize,默认结果保持现状。

优先使用当前已有 C++ test/fixture 体系;不要为了测试引入新的大型 framework。

11. Linux 验证

必须执行:

  • node shaders/generate_shader_code.mjs;
  • 受影响 C++ 精确对象编译;
  • 相关现有/新增过滤测试;
  • 在可行时 ninja -C build-linux-opengl -j3 mbgl-test mbgl-test-runner;
  • git diff --check。

构建日志遵循项目全局 build-output-throttle。

如果全量 Ninja 再受单次终端时间限制,不得伪造 PASS;但应先确保受影响精确对象与过滤测试通过,并在报告明确缺口。不得要求用户现在编 Android。

12. 明确禁止

本任务不得:

  • 修改 Android Java/Kotlin/JNI bridge;
  • 修改 RN package API/version;
  • 实现 v2 multi-plane file ingress;
  • 修改 WeatherV2/NavSea;
  • 解析 NSFT/PMTiles;
  • 添加 Wind/Wave/Rain/Tide enum 或业务分支;
  • 使用 scalar height/period 控制 DIRECTION 速度;
  • 增加第二 scalar/N-channel;
  • 重写 Timeline/Playback/Runtime Window;
  • JSI/zero-copy 重构;
  • 执行 Android Gradle/AAR/APK/ADB;
  • 加入或执行 Jest。

13. 文档与状态

新增/更新:

  • 本任务书 docs/40_任务/STEP-068_MapLibreParticleLab_V3-04_DIRECTION粒子推进_Codex任务_v1.md
  • docs/50_Step记录/STEP-068_MapLibreParticleLab_V3-04_DIRECTION粒子推进_v1.md
  • docs/报告/STEP-068_MapLibreParticleLab_V3-04_DIRECTION粒子推进_Codex完成报告_v1.md
  • 追加 粒子开发记录.md

全部文档中文。完成报告逐项写“已完成 / 未完成 / 无法验证”,明确生产代码范围、验证结果、Android/Jest 未执行、风险和下一步。

若代码与 Linux 验证满足本任务门槛,可标记 CLOSED / PASS;若只有实现而关键精确编译/过滤测试未通过,则只能 IMPLEMENTED / WAITING_VALIDATION。

14. Git 收尾

本任务有生产代码修改,完成后必须 scoped commit + push 到 origin/particle/main。

提交前再次 git status --short。只暂存本任务实际修改文件与上述 STEP-068 文档;禁止纳入 STEP-062 两处用户修改和所有历史 untracked/build/cache/tgz。

允许按“实现代码”与“文档收尾”做 1-2 个 scoped commit。禁止 git add .、git add -A。

push 后必须确认:

  • commit hash/message;
  • push 成功;
  • HEAD == origin/particle/main;
  • 最终工作区剩余 dirty 仍只属于原有用户/历史内容。

push 失败则任务不得声称完全完成。

15. 下一阶段边界

本任务完成后下一阶段应为 V3-05:Android/JNI/RN generic v2 multi-plane ingress。

V3-05 之前不要求 Android build。最终仍按 V3 总规划,将 Android 编译/安装/设备综合验收集中到后续大阶段,避免每个小 Step 重复一次 Android 周期。