mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
100.8k stars 35.22k forks source link

gltf export produces validator with errors #27510

Closed prominentdetail closed 6 months ago

prominentdetail commented 6 months ago

Description

I am import/exporting a gltf from the official three.js editor. https://threejs.org/editor/ Then I run the file in the gltf validator and get errors: https://github.khronos.org/glTF-Validator/ I'm not sure what the errors mean, and how to get it fixed.

Reproduction steps

  1. download the gltf model provided
  2. import into editor
  3. export and run the test

Code

characterVid.zip

Live example

Use the editor.

Screenshots

No response

Version

latest

Device

Desktop

Browser

Chrome

OS

Windows

GitHubDragonFly commented 6 months ago

@prominentdetail you could use my GLTF Viewer to load your model and then export it to GLB by selecting GLB_m option. The attached file below is what you should expect to get exported.

characterVid_GLB_MESHOPT (from Chrome).zip

characterVid_GLB_MESHOPT (from Firefox).zip

The export process is using functions from gltf-transform to optimize and compress the model and if you open browser console before you run the export then you will see these messages:

prune: Removed types... Accessor (46) prune: Removed types... Skin (5), Accessor (22)

prominentdetail commented 6 months ago

@GitHubDragonFly I tried exporting from your viewer, but the glb file it creates can't be opened.

GitHubDragonFly commented 6 months ago

The exported file will be zipped so I will assume that you have extracted the GLB file.

What application are you using to open this GLB file?

I just tried loading it into three.js editor and it opened it fine, see the attached picture.

Editor Screenshot

If you are using some custom application then you will also have to include the following import:

    <script src="https://cdn.jsdelivr.net/npm/meshoptimizer/meshopt_decoder.js" defer></script>

and then tell your GLTF Loader to use it with: gltf_loader.setMeshoptDecoder( MeshoptDecoder ).

You can see the whole code of my GLTF Viewer here.

prominentdetail commented 6 months ago

I tried opening it with Windows 3d viewer, and also Godot, but it didn't work.

GitHubDragonFly commented 6 months ago

Windows 3D Viewer doesn't appear to have been updated in a long time to be able to handle current models. I cannot be smart and tell you anything about Godot.

Mugen87 commented 6 months ago

When checking the exported glTF asset, the following validation error is reported multiple times:

ACCESSOR_ANIMATION_INPUT_NON_INCREASING

I think we should focus in this issue on why these errors appear and how the exporter can be updated to avoid them.

GitHubDragonFly commented 6 months ago

@Mugen87 you would be correct.

What I offered is just a quick and easy alternative.

prominentdetail commented 6 months ago

The main issue I seem to be having when exporting from three.js is that the skinned mesh is not a root (should it be? because I need it a child of other nodes). And this seems to cause issues when I try to import into Godot, where the animation of those meshes don't work. The skeleton bones do, but not the transforms on the skinned mesh.. I'm not sure how to fix this.

prominentdetail commented 6 months ago

Here's a simpler example file: animationtestgodot2.zip

How it looks in windows 3d viewer: spinviewer

but in Godot, it doesn't animate corrrectly: spingodot

In the gltf-validator it shows this: "messages": [ { "code": "ANIMATION_CHANNEL_TARGET_NODE_SKIN", "message": "Animated TRS properties will not affect a skinned mesh.", "severity": 1, "pointer": "/animations/0/channels/2/target/path" }, { "code": "NODE_SKINNED_MESH_NON_ROOT", "message": "Node with a skinned mesh is not root. Parent transforms will not affect a skinned mesh.", "severity": 1, "pointer": "/nodes/1" }, { "code": "NODE_SKINNED_MESH_LOCAL_TRANSFORMS", "message": "Local transforms will not affect a skinned mesh.", "severity": 1, "pointer": "/nodes/1" } ],

I'm not sure how to get it to work. It sounds like the skinned mesh is not a root- but it shouldn't be, right? Because I need it nested inside other objects.

GitHubDragonFly commented 6 months ago

@prominentdetail just as a test, in the meantime, try the attached files in Godot.

Windows 3D Viewer can show them at least.

animationtestgodot2_GLBrq.zip characterVid_GLBrq.zip

prominentdetail commented 6 months ago

@GitHubDragonFly , those still have same issue of not animating correctly in Godot.

prominentdetail commented 6 months ago

I think I managed to fix it. I had to place the skinned meshes into other objects and animate those objects instead of the skinned mesh. It seems to import fine in godot now. I'm still going to try and learn more about this though.

Edit: I also had to make the root bone a child of the parent object (not the skinnedmesh).

WestLangley commented 6 months ago

@Mugen87 The OPs original asset generates 40 errors when imported into https://gltf-viewer.donmccurdy.com.

prominentdetail commented 6 months ago

I still get the same errors in the validator. Maybe the gltfexporter is doing something weird, but I'm not sure. Like the skinnedmesh object isn't being placed as root.. I'm not sure. Maybe something to do with the nodemap?

GitHubDragonFly commented 6 months ago

@prominentdetail see if any of these 2 files might work for you, they do pass in validator even though they contain NON-ROOT messages and they also work in the Windows 3D Viewer.

Your original model file was used and:

characterVid.zip

GitHubDragonFly commented 6 months ago

@prominentdetail it seems to me like your models need fixing and not really GLTF Exporter. This is just my opinion.

My experience with Blender is rather basic but I have given it a go with your first model and changed some parents of the objects. The GLTF / GLB files in the attached zip pass validation and show no errors or warnings. If you can test them as they are in Godot and they are working then the only thing that would need fixing is the animation, since it is not the same any longer and has turned into a rather rudimentary animation.

characterVid.zip

I will not be looking to make any further posts in this topic since it's kind of beyond my knowledge.

Mugen87 commented 6 months ago

The OPs original asset generates 40 errors when imported into https://gltf-viewer.donmccurdy.com/.

Yes, and it seems all of them are ACCESSOR_ANIMATION_INPUT_NON_INCREASING ones. I'm not sure yet what this error means.

prominentdetail commented 6 months ago

@GitHubDragonFly , Thanks- I already have managed to solve my Godot importing issue. I was binding the root bone to the skinnedmesh, and also applying animation transforms to the skinnedmesh. Even though it worked fine in Windows 3d Viewer and Blender, Godot didn't like it. I had to create an empty object and apply the animation transforms to that and make the rootbone and skinnedmessh a child of that.. Actually, now that I think of it, I just went back and made the skinnedmeshes children of the scene, and this fixed the "NODE_SKINNED_MESH_NON_ROOT" error. Everything still imports and loads into other programs just fine it seems. So it looks like the gltf validator expects skinnedmeshes to always be attached to the scene. @Mugen87 , I still get the "ACCESSOR_ANIMATION_INPUT_NON_INCREASING" ..These are the only errors I get now, but I have no idea what it means yet either. I'm going to try and do some testing with a simpler animation to see what triggers it hopefully.

prominentdetail commented 6 months ago

@Mugen87 , ok, so I figured out what the "ACCESSOR_ANIMATION_INPUT_NON_INCREASING" error means. It means there was a Time value in an animationclip that is equal or less than the previous time value.. Due to how I am processing the data, it creates some input with the same time value. I guess it expects the time to always be increasing for each value, which makes sense. I'll have to figure out exactly how I am processing the data so I can determine which value I actually want to use when there are duplicates. So I think this is just my own logic problem and nothing wrong with the gltfexporter.

Mugen87 commented 6 months ago

@prominentdetail Thanks for the additional information!

We can fix the issue in the editor by calling AnimationClip.optimize() for all animation clips right before the export.

I just wonder if we should fix the issue in the editor (Menubar.File.js is a good place for that) or if we apply a patch directly to GLTFExporter 🤔 .

The following zipped glb file was exported from the editor with the mentioned fix in place. All validation errors are now gone.

characterVid.glb.zip

prominentdetail commented 6 months ago

Are there any cases where you wouldn't want to optimize it?

donmccurdy commented 6 months ago

I am a little nervous about optimizing the keyframe tracks in GLTFExporter. The user might have placed keyframes at particular times intentionally, or want all tracks to have the same keyframe times, even if some are redundant... perhaps it would be safer to do this in the Editor, instead?

Mugen87 commented 6 months ago

I'm okay with doing this in the editor for now.

I suggested to fix this in the exporter since it sounds weird to me when GLTFExporter produces outputs that throw glTF validation errors.