服务器端的多个 GLTF 加载和合并

Multiple GLTF loading and Merging on server side

我们正在尝试在服务器端合并多个 GLTF,并将合并的 gltf 作为最终结果导出到服务器。

我们已经证实有效和无效的事情:

  1. 我们使用了三个js GLTFLoader解析方法来加载多个gltf文件,合并加载对象的父子对象并使用GLTFExporter导出最终模型。

  2. 我们已经使用jsdom解决了与window、文档等相关的问题

  3. 上述要点适用于没有纹理的 gltfs

  4. 加载带有纹理的 GLTF 时,响应卡住。

    a) 我们尝试在服务器上托管文件并使用 GLTFLoader 加载方法,并将“localhost:******”作为加载程序路径。

    b) 在内部 TextureLoader 调用了 ImageLoader,其中根本没有触发 onLoad 事件。可能是 jsdom 没有调用它。

    c) 为了解决这个问题,我们将 ImageLoader 更改为具有 canvas 图像 :

        const { Image } = require("canvas");
        const image = new Image();
        image.onload = onImageLoad;
        image.onerror = onImageError;

d) 加载方法在上述更改后得到解决。

e) 下一步 - 导出 GLTF - 由于 ImageData 未找到错误,我们被卡住了。我们从 canvas 添加了 ImageData 并导出了 GLTF。

f) 导出的 GLTF 因图像中损坏的数据而无法查看

 "images": [
    {
      "mimeType": "image/png",
      "uri": "data:,"
    }
  ],

如果有人加载 GLTfs 并将其与纯服务器端的纹理图像合并,请帮助!

由于 three.js 主要是一个用于网络的 3D 渲染库,并且依赖于各种网络图像和 WebGL API,我不确定使用 THREE.GLTFLoader 是合并 glTF 的最有效方法Node.js 服务器上的文件。相反,我建议这样做:

import { Document, NodeIO } from '@gltf-transform/core';
import { KHRONOS_EXTENSIONS } from '@gltf-transform/extensions';

const io = new NodeIO().registerExtensions(KHRONOS_EXTENSIONS);

const document = new Document();
const root = document.getRoot();

// Merge all files.
for (const path of filePaths) {
  document.merge(io.read(path));
}

// (Optional) Consolidate buffers.
const buffer = root.listBuffers()[0];
root.listAccessors().forEach((a) => a.setBuffer(buffer));
root.listBuffers().forEach((b, index) => index > 0 ? b.dispose() : null);

io.write('./output.glb', document);

值得注意的是,此过程将生成包含多个独立场景的 glTF 文件。如果你想将它们组合成一个场景,以某种方式排列,你需要使用 scene API to do that. If the files are not on disk, there are other NodeIO APIs 来处理内存中的二进制文件或 JSON 文件。