USDZ Exporter increases file size

I’ve noticed that three.js now supports exporting scenes to USDZ files.

That’s awesome BTW!

I’ve tried to convert a scene loaded from a GLB file that weighs 2.5 MB and got a USDZ file with the weight of 130 MB.

Maybe I’m doing something wrong, I’m not sure.

Has anyone encountered this issue before?

Thanks.

GLB is a binary format, and THREE.USDZExporter can only support the ASCII form of USDZ. That difference will likely increase the size, although 2.5MB → 130MB is more than I would’ve expected. I’m not sure if there are tools to convert ASCII USDZ to binary USDZ, but probably that would be very hard to implement and maintain without using the native USDZ runtime.

I think the main purpose of USDZExporter is to convert files “on the fly” so that they can be loaded on iOS devices that don’t support WebXR, where the file size is less of an issue since the file is never transferred over the network. If that’s not what you’re doing it may be better to use an offline converter like GitHub - google/usd_from_gltf, which have access to the full USD runtime for the conversion.

1 Like

Thanks @donmccurdy

You are using fflate which does converts ASCII to binary as far as I know.

USDZ is, according to my knowledge, a binary (zipped / gzip) USD.

Even for the use case you have mentioned, you are still loading 130 MB to the RAM.

Even if the output was ASCII I would expect to see the same difference like you would between a glTF and a GLB .

BTW, for the “on the fly” use case to work you will need the file (a blob link?) to have a curtain content type header - Content-Type: model/vnd.usd+zip.

Can you even do that with createObjectURL?

I guess maybe you can:

let blob = new Blob([e.data], {
  type: 'model/vnd.usd+zip'
});

Need to check if it actually works.

After taking a look at the exporter I cannot see any reference for textures when building the material. It’s like the exporter only states the base color, metalness and roughness.

Does it even works?

You are using fflate which does converts ASCII to binary as far as I know.

This understanding isn’t quite correct — fflate does technically output binary data, but in that case it’s still just wrapping larger plaintext source data. Note that USDZ uses zero-compression zipping, so the size of the zipped data is no smaller than the original. Data that is binary to begin with will generally be much smaller.

USD has ASCII and binary variants (USDA and USDC), and USDZ could contain either. This works quite differently than glTF vs GLB… USDC and GLB are pretty similar, but USDA is much less efficient than glTF1.

Probably that’s all beside the point though, because (1) three.js can’t write binary (USDC) data into the USDZ anyway, and (2) it’s entirely possible that the ASCII vs. binary difference isn’t big enough to explain the 50x increase you’re seeing. I’m not sure how to test that without comparing a binary-ified USDZ file, though, sorry.

If your source GLB used Draco or Meshopt compression, or quantization, that would be another explanation, because that compression won’t carry over into USDZ at all.


1 Best case: .gltf references an external .bin and the binary data is exactly the same as a .glb… Worst case: .gltf contains Data URIs for the binary data, which add ~25% to the data size. Either way, the vertex data in glTF is still never plaintext ASCII numbers like it would be in OBJ or USDA.

1 Like

No, textures are not exported yet. Note that this exporter was just added to the project eight days ago, and isn’t even in a published release yet — consider it experimental at this point.

I didn’t use any compression. The glTF file size is about 3.5 MB BTW.

Sure, makes sense.

Super interesting.

Thanks.

1 Like