USDZ Export Issue – Incorrect Metallic/Roughness Rendering, Overly Glossy Appearance, and Flipped Normals

Hi, I believe there’s an issue with the USDZ exporter, specifically related to how it handles roughness values in the metallic/roughness workflow. When I export the same model to the GLB format, everything looks correct. However, exporting to USDZ from the same scene results in a visually different model: it appears overly glossy with intense white reflections and lacking any roughness.

When viewed on Mac or AR mode on iPad, the model has no visible roughness and is excessively reflective.

Tested on:
MacBook Pro 2018 (macOS 13.2.1)
iPad Pro (11-inch) MTXN2FD/A (iPadOS 18.5)

Moreover, in this particular demo model, it seems, that normals are flipped, which is I think a different bug.

Exporter:

An example of problematic model:

You can also use an online viewer, where you can see the flipped textures and the lack of roughness.




cc @alexchuber

1 Like

Thanks for the report! Will investigate soon.

The USDZ exporter is fairly new and limited in its PBR capabilities, but I wouldn’t expect the metal/rough values of a Babylon PBRMaterial to export like that. And the flipped orientation is certainly wrong :wink:

1 Like

Once this is in, you should be set :+1:

2 Likes

Hi @alexchuber , great, I see a significant improvement! Thank you for solving the issue with normal vectors, I haven’t noticed any problems regarding this issue anymore.

Unfortunately, on my models there were still too many reflections. The models looked different than they did when exported from Unity. I started digging into why this might be happening, and I noticed that even with a simple example of a sphere with a material where metallic = 1 and roughness = 0 the problem is still visible.
I created a simple Playground where it’s easy to generate GLB and USDZ files, and use, for example, an online converter to transform GLB to USDZ by a different way. In this case, the sphere actually looks metallic.
With the current Babylon.js exporter, however, the sphere looks more like a magnifying glass than a chrome ball. Maybe that’s why my models haven’t been perfect yet.

Playground:

GLB → USDZ converter used:



Hi again @alexchuber ,

I don’t know if this will be helpful, but I have the impression that setting “gammaSpace” on the albedo texture works in the opposite way for USDZ export than, I guess, it should, which causes albedo textures to appear brighter, e.g., in Blender or in AR on iOS.

Specifically, when I set texture.gammaSpace = false before exporting to USDZ, in Blender, after import the texture shows “Color Space: sRGB”, and when I set texture.gammaSpace = true before export, I get “Color Space: Non-Color” in Blender.
Shouldn’t it work the other way around?

It seems that for the metallic/roughness texture, it should be set to “Non-Color” (linear), and for albedo “sRGB” (gamma corrected).

I have created a simple playground, to double check that:

Thanks a ton for the repro tips-- I’ll take a closer look this week. (But if you’ve already spotted the issue and are comfortable doing so, please feel free to open a PR!)

A couple of observations as I’m looking into this:

  1. I repro the sphere issue in AR mode on iOS, but not in Blender, Preview on Mac, or usdz-viewer.
  2. The sphere issue is a handedness issue with the vertex data
  3. The quickest way to get this sphere to look right in AR mode is to use sideOrientation = "leftHanded" in the USD mesh definition. Convenient!
  4. We might be able to get away with just updating the sideOrientation field. Ironically, in my testing of this field so far, it introduces new issues (with other test assets) in every other platform except AR mode on iOS. Need to investigate more.
  5. If not, we can fallback to updating the vertex data manually.

And nice catch on the gamma! It is indeed the opposite of what it should be :wink:

1 Like

Sorry for the delay! The combination of #4 and a tangentially-related glTF export issue was confusing to sort through.

The reflections on the sphere were wrong because we hadn’t yet implemented handling for left-handed geometry or their facingness, broadly. This PR will fix the sphere case, as well as a couple other gltf-import-related cases:

Let me know if you run into anything else.

3 Likes

Great work @alexchuber !! I have checked and now it is working great. Thank you! :clap:

One last thing I’ve noticed regarding materials: in Reality Composer Pro, USDZ models exported from BabylonJS don’t appear to work correctly. The materials aren’t visible instead, they show up as pink, which usually indicates a problem with the files. Unfortunately, I’m not seeing any more detailed error messages.

Other examples from official website, works correctly there, I downloaded from this link:

Do you have any idea what might be the cause? Should I create a new thread for this issue?

Does it happen only on Reality Composer? I’ll have to look at the export itself to know what’s going on, but something I discovered while debugging earlier was this suite of CLI tools built-in on Mac. They seem like promising diagnostic tools, so long as you know which Apple renderers the issue repros on.

This is just a straight USD export of the glTF BoomBox sample asset, right?

Yes, I have noticed this issue only in Reality Composer Pro (I’m using version 2.0 (448.120.2) on macOS 15.5).

The USDZ file of the boombox was downloaded from the link in the Babylon.js documentation:

I checked this model because my own models - exported using the new USDZ exporter from Babylon.js - appeared the same (with pink stripes, without materials).

I checked this model using the USD Toolset’s usdchecker also, and it returned this error and a failed status - the same happens with my models. Should I create a new thread for this issue?

Error checking rule 'NormalMapTextureChecker': UsdUVTexture prim </Materials/Material_12/Texture_13_normal> that reads Normal Map @/...path.../scene.usdz[textures/Texture_5_false.png]@ should set inputs:sourceColorSpace to 'raw'.
Error checking rule 'NormalMapTextureChecker': UsdUVTexture prim </Materials/Material_12/Texture_13_normal> reads 8 bit Normal Map @/...path.../scene.usdz[textures/Texture_5_false.png]@, which requires that inputs:scale be set to (2, 2, 2, 1) and inputs:bias be set to (-1, -1, -1, 0) for proper interpretation as per the UsdPreviewSurface and UsdUVTexture docs.
Failed!