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

Nil*_*ilu 4 three.js gltf

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

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

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

  2. 我们使用jsdom来解决与窗口、文档等相关的问题。

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

  4. 当使用纹理加载 GLTF 时,响应会卡住。

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

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

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

        const { Image } = require("canvas");
        const image = new Image();
        image.onload = onImageLoad;
        image.onerror = onImageError;
Run Code Online (Sandbox Code Playgroud)

d) 经过上述更改后,加载方法得到了解决。

e) 下一步 - 导出 GLTF - 由于未找到 ImageData 错误,我们陷入了困境。我们从画布添加了 ImageData,并导出了 GLTF。

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

 "images": [
    {
      "mimeType": "image/png",
      "uri": "data:,"
    }
  ],
Run Code Online (Sandbox Code Playgroud)

如果有人纯粹在服务器端加载并合并 GLTfs 与纹理图像,请帮忙!

Don*_*rdy 7

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

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);
Run Code Online (Sandbox Code Playgroud)

值得注意的是,这个过程将产生一个包含多个单独场景的 glTF 文件。如果您想将它们组合成一个场景,并以某种方式排列,您需要使用场景 API来完成此操作。如果文件不在磁盘上,则还有其他 NodeIO API用于处理内存中的二进制或 JSON 文件。