Gltf + multiple bin

Hey @donmccurdy

I am trying to convert a glTF file into multiple BIN files. I came across an SDK called glTF Transform. I achieved this using the command-line API, and now I want to do the same using the scripting API.
I found the following code:

document.getRoot().listBuffers(); // → [Buffer]
await document.transform(partition({meshes: true}));
document.getRoot().listBuffers(); // → [Buffer, Buffer, ...]

However, in the command-line API, we can pass the name of the meshes.

  1. How can we pass the name of the meshes to the scripting API?
  2. In another case, sometimes the glTF file doesn’t contain any mesh names, or they may be empty. How can we still convert such a glTF file into a glTF file with multiple BIN files?
  1. How can we pass the name of the meshes to the scripting API?

Instead of meshes: true you can provide an array of string mesh names. For example:

await document.transform(partition({meshes: ['A', 'B', 'C']}));

See PartitionOptions.

  1. In another case, sometimes the glTF file doesn’t contain any mesh names, or they may be empty. How can we still convert such a glTF file into a glTF file with multiple BIN files?

In order to have external BIN files, the glTF document must contain at least some binary data. If there are no meshes and no animations, then it’s unclear what would go into those BIN files.

Aside – there is a dedicated discussion area for glTF Transform, if you have questions specifically about the library.

Thanks @donmccurdy

  1. How can we save those files in any folder?
  2. Can we create a separate bin file for animations and images/textures?

@donmccurdy
I am waiting for your reply,

  1. Is it possible to create separate .bin files for animations and images/textures using gltf-transform?
  2. While exploring gltf-transform, I learned that to create multiple .bin files, the --meshes command is used. Is it possible to export based on nodes instead?

The CLI supports changing where the base .gltf is saved, but doesn’t customize locations of texture and .bin resources. To do these customizations you’d need to use the scripting API, and methods like buffer.setURI('path/to/buffer.bin') and texture.setURI. See Buffer | glTF Transform.

Is it possible to create separate .bin files for animations and images/textures using gltf-transform?

glTF Transform writes images to separate files, and does not embed them in a .bin.

While exploring gltf-transform, I learned that to create multiple .bin files, the --meshes command is used. Is it possible to export based on nodes instead?

Not through the CLI – You may find it helpful to see how the per-mesh partitioning is implemented in the scripting interface, as you could customize this further to group binary data into buffers however you prefer:

Thanks @donmccurdy ,

I recently discovered that when using the optimize method via the CLI in gltf-transform, it optimizes the GLTF file by internally invoking the following methods:

  1. dedup
  2. instance
  3. palette
  4. flatten
  5. join
  6. weld
  7. simplify
  8. resample
  9. prune
  10. sparse
  11. textureCompress
  12. draco

I would like to examine the internal algorithm of the optimize function. Could you please provide the link to that function’s source code if it’s available on GitHub?

Actually, I’m currently trying to create multiple bins for a single GLTF file, but I noticed that the number of bins differs between the CLI and the JavaScript API. This is why I’m interested in reviewing the optimize function’s algorithm (since the optimize function isn’t available in the JavaScript API).

Hi @swapnil.vikhe — you can find the implementation of the optimize() command here:

Each of the transform functions you list are implemented separately as functions from the @gltf-transform/functions model, you can find the individual function implementations at:

Hi @donmccurdy,

While reviewing the optimize action, I found that it uses the following parameters when the command is called:

const opts = options as {
instance: boolean;
instanceMin: number;
meshoptLevel: ‘medium’ | ‘high’;
palette: boolean;
paletteMin: number;
simplify: boolean;
simplifyError: number;
simplifyRatio: number;
simplifyLockBorder: boolean;
prune: boolean;
pruneAttributes: boolean;
pruneLeaves: boolean;
pruneSolidTextures: boolean;
compress: ‘draco’ | ‘meshopt’ | ‘quantize’ | false;
textureCompress: ‘ktx2’ | ‘webp’ | ‘auto’ | false;
textureSize: number;
flatten: boolean;
join: boolean;
weld: boolean;
};
However, I’m curious about the standard parameters being used.

The full source code is what you see there, at the link. The partition command can also accept a boolean, partition({meshes: true}), to put each mesh in a separate .bin. Any defaults not in the “optimize” implementation are probably the defaults of the individual commands, in their source files.

Hi @donmccurdy,
While optimizing a model using GLTF Transform, I encountered the following issue:

When I inspected the model using the GLTF Validator, I discovered that the attributes for some meshes were empty. Please refer to the following image:

It seems likely that the optimization error is occurring due to the empty attributes (correct me if I’m wrong).

If that’s the case, is there a method or approach to remove these empty attributes using GLTF Transform?

It would be possible to remove empty primitives with the glTF Transform scripting API, yes — but I’d be very surprised if that’s the only problem given this validation output.

That missing FB_ngon_encoding extension could be a concern, it’s a proposal/draft extension and was never completed. So there may be some problems with this model. If you can share the original model (before glTF Transform has processed it) that may provide more information.

The issue isn’t with the primitives themselves; it’s that some mesh primitives have empty attributes. Can we manage cases where attributes are missing or empty?

image

I am waiting for your reply @donmccurdy

Removing primitives without extensions can be done the scripting API:

import { prune } from '@gltf-transform/functions';

for (const mesh of document.getRoot().listMeshes()) {
  for (const prim of mesh.listPrimitives()) {
    if (prim.listAttributes().length === 0) {
      prim.dispose();
    }
  }
  if (mesh.listPrimitives().length === 0) {
    mesh.dispose();
  }
}

await document.transform(
  prune({ keepLeaves: false })
);

However, I do not think this will solve the underlying problem.

glTF Transform supports the extensions listed on this page:

When loading files containing extensions not listed there, like FB_ngon_encoding, any number of problems may manifest in the file, and I expect this includes the errors you’re seeing now. To support the FB_ngon_encoding extension in glTF Transform, you would need to provide a custom implementation of the extension, as described in the “Custom extensions” section of the link above. Or, perhaps preferably, find a way to export the original file without this extension.

Please be aware that this is a forum. Replies may be delayed, and I do not provide daily 1:1 support.

Hi @donmccurdy,

I’m encountering an issue with a model that includes identical parts. When I apply all optimization methods and partitioning using the glTF Transform JavaScript API, the scale of these identical parts decreases during meshopt compression (using the method described below). However, this issue doesn’t occur when I use Draco compression instead of meshopt.

Interestingly, this problem only happens with certain models, while others work as expected.

Meshopt compression will typically scale vertex positions to fit a quantization grid, and then apply an inverse transform to the parent node. The appearance of the full model should remain the same, but if you’re using parts of the model individually in your application, it would be something to be aware of.

Hi @donmccurdy,
I encountered an issue while exporting a GLTF file using the “gltf-transform” library. Most of the elements are being grouped together, and when I try to select a single element, the entire group gets selected. I would like to avoid this behavior.

Could you please guide me on how to configure the export so that individual elements can be selected separately instead of as a group?

I would suggest starting a discussion thread in the glTF Transform GitHub page…

…and including more details about which operations of glTF Transform you’re applying to the files. If you’re applying operations that merge meshes, those results are expected.