# 前端执行票 —— 调色后处理着色器编译失败使地图停止渲染 ## 问题与实测证据 [前端真实接口联调与阶段收口](18-frontend-real-integration-gate.md)本轮已授权浏览器预检,2026-10-13约16:38–16:44,现有 dev 页面 `http://127.0.0.1:8000/#/cockpit`,按真实界面进入系统后,配置显示real且面板能读真实计数,但地图黑屏,Cesium提示: ``` An error occurred while rendering. Rendering has stopped. RuntimeError: Fragment shader failed to compile. ERROR: 0:7: 'varying' : Illegal use of reserved word ``` 控制台生成后的shader为 `#version 300 es`,同时仍含 `varying vec2 v_textureCoordinates;`;uniform前缀为 `gradeSaturation/gradeBrightness/gradeContrast/gradeTint`,调用栈经过 `PostProcessStage.execute`。本工作树 `src/modules/cockpit/services/cesiumEngine.js` 约751–756行与报错源码对应;该源码含并行未提交改动,不能把故障归于某个已提交版本或推断所有部署都复现。 证据:[真实页面截图](../verify/artifacts/t18/takeover-browser-20261013/rendering-stopped.jpg)。页面CSS视口1600×1000,浏览器会话曾设置ipad-mini仿真,需在桌面浏览器/实际GPU环境再核对;此处记录观察到的编译错误,不把它归因为GPU性能问题。 ## 任务 由前端执行会话核对调色后处理与Cesium1.145/WebGL2的shader兼容,协调并行素材/调色改动后做最小修复。本票不裁定新视觉效果,不通过关闭地图、改mock、隐藏错误弹窗来宣称修复。不在上位真人验收票中混入功能代码修改。 ## 验收 1. 同一真实页面从进入系统开始,地图持续正常渲染;控制台无片元shader编译错误和Rendering has stopped。 2. 调色效果按现有配置工作,启用与关闭路径都可核对,不破坏影像/模型/管线渲染。 3. 桌面GPU环境覆盖freshness刷新、模式/筛选切换与真实对象定位;没有周期抽搐或选择态回归。 4. 最小限定diff、必要回归证据、提交推送与运行版本绑定齐备。 ## 下一步 等待执行会话诊断认领;当前只建票,未修改功能代码、未宣称根因修复。上位阶段门须等待地图恢复后继续真人完整验收。 ## 进度 - 2026-10-14 诊断(只读,未改业务代码):**未动工**阶段;票面 `Status: ready-for-agent` 与 `needs-triage` 双状态冲突已消除。 - **本票与 [票 49「恢复驾驶舱3D渲染:调色与雾着色器的GLSL兼容性」](../../cockpit-shell-panel-layout/issues/49-3d-glsl.md) 是同一缺陷的重复建票**:票 49 已按同一根因修复并浏览器复验、状态 `resolved`。 - 根因确证(高置信):Cesium 1.145 在 WebGL2 下给所有 shader 前置 `#version 300 es`,而 GLSL ES 3.00 删除了 `varying` 关键字 → 自有调色 shader `GRADE_FRAGMENT_SHADER` 的 `varying vec2 v_textureCoordinates;` 直接编译失败,`PostProcessStage` 失败即整帧失败 → 黑屏 +「Rendering has stopped」。 - 引入提交 `e2529b5`(调色滤镜)——同文件雾 shader 早在 `8db64fc` 已迁到 `in vec2`,调色 shader 漏迁。 - 触发条件确证:`GRADE_DEFAULTS.enabled = true` 且部署 `public/cockpit/config.json` 显式 `"grade":{"enabled":true}` → 该处理级必然构建、必然编译失败。 - **修复已存在,但只在工作树、未提交**:committed HEAD(`09905be`)仍含 `varying`;`origin/master` 根本不含调色提醒级 → 缺陷不在任何已提交/已推送版本上。 - disease-side 测试反向锁定:HEAD 的 t49 闸门**断言 `varying` 是正确写法**(把 bug 当规格);工作树已改为断言 GLSL3 并拒绝 `varying/texture2D/gl_FragColor`。 - 真实浏览器复验(工作树,2026-10-14 11:52,只读使用既有 8000 实例):进入系统后整幅地图正常渲染(地形/影像/管线/标记齐备),控制台**无** `varying` 编译错误、**无** `Rendering has stopped`;因调色级按配置启用,无错误即证明该 shader 编译通过。 - 分流:分入「不做」→ `wontfix`(已实现/重复),已摘 `needs-triage`;**未关闭**(诊断阶段不关单)。遗留待维护者拍板:修复未提交。 ### 实施收口(2026-10-14,维护者 /implement 指令) **限定提交 [`850c6c6`](../../../../../) `fix(cockpit): use GLSL3 fragment input in scene-grade shader (#36)`**,仅 2 文件、+12/−4: - `cesiumEngine.js`:**一行** `varying vec2` → `in vec2`(GRADE_FRAGMENT_SHADER 片元输入); - `t49-scene-grade.mjs`:闸门断言从「把 bug 当规格」(原断言 `varying` 正确)改为对 GRADE/FOG 双 stage 断言 GLSL3 输入并拒绝 `varying/texture2D/gl_FragColor`;含**截断哨兵**(`void main` 存在性,防提取正则被反引号静默截断而 fail-open)——哨牙经变异测试证实有效(注入杂散反引号 → 闸门红;还原 → 绿)。 **采用工作树既有修复的理由**:修复内容与票 49 的已验证修法逐字一致(`in vec2`,不动数学/uniform/配置),本票的增量是**把它提交固化 + 闸门反向锁定**,不重复造修复。 **测试与验证**: - 纯提交内容自洽(临时 worktree 于 `850c6c6` 复跑):t49 全绿、t38 雾闸门全绿、GLSL1 残留扫描 CLEAN、两处片元输入均 `in vec2`。 - 真机浏览器(dev 实例,11:48/11:52):整幅地图连续渲染,控制台零 shader 错误、零 `Rendering has stopped`。 - **CDP 交互探针**(`verify/artifacts/t36/probe-acceptance.mjs`,9/9 过,报告 `acceptance-report.json` + 截图 `final-state.png`):引擎 ready、`mapGrade=on`(调色级真实在跑);四模式切换(总体概览/基础设施/运行监测/预警处置)后引擎均 ready 且零新增 console 错误;真实对象定位点击不炸帧;静置 35s 帧统计 n=282/p50=33ms/p95=350ms(软渲染底噪口径,同票 33),零 pageerror。post 交互窗口 rAF n=20/1.5s 为 CDP 无头按需渲染(场景静止时不再请求帧),非冻结——引擎态与零错误为准。 **验收对照**: 1. ✅ 进入系统地图持续渲染、无 shader 编译错误/Rendering has stopped(真机 + 探针 `no-shader-compile-error`/`no-rendering-stopped`/`engine-ready`)。 2. ✅ 调色按现有配置工作:`mapGrade=on`(启用路径);关闭路径由闸门 A1(`enabled=false` 被尊重)+ D1(建级/写参/销毁/归零)锁定——浏览器级关闭核对未做(修复不动开关数学,风险低,如实记为 minor)。 3. ✅ 程序面覆盖 freshness(35s+30s 静置跨刷新周期)、四模式切换、定位点击、帧形态无周期尖峰;**真人桌面 GPU 目视复核仍留给上位真人验收**(本票不替代)。 4. ⚠ 部分:最小限定 diff(2 文件)✅、回归证据 ✅、运行绑定 = 纯提交内容 worktree 复跑闸门 + dev 实例两文件与提交一致 ✅;**推送未做**——前端 `master` 现有 16 个未推送提交(多数属其他会话),不代推,随该分支后续统一推送上线(缺陷本就不在 `origin/master` 上)。 **code-review(两轴)**:Standards 0 硬违规(3 条判断题,已采纳「截断哨兵」建议并 amend);Spec 判定修复与回归锁定合格,欠账如上(推送 + 真人 GPU 目视 + 浏览器级关闭核对 minor)。 **状态**:修复完成、已提交(本分支)、未推送(不代推并行会话提交链)。 Status: resolved Type: bug Blocked by: Assignee: @me Labels: wayfinder:task, frontend-execution, bug ## Comments ### local — 2026-10-14(诊断,未改业务代码) > *This was generated by AI during triage.* ### local — 2026-10-14T04:00:38.296Z > *This was generated by AI during triage.* ## Triage Notes(2026-10-14,未改业务代码) **阶段判定:未动工;但缺陷已由另一张票修复 —— 本票是重复建票。** **一、现象(已复现)**:真实 dev 页面进入系统后地图黑屏,Cesium 报 `RuntimeError: Fragment shader failed to compile. ERROR: 0:7: 'varying' : Illegal use of reserved word`,随后 `Rendering has stopped`。 **二、根因(高置信,已确证到安装版 Cesium 源码)**:自有**调色**后处理 shader 用 GLSL1 语法,而 Cesium 在 WebGL2 下强制升级到 GLSL ES 3.00: 1. Cesium 1.145 shader 组装对 WebGL2 **无条件前置 `#version 300 es`**(`node_modules/cesium/Build/Cesium/index.js`,组装尾部 `n.webgl2?c=`#version 300 es\n${c}``)。 2. GLSL ES 3.00 **删除了 `varying`**(改 `in`/`out`)→ 报错落在 `ERROR: 0:7`,与 `const GRADE_FRAGMENT_SHADER` 第 7 行 `varying vec2 v_textureCoordinates;` 逐行对齐。 3. **权威接口核对**:Cesium 自带 `ViewportQuadVS` 声明 `out vec2 v_textureCoordinates;`,其配套片元 shader 一律用 `in vec2 v_textureCoordinates;` → 自有后处理必须跟随 `in`。 4. 后果:`PostProcessStage` 是**整帧**后处理,编译失败即 `Rendering has stopped` → 黑屏,不是「少一层滤镜」。 **三、引入点与触发条件**: | 项 | 结论 | | --- | --- | | 引入提交 | **`e2529b5`**(调色滤镜)——同文件**雾** shader 早在 `8db64fc` 已迁 `in vec2`,调色 shader **漏迁** | | 触发条件 | `GRADE_DEFAULTS.enabled = true` **且**部署 `public/cockpit/config.json` 显式 `"grade":{"enabled":true}` → 必然构建、必然编译失败,**非偶发、非特定 GPU** | | 所在版本 | 缺陷**只在未推送的本地提交上**:`origin/master`(`a6fbbea9`)不含调色处理级;committed HEAD(`09905be`)仍含 `varying` → **远端版本不受影响** | **四、修复状态(关键)**: - **修复已存在于工作树,但未提交**:调色与雾 shader 现均为 `in vec2 v_textureCoordinates;`,全 cockpit 源码无 `varying`/`gl_FragColor`/`texture2D` 残留。 - **同缺陷已由 [票 49「恢复驾驶舱3D渲染:调色与雾着色器的GLSL兼容性」](49-3d-glsl.md)(另一 effort,`resolved`)修复**:票 49 记录的根因、修法、证据与本轮完全一致(「只将两处片元输入改为 `in`,不关效果、不改数学/uniform/配置」)。 - **病侧测试反向锁定(值得记一笔)**:committed HEAD 的 t49 闸门**断言 `varying` 是正确写法**(注释「与雾 shader 保持一致」),即把 bug 当规格;工作树版本已改为断言 GLSL3 并**拒绝** `varying`/`texture2D`/`gl_FragColor`,先红后绿。这正是缺陷能过闸门进主干的机制。 **五、真实复验(只读,沿用既有 8000 实例,未另起服务)**:2026-10-14 11:52 进入正式入口,整幅地图**正常连续渲染**(地形/影像/管线/标记齐备,面板读真实 5283/9/33.3%),控制台**无** `varying` 编译错误、**无** `Rendering has stopped`;调色级按配置启用,故无错误即证明其编译通过。`t49-scene-grade.mjs` 全绿(含新 GLSL3 守卫)。 **六、分流**:分类 `bug`;状态落 **`wontfix`**(**已实现/重复** —— 缺陷已由票 49 修复,本票无独立待办)。已摘 `needs-triage`。**未关闭**(诊断阶段不关单)。 **遗留(唯一真问题)**:修复**只在工作树、未提交、未推送** → 「正式入口不再黑屏」目前**只对本地 dev 实例成立**;从远端拉取仍会复现黑屏。详见收尾提问。 **本轮未做**:未修改业务代码、未关闭本票、未代表票 49 提交或推送其成果、未改动 t18 上位票。 ## Triage Notes **阶段判定:未动工;但缺陷已由另一张票修复 —— 本票是重复建票。** **一、现象(已复现)** 票面记载:真实 dev 页面 `http://127.0.0.1:8000/#/cockpit` 进入系统后地图黑屏,Cesium 报 `RuntimeError: Fragment shader failed to compile. ERROR: 0:7: 'varying' : Illegal use of reserved word`,随后 `Rendering has stopped`。 **二、根因(高置信,已确证到安装版 Cesium 源码)** 自有**调色**后处理 shader 用的是 GLSL1 语法,而 Cesium 在 WebGL2 下强制升级到 GLSL ES 3.00: 1. Cesium 1.145 的 shader 组装函数对 WebGL2 **无条件前置 `#version 300 es`**(`node_modules/cesium/Build/Cesium/index.js`,组装尾部 `n.webgl2?c=\`#version 300 es\n${c}\``)。 2. GLSL ES 3.00 **删除了 `varying` 关键字**(改 `in`/`out`)→ 报错「Illegal use of reserved word」正好落在 `ERROR: 0:7`,与源码 `const GRADE_FRAGMENT_SHADER` 第 7 行 `varying vec2 v_textureCoordinates;` 逐行对齐。 3. **权威接口核对**:Cesium 自带的 `ViewportQuadVS` 顶点着色器声明 `out vec2 v_textureCoordinates;`,其配套片元着色器一律用 `in vec2 v_textureCoordinates;` → 自有后处理必须跟随 `in`。 4. 失败后果:`PostProcessStage` 是**整帧**后处理,编译失败即 `Rendering has stopped` → 地图黑屏,不是「少一层滤镜」。 **三、引入点与触发条件** | 项 | 结论 | | --- | --- | | 引入提交 | **`e2529b5`**(「add configurable blue-tone scene grade filter」)——同文件的**雾** shader 早在 `8db64fc` 已迁到 `in vec2`,调色 shader **漏迁**,属拷贝模板时未跟随 | | 触发条件 | `GRADE_DEFAULTS.enabled = true`(`domain/sceneGrade.js`)**且**部署配置 `public/cockpit/config.json` 显式 `"grade": { "enabled": true, ... }` → 处理级必然构建、必然编译失败。**不是**偶发或仅特定 GPU | | 所在版本 | 缺陷**只在未推送的本地提交上**:`origin/master`(`a6fbbea9`)根本不含调色处理级;committed HEAD(`09905be`)仍含 `varying`。故**生产/远端版本不受影响** | **四、修复状态(关键)** - **修复已存在于工作树,但未提交**:`src/modules/cockpit/services/cesiumEngine.js` 的调色与雾 shader 现均为 `in vec2 v_textureCoordinates;`,全 cockpit 源码已无任何 `varying` / `gl_FragColor` / `texture2D` 残留。 - **同缺陷已由 [票 49](../../cockpit-shell-panel-layout/issues/49-3d-glsl.md)(另一 effort,`resolved`)修复**:票 49 的记录与本轮根因、修法、证据完全一致(同为「只将两处片元输入改为 `in`,不关效果、不改数学/uniform/配置」)。 - **病侧测试反向锁定(值得记一笔)**:committed HEAD 的 [t49 闸门](../../cockpit-shell-panel-layout/verify/t49-scene-grade.mjs) **断言 `varying vec2 v_textureCoordinates;` 是正确写法**(注释写「与雾 shader 保持一致」),即把 bug 当成了规格;工作树版本已改为断言 GLSL3 接口并**拒绝** `varying`/`texture2D`/`gl_FragColor`,先红后绿。**这正是缺陷能过闸门进主干的机制。** **五、真实复验(只读,使用既有 8000 实例,未另起服务)** 2026-10-14 11:52 进入 `http://127.0.0.1:8000/#/cockpit`:整幅地图**正常连续渲染**(地形、影像、管线、状态标记齐备,面板读真实数据 5283/9/33.3%),控制台**无** `varying` 编译错误、**无** `Rendering has stopped`;因调色级按上述配置为启用,无错误即证明该 shader 编译并通过。逻辑闸门 `t49-scene-grade.mjs` 全部通过(含新 GLSL3 守卫)。 **六、分流建议** 分类 `bug`;状态落 **`wontfix`**(理由:**已实现/重复** —— 缺陷已由票 49 修复,本票无独立待办;**不是**「已实现 → 关单」以外的终态)。已摘 `needs-triage`。**未关闭**(诊断阶段不关单)。 **遗留(唯一真问题,见收尾提问)**:修复**只在工作树、未提交、未推送**,因此「正式入口不再黑屏」目前**只对本地 dev 实例成立**;任何人从远端拉取都会复现黑屏。 ## Answer **已修复并收口(2026-10-14,实施提交 `850c6c6`)。** - **根因**:自有调色后处理 shader 用 GLSL1 的 `varying`,而 Cesium 1.145 在 WebGL2 下前置 `#version 300 es`,GLSL ES 3.00 已删除该关键字 → 编译失败即整帧停止(黑屏)。引入提交 `e2529b5`(同文件雾 shader 先已迁 `in vec2`,调色漏迁);触发条件=调色默认启用且部署配置显式启用。 - **修复**(限定 2 文件 +12/−4):GRADE 片元输入 `varying` → `in vec2`(与票 49 已验证修法一致——本票增量为**提交固化**,不重复造修复);t49 闸门反向锁定:GLSL3 输入断言 + GLSL1 语法拒绝 + **截断哨兵**(防提取正则被杂散反引号静默截断而 fail-open,变异测试证实哨兵有效)。 - **验证**:纯提交内容(临时 worktree 于提交点)复跑 t49/t38 全绿、GLSL1 零残留;真机 dev 实例地图连续渲染、控制台零 shader 错误;CDP 交互探针 **9/9**(四模式切换 / 真实对象定位 / 跨 freshness 周期静置,引擎恒 `ready`、`mapGrade=on`、零 pageerror)。证据 `verify/artifacts/t36/acceptance-report.json`、`final-state.png`。 - **未竟(如实)**:**未推送**——前端 `master` 现有 16 个未推送提交多为其他会话在制品,不代推;缺陷本不在 `origin/master` 上,随分支统一推送上线。浏览器级关闭路径核对未做(闸门级 A1/D1 已锁定,minor);真人桌面 GPU 目视归上位真人验收。 ## Answer