5.8 KiB
STEP-046 Android OpenGL 正式粒子视觉与运行时渲染控制
日期:2026-09-03 状态:CLOSED / PASS
目标
在已关闭的 40-04 Runtime Field 链路上,将正式 RasterParticleLayer 的 full particle draw 从固定蓝色 point 扩展为 GPU 速度驱动的短 streak,并一次性提供运行时视觉属性和 Android 验收入口。
正式链路保持唯一:
RasterArraySource T0/T1
-> GPU time interpolation
-> State A/B
-> Trail A/B
-> GPU full streak draw
-> Composite
实现
- 每个 State texel 仍代表一颗正式粒子。静态 VBO 仅保存该 texel 的两个 line endpoint 编码;不包含 live position、direction 或 color。
- vertex shader 从当前 State write texture 和 T0/T1 Field textures 获取位置与
mix后的速度,按既有边界将V north-positive转换为 Mercatordy=-v,生成 canonical map-space 短 streak。无效/NoData/NaN/近零速度会 fail-closed,不绘制该 streak。 - fragment shader 用最终插值速度 magnitude 走稳定的蓝→绿→橙 ramp;COLOR 控制可关闭 ramp 回退为固定蓝色。相同 magnitude 的 EAST/NORTH 保持同色,vortex 可显示局部速度差异。
- 新增 Core visual paint properties:
raster-particle-line-widthraster-particle-particle-lengthraster-particle-particle-opacityraster-particle-trail-opacityraster-particle-trail-faderaster-particle-speed-color-enabled
- 所有属性是 Render/Visual property,不是 Field 或 simulation state。其运行时更新经既有
MapLibreMap -> NativeMapView -> JNI -> RasterParticleLayerboolean thin bridge,调用强类型 Core setter;不通过 Android Java Layer peer。 - Android Validation 页面加入 VISUAL DEFAULT、SIZE、LENGTH、OPACITY、TRAIL、FADE 与 COLOR 控制,另有直接 VORTEX fixture 与 256K capacity 档;状态栏保留当前可见参数;Activity recreation 保存这些值。
不变量与观测
- visual property 更新只更新 RenderLayer/UBO;不会 reload Style、reload Source、上传 Field、重建 T0/T1、reset State/Trail 或清 Trail。
- 40-04 的 A/B→B/C→C/D、
OLD_T1 -> NEW_T0GPU reuse、Duplicate→NOOP、NO_PRELOADED_FIELDfail-closed 保持不变。 PARTICLE_DRAW_RESOURCES_*记录particleDrawCount=N与streakVertexCount=2N,明确两个顶点仍是一颗粒子的线段,不改变 40-03 已验证容量>= 1,048,576的含义。VISUAL_PROPERTY_APPLIED记录参数、renderLayerInstanceId、resourceGeneration、fieldUploadCount、resetCount;不按 frame 高频输出。没有可靠 GPU timer,因此不虚构 GPU ms。
静态验证
node shaders/generate_shader_code.mjs连续运行两次,生成物稳定。- Linux OpenGL 精确编译:
raster_particle_layer.cpp.o、render_particle_validation_layer.cpp.o、style_layer.test.cpp.o:PASS。 - 新增
RasterParticleVisualPropertiesC++ unit-level coverage,检查默认、运行时 setter 和 visual 参数边界。 clang-format与git diff --check:PASS。- 未运行 Android Gradle、ADB、真机或 Jest。
Android 最终验收
实施提交:e48fa087e01e9710c5d0c18ab062726226bbb6bd(feat: add particle visual runtime controls)。用户已完成 Android OpenGL APK 编译、安装、实体机/虚拟机操作和完整 logcat 收集;本次收尾不重新运行 Android Gradle、ADB 或 Jest。
- T1 正式粒子方向视觉:PASS。UNIFORM EAST、UNIFORM NORTH、VORTEX 的 streak 正常显示,未见明显方向错误、黑屏或渲染异常。
- T2 Runtime Visual Properties:PASS。VIS DEFAULT、SIZE、LENGTH、OPACITY、TRAIL、FADE、COLOR 都经正式 Runtime Property 路径生效;它们不是 Field reload 或 simulation rebuild。
- T3 Speed Color / MIX:PASS。T0 EAST/T1 NORTH 的 MIX 0/50/100 与 speed color 正常;日志确认 MIX property-only,未重载 Field Window 或 reset simulation。
- T4 Runtime Field Window:PASS。连续窗口推进、
OLD_T1 -> NEW_T0reuse、新 T1 上传、Duplicate NOOP、fail-closed 都正常;推进未重载 Style、未无意义 reset simulation 或清 Trail。 - T5 Camera / Projection:PASS。pan、zoom、bearing、DATELINE、WORLD WRAP 后正式粒子与地图组合正常。
- T6 Lifecycle:PASS。DISABLE/ENABLE 与屏幕/生命周期恢复后无需额外按钮即可恢复显示。
- T7 Mask:PASS。GLOBAL、OCEAN A、OCEAN B 均未发现 streak/speed color 绕过既有 mask 语义。
- T8 Capacity Regression:PASS。256、1K、4K、16K、64K、256K、1M 全部实际运行;新的 streak + speed color 路径未发生 crash、黑屏、Renderer 中断、明显资源错误或结构性 full-particle-draw 失败。
256/1K 适合单 streak 的视觉正确性检查。当前 Validation viewport 下 4K 以上的粒子/Trail 已非常密集并接近铺满屏幕;这是 Validation 可读性现象,不是功能失败。64K、256K 和 1M 主要验证容量、稳定性与正式 full draw 路径,不要求肉眼分辨每一颗粒子。1M 继续只代表当前验证设备的已验证容量,不是理论最大值、产品默认值或所有 Android 设备保证。
logcat 的 TimeStats: RenderEngineTimes are already at its maximum size[64] 属于 Android/RenderEngine/虚拟机环境的日志噪声。同期粒子 Renderer 持续 State -> Trail -> Composite 且 hazard=SAFE,未观察到关联 crash 或中断,不能判为 STEP-046 Renderer FAIL。
最终结论
40-05 / STEP-046 已完成 Android 验收并正式 CLOSED / PASS。下一阶段如继续,可单独规划 40-06 时间序列 Playback/preload/cache;高密度 Validation 可读性可作为低优先级测试工具改进,不阻塞本阶段。
本阶段不包含 WeatherColorLayer、网络/GRIB/provider、React Native、Vulkan、iOS/Metal、生产 Land/Ocean mask、粒子箭头贴图或 APK packaging 技术债。