Maya gltf exporter -- mesh breaks when bone count exceeds 128. Is this a known issue?

Hello, all! Making my first post here.

Wondering if anyone else has run into this problem, or maybe it’s a known limitation of the Babylon Maya plugin.

We’ve been iterating versions with a rigged and animated character, exporting to gtlf out of Maya 2018 using the Babylon plugin. We ran into an odd problem where some verts on the character were stretched out of place, more or less aiming toward the origin. (This problem appeared only after exporting the gltf.) After a lot of troubleshooting, I found that the problem went away when I reduced the number of bones on the rig to 128. It does not seem to matter which joints/bones I remove – once it’s 128 or lower, the geo comes out fine. If only we could get away with just 128 bones, but for this character, we cannot.

Other bits of data:

  • This threshold of 128 applies when all those bones are part of the same skincluster. If the geometry is made up of separate meshes, the errant verts problem goes away. (Too bad I can’t just use this as a workaround, because the delivery specs for this project require a single mesh.)

  • We’ve got a max of 4 influences per vert – double-checked that.

  • This is a fun one. When I view one of these ugly gtlf files in the sandbox.babylonjs.com viewer, and I use the “Export to GLB” tool in the inspector, the glb file that comes back looks fine. The verts return to where they belong. (Too bad I can’t just use this as a workaround, because the “Export to GLB” tool does not yet export bones.)

Unfortunately, because I’m working on a commercial project with sensitive content, I am unable to share any of these files. I’m aware that is a problem. But like I said, at this stage I’m just curious if this is something anyone else has encountered.

Have you checked that skeleton.isUsingTextureForMatrices returns true? I think that if a texture is used to store the bone matrices there’s no limit on the number of bones you can use. However, if it is false, you are limited by the number of uniforms you can pass to a shader.

You can use the skeleton.useTextureToStoreBoneMatrices property to force using a texture (your webgl implementation must support float texture and vertex texture image unit, however).

I have to confess that your kind reply is beyond my understanding – I’m not that deep into the process, certainly not working at the api level. I searched those terms and did some reading, but I’m only a novice coder.

However, I have been poking some more at this issue, and I found something more of interest. When I compare versions of our asset, one with 128 joints and the other with 130, the latter generates ~100 more errors in the inspector. They look like this, with only the 5-digit index number varying.

“code”: “ACCESSOR_JOINTS_INDEX_OOB”,
“message”: “Joints accessor element at index 33863 (component index 3) has value 65408 that is greater than the maximum joint index (130) set by skin 0.”,
“severity”: 0,
“pointer”: “/meshes/0/primitives/2/attributes/JOINTS_0”
Blockquote

That erroneous value of 65408 that is getting assigned improperly…
65408 = 65536 - 128

When powers of 2 are involved like that, I get suspicious of bitwise issues.

1 Like

I would rather say it’s a problem with signed/unsigned short or byte values…

I’m not sure if it’s a problem on Babylon or the file side: the error message you provided may be generated by the GLTF validator, meaning it is not a valid file.

Can you try to check the file here and see what happens?

Yes, an issue with signed/unsigned short or byte values… makes sense.

I get the same messages in the khronos validator, ~100 of them.

So it’s a problem with the Maya exporter I guess.

pinging @Drigax

1 Like

I tried using Facebook’s FBX2GLTF exporter, and there are no geometry problems when I go that route.
Unfortunately, going that route messes up our shaders. :cry:

That investigation sounds really suspicious. I assume we’re doing something seriously wrong here. Currently i believe that we export bone indices as 8bit unsigned byte, for a theoretical max of 255 bones per skin (gltf actually supports 16 bit short as well for a max bone count of 65535) but the fact that 128 works while 130 doesnt, sounds like were using signed byte somewhere along the way, your error index looks like casting a negative signed byte to unsigned short… Not totally sure whats going on offhand. I’ll take a closer look tomorrow after I’m a little less sore from lugging boxes all day.

@hermantah can you upload a scene that reproduces this when exported? It would make the investigation a bit quicker if i dont need to rig up a 128 bone asset

1 Like

I will try to transfer the rig to a different human model and see if I can reproduce it. The skinning won’t be pretty, but it should work for our purposes.

Thanks, I think I was able to address it.

ProgC (ProgC) · GitHub provided a nice snippet to fix our bitwise operations when unpacking the babylon indices into glTF, looks like making that change fixes our skeleton export:
bonesIndicesMerged's bit operation bug? · Issue #810 · BabylonJS/Exporters · GitHub

4 Likes

Fantastic, thanks!

I will report back when I can test.

2 Likes

Success!

Mesh is behaving wonderfully.

Thanks again for the help!

2 Likes