As reported in https://github.com/KhronosGroup/glTF-Blender-IO/issues/856, the model below appears rotated by 90º around the X axis in three.js, when any of the included animations are played. In several other viewers (BabylonJS, glTF-Sample-Viewer, Blender), the model appears upright.
^The second link also contains a second version of the model, game_man_packed.glb
. The only difference is that the second has been optimized by gltfpack — and for some reason it then renders correctly. 🤔
| expected | three.js |
|----|---|
| |
|
The glTF validator reports several possible issues with this model (joint weights should be normalized, and so on) but nothing that looked like an obvious cause to me.
For a quick way to preview the problem, drag the model into https://threejs.org/editor/ or https://gltf-viewer.donmccurdy.com/, then play the Idle animation (or any animation with an obvious upright pose). In my viewer, the model itself is accessible as content
from the JS console.
It's resting... 🤡
The only difference is that the second has been optimized by gltfpack — and for some reason it then renders correctly. 🤔
I've tried to compare both glb
files today but noticed that the asset data are extensively change by gltfpack
. Meaning geometry, transformation and even the animation data are different. That makes it really hard to compare both assets. Although they represent the same character, they are totally different from a technical point of view.
The other github issue in context of glTF-Blender-IO
mentions a rotation of the root bone by 90° around the x axis. Indeed, removing this transformation makes the animation look correct. There must be a place in the three.js
code base where this transformation is not honored correctly.
^That 90º rotation sounds like the right place to look, yes. The glTF skinning spec mentions that:
Client implementations should apply only the transform of the skeleton root [joint] node to the skinned mesh while ignoring the transform of the skinned mesh node.
As far as I can tell we're doing that – moving the SkinnedMesh has no effect (except to trigger frustum culling at some point) and moving the root bone does. Why it's 90º off, I'm still not sure.
It seems it works if the bone root
is renamed to something different. Can someone please verify^^? This is my updated glb
exported from Blender 2.81a: game_man_sketchbookb1.glb.zip
Notice that root
has a special semantics in the three.js
animation system. I've not debugged this in detail so far but I guess there is a side effect.
Wow... that's... yeah. Confirmed, renaming the node (I edited the original .glb
by hand) fixes the issue.
(╯°□°)╯︵ ┻━┻
Either we need to escape this name in PropertyBinding.sanitizeNodeName, or remove the special case entirely. I think I'd vote for the latter.
Thanks for finding that! Had not occurred to me at all.
"root" name issue has been discussed here, too https://github.com/mrdoob/three.js/issues/16693
We should finally fix this issue for the next release. I think I still favor an enhancing of PropertyBinding.sanitizeNodeName()
.
Most helpful comment
Wow... that's... yeah. Confirmed, renaming the node (I edited the original
.glb
by hand) fixes the issue.(╯°□°)╯︵ ┻━┻
Either we need to escape this name in PropertyBinding.sanitizeNodeName, or remove the special case entirely. I think I'd vote for the latter.
Thanks for finding that! Had not occurred to me at all.