webgl-texture-error-analysis.md 3.1 KB

WebGL 纹理扩展错误分析

错误信息

Failed to load OES_texture_float_linear. Texture filtering is not available for *32F internal formats.

错误原因分析

1. WebGL 扩展支持问题

  • OES_texture_float_linear 是一个 WebGL 扩展
  • 用于支持 32 位浮点纹理的线性过滤
  • 不是所有 GPU/浏览器都支持这个扩展

2. 医学图像格式问题

  • DICOM 图像通常使用高精度格式(16位或32位)
  • Cornerstone.js 尝试使用浮点纹理来处理这些高精度图像
  • 当 GPU 不支持浮点纹理线性过滤时就会报错

3. 发生位置

// DcmCell.tsx:56 - stackViewport.setStack() 调用时
await stackViewport.setStack([fullImageUrl], 0);
stackViewport.render(); // 可能在这里触发WebGL错误

解决方案

方案1:添加 WebGL 兼容性检测

// 检测 WebGL 扩展支持
const checkWebGLSupport = () => {
  const canvas = document.createElement('canvas');
  const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
  if (!gl) return false;
  
  const floatLinearExt = gl.getExtension('OES_texture_float_linear');
  return !!floatLinearExt;
};

方案2:配置 Cornerstone 渲染选项

// 在创建 viewport 时配置渲染选项
const viewportInput: cornerstone.Types.PublicViewportInput = {
  viewportId: viewportId,
  type: Enums.ViewportType.STACK,
  element: viewportRef.current,
  defaultOptions: {
    background: [0.1, 0.1, 0.1],
    // 添加渲染配置
    renderer: {
      preferLowerPrecision: true, // 优先使用低精度纹理
      enableFloatTextures: false, // 禁用浮点纹理
    }
  },
};

方案3:改进错误处理

const loadImage = async (targetImageId: string, source: 'props' | 'drag' = 'props'): Promise<boolean> => {
  if (!stackViewport || !targetImageId) return false;
  
  try {
    const fullImageUrl = targetImageId.startsWith('dicomweb:')
      ? targetImageId
      : getDcmImageUrl(targetImageId);
    
    await stackViewport.setStack([fullImageUrl], 0);
    stackViewport.render();
    setHasImage(true);
    
    console.log(`[DcmCell] 图像加载成功 (${source}): ${targetImageId}`);
    return true;
  } catch (error) {
    // 特别处理 WebGL 相关错误
    if (error.message && error.message.includes('OES_texture_float_linear')) {
      console.warn(`[DcmCell] WebGL 浮点纹理不支持,尝试降级渲染: ${error.message}`);
      // 尝试降级处理
      try {
        // 可以尝试不同的渲染配置
        await stackViewport.setStack([fullImageUrl], 0);
        stackViewport.render();
        setHasImage(true);
        return true;
      } catch (fallbackError) {
        console.error(`[DcmCell] 降级渲染也失败: ${fallbackError}`);
      }
    }
    
    console.error(`[DcmCell] 图像加载失败 (${source}):`, error);
    setHasImage(false);
    return false;
  }
};

推荐实施步骤

  1. 首先添加更详细的错误处理和日志
  2. 检查是否可以配置 Cornerstone 使用更兼容的渲染模式
  3. 如果问题持续,考虑添加 WebGL 兼容性检测和降级方案