2.8 KiB
STEP-055 Android 真实 WeatherV2 风场综合可视化 v2
状态:IMPLEMENTED / WAITING_ANDROID_VALIDATION
Starting HEAD:37c9aa31da1d2b3495c8802e6fd2f6b999562b06
本轮问题与根因
Android 已确认真实 WeatherV2 Field、Host submission、WeatherColorLayer、Timeline State A/B 调度、非零 U/V 与非零 m/s→Web Mercator 位移均存在,但 Timeline Pause 下粒子仍肉眼静止。
根因是 Particle State A/B 与 Trail A/B 共用 createValidationTarget() 的 UnsignedByte target。State RG 保存的是 Web Mercator world position;RGBA8 的一个量化步长约为 1/255=0.00392 world,远大于日志中每个真实 Weather simulation step 的 0.000003–0.000008 world,写回后不能累积有效位移。
修复
- State A/B target 改为
TextureChannelDataType::Float,包括初次创建、context/resource recreation 和 particleCount 变更的 replacement targets。 - Trail A/B 保持
TextureChannelDataType::UnsignedByte,继续是 viewport-sized 颜色/透明度 target;没有升级 WeatherColorLayer 或任意无关 full-screen target。 RenderTarget新增isRenderable(),在 Particle target 创建时立即驱动现有OffscreenTexture → GL texture → framebuffer创建/检查。Android OpenGL 已有映射链为Float → RGBA32F + GL_FLOAT → glFramebufferTexture2D → checkFramebuffer();无需新增 backend 抽象。- Float State FBO 不能创建时不回退到 UByte:
ParticleStateTarget: event=CREATE_FAILED ... dataType=Float后停止该 State resource 创建;count change 同样明确返回STATE_RESOURCE_CREATE_FAILED dataType=Float。 - 每个成功 target 输出
CREATE_SUCCESS,Trail pair 就绪时另输出一次ParticleStateTarget: stateAType=Float stateBType=Float trailAType=UnsignedByte trailBType=UnsignedByte。 - Shader 注释校正为 State RG 保存
Web Mercator world position,不是 field-normalized position。
冻结边界
未修改 canonical Field、STEP-054 assets、Host Submission Contract、Timeline、Playback、Runtime Field Window、WeatherColorLayer、U/V=m/s 或 visualSpeedScale=6000。继续保持 Timeline Pause 只冻结 forecast 时间、Particle simulation 在当前 Field 中运行;Window reuse、NEW_T1-only、MIX property-only、normal boundary simulationRebuild=false / trailCleared=false 不变。
验证与待验收
已执行 shader 生成、Linux OpenGL 受影响 Core 精确编译、相关测试源精确编译和 git diff --check;未执行 Android Gradle/APK/ADB/App/设备或 Jest。
下一轮人工验收的第一优先项是:进入 REAL WEATHER、保持 Timeline Pause,确认 Float State 类型日志后粒子中心位置连续运动。若仍完全不动,停止调节 6000,改以单独任务调查 GPU State readback / State Update→Draw 链。