WebGPU 选择高亮闪烁:从异步 pick 到资源代际的一条排查路径

📅 2026/7/19 6:56:47
WebGPU 选择高亮闪烁:从异步 pick 到资源代际的一条排查路径
WebGPU 选择高亮闪烁从异步 pick 到资源代际的一条排查路径在工程三维查看器中用户点击构件后出现高亮闪烁、属性面板偶尔跳回上一个构件通常不是 CSS 问题。更常见的根因是GPU pick 的结果异步返回而场景、缓存或资源代际已经变化。先区分三个时间点一次选择至少包含三个时间点指针事件发生记录屏幕坐标GPU 完成 pick返回一个渲染侧引用UI 应用结果更新高亮、结构树和属性面板。如果模型切换、LOD 重建或隐藏状态更新发生在第 1 和第 3 步之间旧结果就可能覆盖新场景。只把最后一次点击坐标保存在全局变量里不能解决这个竞态。给异步操作加 generation打开模型或重建 render cache 时递增 generation。每次发起 pick 都记录当前 generation。结果返回时先检查请求代际是否仍等于场景当前代际如果不一致直接丢弃结果不要回写当前 UI。generation 不是简单的时间戳。它表达的是“这次异步任务是否仍属于当前资源代际”。模型切换、缓存整体重建和 Worker 重新加载都应使它变化普通相机移动是否递增则取决于 pick 缓冲是否仍然有效。不要把 GPU 引用当业务身份pick 结果可能对应批次、实例、间接绘制项或 GPU buffer 中的偏移。这些渲染引用会随着 LOD、资源池和上传批次变化。结构树和属性面板应该接收稳定的业务 nodeId而不是本机 GPU 句柄。一个更稳妥的链路是屏幕坐标 → 当前 render cache 的渲染引用 → 业务 nodeId → 结构树/属性/协同这样资源重建只替换渲染侧映射不会改变业务身份。nodeId 为 0 时也要单独判断不能使用 if (nodeId) 把合法根节点当成未命中。高亮状态要有明确的所有权高亮通常同时影响 GPU 绘制、结构树选中项和属性面板。建议让一个选择状态对象拥有这三个消费者需要的业务身份selectedNodeId业务层稳定身份selectionGeneration选择结果所属的资源代际source来自鼠标、结构树还是协同事件。渲染层依据 selectedNodeId 查当前代际的绘制引用UI 不直接持有旧的 GPU 对象。销毁旧场景时清理旧代际高亮避免旧资源释放后仍然被下一帧读取。一套可以复现的验收清单排查这类问题时我会连续执行以下场景快速点击两个相邻构件确认后返回的结果不会反转点击后立即切换模型旧模型的 pick 不得更新新模型的属性触发 LOD 切换后再次点击业务 nodeId 应保持一致隐藏/显示构件后结构树、属性和高亮状态仍指向同一业务对象断开 Worker 或模拟 device.lost 后过期结果不得重新写入当前场景连续执行选择和取消资源登记数应回到预期基线。日志不要只打印“pick 命中”。至少记录 generation、业务 nodeId、渲染引用是否存在和结果应用时的当前代际。这样才能区分“没有命中”“命中了旧场景”和“业务映射丢失”。ModelView 是一个面向 BIM、机械 CAD、工业装配和其他工程模型的渲染与协同底座结构树、属性、选择、隐藏、测量、剖切和协同审阅都应建立在稳定业务身份之上。开发者披露我是项目开发者。可以下载 Windows 标准版用自己的真实模型测试连续切换和选择流程https://gitee.com/onedraw/modelView