You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js服务器用draco3d压缩GLB文件遇编码错误求助

问题分析与解决

核心问题

你直接将GLB文件的二进制数据(Uint8Array)传给了EncodeMeshToDracoBuffer,但Draco编码器不支持直接处理GLB容器文件。EncodeMeshToDracoBuffer需要的是Draco库定义的Mesh对象(包含顶点、索引、法线等几何属性的结构化数据),而不是原始的GLB二进制。返回0是因为编码失败,后续用Buffer.from(0)自然会触发类型错误。

正确流程

要压缩GLB中的模型,必须先解析GLB提取出网格数据,转换成Draco能识别的格式,再进行编码:

  1. 解析GLB文件,提取场景中的Mesh几何数据
  2. 将Mesh的顶点、索引、法线等属性导入Draco的Mesh对象
  3. 使用Draco编码器对Mesh对象进行编码
  4. 提取编码后的二进制数据并保存为.drc文件

修改后的代码示例

这里用three.js来解析GLB(Node.js环境可用),结合draco3d完成压缩:

首先安装依赖:

npm install three draco3d

然后修改控制器中的Draco处理部分:

const { GLTFLoader } = require('three/examples/jsm/loaders/GLTFLoader');
const { BufferGeometryUtils } = require('three/examples/jsm/utils/BufferGeometryUtils');
const THREE = require('three');
const draco3d = require('draco3d');

// ... 原有代码 ...

/*********** DRACO ************** */
const dracoEncoderModule = draco3d.createEncoderModule({});

dracoEncoderModule
  .then((module) => {
    const encoder = new module.Encoder();
    // 设置压缩参数(可选,值越高压缩效果越好但速度越慢)
    encoder.SetSpeedOptions(5, 5);

    // 用three.js解析GLB文件
    const loader = new GLTFLoader();
    loader.load(
      pathGLB,
      (gltf) => {
        // 提取模型中的所有网格
        const geometries = [];
        gltf.scene.traverse((child) => {
          if (child.isMesh) {
            geometries.push(child.geometry);
          }
        });
        if (geometries.length === 0) {
          console.error('GLB文件中未找到Mesh数据');
          return;
        }
        // 合并多个网格(如果模型有多个部件)
        const mergedGeometry = BufferGeometryUtils.mergeBufferGeometries(geometries);

        // 将three.js的BufferGeometry转换为Draco的Mesh
        const dracoMesh = new module.Mesh();
        
        // 导入顶点数据
        const positionArray = mergedGeometry.attributes.position.array;
        const positionAttribute = new module.Attribute();
        positionAttribute.Init(3, module.TYPE_FLOAT32, positionArray.length / 3, new module.DracoFloat32Array(positionArray));
        dracoMesh.AddAttribute(module.POSITION, positionAttribute);

        // 导入索引数据(如果存在)
        if (mergedGeometry.index) {
          const indexArray = mergedGeometry.index.array;
          const indexAttribute = new module.Attribute();
          indexAttribute.Init(1, module.TYPE_UINT32, indexArray.length, new module.DracoUInt32Array(indexArray));
          dracoMesh.AddAttribute(module.INDICES, indexAttribute);
        }

        // 导入法线数据(可选,提升渲染效果)
        if (mergedGeometry.attributes.normal) {
          const normalArray = mergedGeometry.attributes.normal.array;
          const normalAttribute = new module.Attribute();
          normalAttribute.Init(3, module.TYPE_FLOAT32, normalArray.length / 3, new module.DracoFloat32Array(normalArray));
          dracoMesh.AddAttribute(module.NORMAL, normalAttribute);
        }

        // 执行编码
        const encodedBuffer = new module.DracoInt8Array();
        const encodingResult = encoder.EncodeMeshToDracoBuffer(dracoMesh, encodedBuffer);
        
        if (encodingResult === module.SUCCESS) {
          // 转换为Node.js Buffer并保存
          const encodedData = Buffer.from(encodedBuffer.buffer, encodedBuffer.byteOffset, encodedBuffer.length);
          fs.writeFileSync(pathDRC, encodedData);
          console.log('Draco压缩完成');
        } else {
          console.error('Draco编码失败,错误码:', encodingResult);
        }

        // 释放WebAssembly内存
        module.destroy(dracoMesh);
        module.destroy(encoder);
        module.destroy(encodedBuffer);
      },
      undefined,
      (err) => {
        console.error('解析GLB失败:', err);
      }
    );
  })
  .catch((error) => {
    console.error('初始化Draco编码器失败:', error);
  });

/************************* */

关键说明

  • GLB解析:three.js的GLTFLoader能正确解析GLB中的场景、Mesh等数据,遍历场景可提取所有网格并合并(适配多部件模型)。
  • Draco Mesh构建:必须手动将three.js的几何属性(顶点、索引、法线等)导入Draco的Attribute对象,再添加到Draco的Mesh中,这是Draco编码器唯一能识别的输入格式。
  • 内存管理:Draco的WebAssembly模块创建的对象需要手动调用module.destroy()释放,避免内存泄漏。
  • 压缩参数:SetSpeedOptions可调整压缩速度和质量,第一个参数是编码速度(1-10),第二个是解码速度(1-10),可根据业务需求平衡选择。

内容的提问来源于stack exchange,提问作者Ruslan Karimov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 14:57:49