cesium-patch.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. /**
  2. * Cesium 运行时补丁:为 PostProcessStage 添加 sampler3D uniform 支持。
  3. *
  4. * SuperMap 定制的 Cesium.js 缺少对 sampler3D (GL_SAMPLER_3D = 35679) 类型的
  5. * uniform 处理,导致含有 3D 纹理的 PostProcessStage 渲染崩溃。
  6. *
  7. * 修复策略:
  8. * 包装 WebGL2RenderingContext.prototype.getActiveUniform,
  9. * 将 SAMPLER_3D (35679) 报告为 SAMPLER_2D (35678),
  10. * 让 Cesium 的正常 uniform 处理流程接管。
  11. * 实际的 3D 纹理绑定由自定义纹理对象的 bind() 方法(使用 GL_TEXTURE_3D)完成。
  12. *
  13. * 必须在 Cesium 加载之后、任何 PostProcessStage 创建之前执行。
  14. */
  15. (function patchCesiumSampler3D() {
  16. if (typeof Cesium === 'undefined') {
  17. console.warn('[CesiumPatch] Cesium 未加载,跳过补丁');
  18. return;
  19. }
  20. const SAMPLER_3D = 35679;
  21. const SAMPLER_2D = 35678;
  22. let patchedCount = 0;
  23. // ── 包装 getActiveUniform ──────────────────────────────────────
  24. // 让 Cesium 把所有 sampler3D uniform 当作 sampler2D 处理。
  25. // 实际 3D 纹理绑定由纹理对象的自定义 bind() 方法自动处理。
  26. function wrapGetActiveUniform(proto) {
  27. if (!proto || !proto.getActiveUniform) return false;
  28. const orig = proto.getActiveUniform;
  29. proto.getActiveUniform = function (program, index) {
  30. const info = orig.call(this, program, index);
  31. if (info && info.type === SAMPLER_3D) {
  32. info.type = SAMPLER_2D;
  33. patchedCount++;
  34. }
  35. return info;
  36. };
  37. return true;
  38. }
  39. // WebGL2 上下文继承自 WebGLRenderingContext
  40. const patched2 = wrapGetActiveUniform(WebGL2RenderingContext.prototype);
  41. const patched1 = wrapGetActiveUniform(WebGLRenderingContext.prototype);
  42. if (patched2 || patched1) {
  43. console.log('[CesiumPatch] sampler3D → sampler2D 补丁已应用 ✅');
  44. console.log('[CesiumPatch] WebGL2RenderingContext:', patched2);
  45. console.log('[CesiumPatch] WebGLRenderingContext:', patched1);
  46. } else {
  47. console.warn('[CesiumPatch] 无法找到 getActiveUniform 进行补丁');
  48. }
  49. })();