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

ThreeJS导出GLTF/GLB时场景层级结构被破坏的问题

解决Three.js GLTF导出层级结构被破坏的问题

我使用以下代码导出Three.js场景:

function save(blob, filename) {
  const link = document.createElement("a");
  link.href = URL.createObjectURL(blob);
  link.download = filename;
  link.click();
  URL.revokeObjectURL(link);
}

function saveString(text, filename) {
  save(new Blob([text], { type: "text/plain" }), filename);
}

function saveArrayBuffer(buffer, filename) {
  save(new Blob([buffer], { type: "application/octet-stream" }), filename);
}

const exporter = new GLTFExporter();
exporter.parse(
  scene,
  function (result) {
    const name = `${modelName}.glb`;
    if (result instanceof ArrayBuffer) {
      saveArrayBuffer(result, name);
    } else {
      const output = JSON.stringify(result, null, 2);
      saveString(output, name);
    }
  },
  function (error) {
    console.log(error);
  },
  {
    binary: true,
    animations: [mixer.clipAction(model.animations[0]).getClip()],
  }
);

但导出后场景层级结构被破坏:原本直接挂载在scene下的对象,被自动嵌套到一个新创建的空对象中。我需要导出时保留场景的原始层级结构,同时保留对象的动画。

导出前场景层级:
导出前场景层级

导出后场景层级:
导出后场景层级


解决方法

GLTFExporter默认导出整个Scene对象时,会自动创建一个根包裹节点,导致层级嵌套。要保留原始层级,只需将导出目标从scene改为scene.children(场景的子节点数组),让原直接挂载在scene下的对象成为GLB的根层级对象。

修改后的导出代码:

function save(blob, filename) {
  const link = document.createElement("a");
  link.href = URL.createObjectURL(blob);
  link.download = filename;
  link.click();
  URL.revokeObjectURL(link);
}

function saveString(text, filename) {
  save(new Blob([text], { type: "text/plain" }), filename);
}

function saveArrayBuffer(buffer, filename) {
  save(new Blob([buffer], { type: "application/octet-stream" }), filename);
}

const exporter = new GLTFExporter();
exporter.parse(
  scene.children, // 直接导出场景子节点数组,避免自动创建根包裹对象
  function (result) {
    const name = `${modelName}.glb`;
    if (result instanceof ArrayBuffer) {
      saveArrayBuffer(result, name);
    } else {
      const output = JSON.stringify(result, null, 2);
      saveString(output, name);
    }
  },
  function (error) {
    console.error(error);
  },
  {
    binary: true,
    animations: [mixer.clipAction(model.animations[0]).getClip()],
  }
);

注意事项

  • 确保需要导出的动画目标对象存在于scene.children数组中,避免动画丢失或路径错误。
  • 如果动画引用出现异常,可以尝试使用THREE.AnimationUtils.stringifyClip()处理动画剪辑,或确保场景中对象名称唯一,避免路径解析冲突。

内容的提问来源于stack exchange,提问作者Mustafa AHCI

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 15:44:55