Gltf-blender-io: GLTF is generated with zero weight vertices

Created on 1 Aug 2018  Â·  15Comments  Â·  Source: KhronosGroup/glTF-Blender-IO

Taking the discussion back from here. I'm generating this gtlf with blender+exporter and some of the branches of the generated tree cannot be displayed in babylon.js.

They pointed out that some of the vertices are being exported with wights all in 0 that is not compliant with GLTF standard.

Is this correct? Should I do something in modelling time to avoid this issue?

thanks!

Skinning_&_Rigging bug exporter

Most helpful comment

AFAICT, verts that aren't assigned groups in Blender stay in the same place they would be if they weren't skinned?

To do this in glTF we would need to export as if there were a new bone with the identity transform relative to the arma that all those verts were assigned to. Inserting a new bone in every arma would obviously hurt round-tripping though. I guess we could try to do it only when there are unassigned verts (propagating that information to the right places would be a pain...).

it's not exactly a satisfying fix, but in practice using 1, 0, 0, 0 when the weights would otherwise be zero has avoided these issues in threejs.

I think we should merge this as a stopgap, like, now. Obviously (*looks at filing date*) a real fix for this bug is not forthcoming. This is what everyone appears to be doing anyway, it has a non-zero chance of working correctly, and we might as well export a wrong-looking but valid file instead of a wrong-looking _and_ invalid file.

Patch is:

diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
index c605a60..12c9060 100644
--- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
+++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
@@ -286,6 +286,7 @@ def extract_primitives(glTF, blender_mesh, library, blender_object, blender_vert
                         bones.append((joint, weight))
                 bones.sort(key=lambda x: x[1], reverse=True)
                 bones = tuple(bones)
+                if not bones: bones = ((0, 1.0),)  # HACK for verts with zero weight
                 vert += (bones,)

             for shape_key in shape_keys:

All 15 comments

It's this model, yes? Would you be able to share the original .blend file as well? You can drag .ZIP files into GitHub comments.

Tree.zip
It seems to be related with the animations associated with the tree. As a workaround, we are assigning a low weight paint to the whole tree.

Transferring this to the new importer/exporter, where the issue still appears reproducible.

Is this still being worked on? I have a .blend file which I am trying to export from Blender as GLB and import into a game engine but our custom gltf importer chokes on the zero weights. I don't know whether to modify our importer to accept the zero-weight files if they're not actually standard compliant files to start with.

(https://gltf-viewer.donmccurdy.com — thanks Mr. McCurdy, great website!— currently does display things ok despite the zero-weight vertices, I don't know if that means Mr. McCurdy's viewer is just tolerant of standard-breaking files)

@matiasbargas
Some 0 weights are exported, because some vertices are not assigned to any vertex groups.
See screenshots when moving the root bone ("Bone") : some vertices are not moved
image
--> So export does export 0. This is allowed in Blender, not in glTF.

@mcclure : Can you please share your blend file? Want to check what happen.

Hmm. On one hand, if engines are likely to be unhappy with zero-weight vertices, it seems like glTF is probably doing the right thing by disallowing that. On the other hand, if Blender _does_ allow zero-weight vertices, it's not clear what this exporter should do when it finds them. Assign the vertex to an arbitrary bone? Add a new bone? Drop the vertex? Crash? 😣

@mcclure my website uses threejs and tries to stick to its default configuration for the most part. It does normalize skin weights after loading. While the glTF spec tries to say "please don't do that" that's the exporter's responsibility, un-normalized weights seem to be pretty common with models coming out of DCC tools regardless of format. See: https://github.com/mrdoob/three.js/blob/8685a33e011f014eca88de8d49e1bc0efa845f4a/src/objects/SkinnedMesh.js#L60-L89.

@julienduroure it's not exactly a satisfying fix, but in practice using 1, 0, 0, 0 when the weights would otherwise be zero has avoided these issues in threejs.

We've been meaning to get this case into the official validation suite (https://github.com/KhronosGroup/glTF-Validator), but haven't yet: https://github.com/KhronosGroup/glTF-Validator/issues/58.

@julienduroure "Can you please share your blend file? Want to check what happen"
I have just now sent you the blend file via email (as we discussed in https://developer.blender.org/T69673) .

Your model displays fine in https://gltf-viewer.donmccurdy.com/

He you want to be sure to not have 0 weights, move your controller_world bone, and check all parts that not moved. Then assign all these vertices to controller_world vertex group

@julienduroure Thanks— as explained above I am aware the model works right in the donmccurdy.com viewer, and Mr. McCurdy above says that his viewer normalizes weights (although this is not what the GLTF spec says to do). So to be totally clear I see short term I can get around my problem by either modifying the .blend or normalizing weights in my importer, but Blender is exporting noncompliant GLTFs and so long term there is a bug there…

so long term there _is_ a bug there…

Don't worry, we agreed on that. I was only explain the root cause, and how to workaround, waiting a fix is pushed. This ticket is still open, bug remains, and still need to be fixed.

Blender allows something that is forbidden in glTF specification, so we have to found how to manage it, as explained by Don. Not sure yet what is the best solution

@julienduroure, you were correct, moving the meshes under the controller_world bone as you recommended fixed my file.

Also, just in case this is useful to anyone who finds this bug on Google: I have created a script that normalizes weights in GLTF files. You can find it in this repo https://github.com/mcclure/gltf-edit as "normalize.py". In my testing, running one of the incorrect "zero weight" blender GLBs through this script made it usable by my engine.

AFAICT, verts that aren't assigned groups in Blender stay in the same place they would be if they weren't skinned?

To do this in glTF we would need to export as if there were a new bone with the identity transform relative to the arma that all those verts were assigned to. Inserting a new bone in every arma would obviously hurt round-tripping though. I guess we could try to do it only when there are unassigned verts (propagating that information to the right places would be a pain...).

it's not exactly a satisfying fix, but in practice using 1, 0, 0, 0 when the weights would otherwise be zero has avoided these issues in threejs.

I think we should merge this as a stopgap, like, now. Obviously (*looks at filing date*) a real fix for this bug is not forthcoming. This is what everyone appears to be doing anyway, it has a non-zero chance of working correctly, and we might as well export a wrong-looking but valid file instead of a wrong-looking _and_ invalid file.

Patch is:

diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
index c605a60..12c9060 100644
--- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
+++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
@@ -286,6 +286,7 @@ def extract_primitives(glTF, blender_mesh, library, blender_object, blender_vert
                         bones.append((joint, weight))
                 bones.sort(key=lambda x: x[1], reverse=True)
                 bones = tuple(bones)
+                if not bones: bones = ((0, 1.0),)  # HACK for verts with zero weight
                 vert += (bones,)

             for shape_key in shape_keys:

I think we should merge this as a stopgap, like, now. Obviously (looks at filing date) a real fix for this bug is not forthcoming

I'm OK with this, if we include a comment and a link to this issue for future reference.

Okay, I PRed the stopgap for 2.90. I also opened #1151 to talk about the real fix.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Quinten123 picture Quinten123  Â·  4Comments

cstfan picture cstfan  Â·  4Comments

julienduroure picture julienduroure  Â·  3Comments

spiraloid picture spiraloid  Â·  5Comments

KannebTo picture KannebTo  Â·  3Comments