KhronosGroup / glTF-Blender-IO

Blender glTF 2.0 importer and exporter
https://docs.blender.org/manual/en/latest/addons/import_export/scene_gltf2.html
Apache License 2.0
1.5k stars 319 forks source link

Very slow export to GLB for files with animations #1913

Closed uguu-org closed 6 months ago

uguu-org commented 1 year ago

Describe the bug

Blender appears to take extraordinary amount of time when exporting files containing animations, particularly for files imported from VRM 1.0.

To Reproduce

  1. Extract imported_from_vrm_1_0_6actions.blend from vrm1_0.zip.

  2. Create export_glb.py with these lines:

import bpy, sys
argv = sys.argv[sys.argv.index('--') + 1:]
bpy.ops.wm.open_mainfile(filepath=argv[0])
bpy.ops.export_scene.gltf(filepath=argv[1],
                          export_animations=True,
                          export_optimize_animation_size=True)
  1. Run blender to export:
blender --background --python export_glb.py -- \
  imported_from_vrm_1_0_6actions.blend output.glb
  1. Observe that it took several minutes.

This is a reduced test case of what I was doing. My original file had 51 animations and it took 4 hours for the export to complete, during which blender UI was frozen.

Expected behavior

Export should complete within minutes.

.blend file/ .gltf

ZIP with offending model: vrm1_0.zip

ZIP with a model that's pretty much identical, except it was VRM 0.0 as opposed to 1.0. This one exports to GLB much faster. vrm0_0.zip

Version

Additional context

What prompted me to file this bug was the 4 hour export time for a VRM 1.0 model, compared to just a few minutes for VRM 0.0. Summary:

VRM actions time
0.0 1 1.296602725982666 s
0.0 2 2.23384428024292 s
0.0 3 2.827441453933716 s
0.0 4 4.389584302902222 s
0.0 5 18.44874882698059 s
0.0 6 35.11666750907898 s
1.0 1 6.029803991317749 s
1.0 2 21.260582208633423 s
1.0 3 28.7117862701416 s
1.0 4 56.7209210395813 s
1.0 5 417.5515892505646 s
1.0 6 781.1363813877106 s

Details: results.txt

One relevant difference between VRM 0.0 and 1.0 might be due to the divided vertex buffers, according to this page: https://vrm.dev/en/vrm1/changed.html#gltf-divided-vertex-buffer

I found an existing issue that might be related, but it's closed: https://github.com/KhronosGroup/glTF-Blender-IO/issues/1078

TBAndrade commented 1 year ago

Experiencing a very similar issue, where exporting a GLB with 3 simple animations causes the UI to freeze for 4 to 5 minutes during the export process. This is quite disruptive, as even transferring the files to a clean scene for exporting doesn't resolve the issue.

julienduroure commented 1 year ago

Hello,

Export animation needs to bake animation, and this require to go frame by frame for each if your animation.

There are some way to avoid this on user side (for example baking animation, and export glTF without baking), and a few things to investigate on code side to try have better result.

On your file => VRM 1.0 is much bigger the 0.0. Trying to playbast 1.0 don't success to get it at 30 fps, where 0.0 does. This explains why the 1.0 is longer.

Give me a few time to write a complete document about it.

bigrig2212 commented 1 year ago

Me too. I've got 20min exports - three computers running these exports now to save time - fans blasting on full - feel like i'm bitcoin mining to get this done.

SolarLune commented 1 year ago

Hello, Export animation needs to bake animation, and this require to go frame by frame for each if your animation. There are some way to avoid this on user side (for example baking animation, and export glTF without baking), and a few things to investigate on code side to try have better result.

Hello, I'm also running into this issue with exports taking a long time. I have four very simple, low-poly humanoid characters in a single blend file that I'm exporting. The characters are under 300 triangles each, and exporting a GLTF file with them takes upwards of four seconds because of the animations (which are also very simple). Their armatures are comprised of 12 bones.

You mentioned exporting the GLTF without baking the animations - is that possible for me to specify when exporting my scene?

julienduroure commented 1 year ago

Hello,

Some refactoring should happen in 2023 semester 2, that will enhance export times. Some preliminary tests (really hacky, not ready to be merged at all):

JamesLedger commented 1 year ago

Great to see that this is being worked on - I've encountered the same thing since upgrading from 3.1. I believe a key factor in this issue is having NLA animations in the file - the initial vrm1_0 example files have all animation as NLA.

Specifically I tried exporting something with just actions in Blender 4.0 and it took ~6 seconds, converting them to NLA took the export time to around ~130 seconds. I've got more stats on my work PC, will drop them in here tomorrow.

cleverfrog commented 1 year ago

Export animation needs to bake animation, and this require to go frame by frame for each if your animation.

There are some way to avoid this on user side (for example baking animation, and export glTF without baking), and a few things to investigate on code side to try have better result.

I'm a bit confused here....

Why does the animation need to be baked upon export frame by frame?

Shouldn't the only animation information being exported be the keyframes?

cleverfrog commented 1 year ago

As a possible clue:

What is making the difference for me between a few seconds and a much longer export seems to be the 'include all actions ' on the armatures' option in the export settings.

However I deleted all other armatures from the scene.... so I'm wondering if the culprit could be some lingering homeless armatures/tracks?

julienduroure commented 1 year ago

@cleverfrog There is lot of cases where you can't "simply" get the keyframes and use them as animation in glTF animation:

Using "include all actions" will try to export all armature actions for you single armature. Even if not assigned to your armature (active action or in NLA). You have multiple ways to avoid that (not using "include all actions", using "Active action mode"). A new way should come in Blender 4.1 where you will be able to filter action you want to export.

KnightNine commented 10 months ago

I have all my characters and animations in a singular blender file because I want to retarget animations across multiple characters and I wrote some code in my game engine that breaks up all the meshes and armatures into separate files to be compiled later. I disabled "include all actions" and it's still taking around 5 minutes to export.

Hello,

Some refactoring should happen in 2023 semester 2, that will enhance export times. Some preliminary tests (really hacky, not ready to be merged at all):

  • Blender 3.6 export time : 341s
  • Current test export time: around 25s

I have tried blender 3.6.8 but saw no improvement, 4.0.2 had a bit of an improvement (I think, I didn't measure it), has this enhancement been implemented in some capacity? If so which versions?

julienduroure commented 10 months ago

Hello, This enhancement is not fully implemented yet (as you can see, the ticket is still open). To be 100% compatible, we still need some changes on Blender API side: Either:

Seems there is still no known deadline for these 2 subjects, so maybe I should enable enhancement when it's possible, with fallback on current code when there are drivers on SK / armature

vaner-org commented 10 months ago

@julienduroure Are there any plans to make the frame-by-frame baking multi-threaded? So multiple actions can be baked in parallel? Sorry if this question has been answered elsewhere.

julienduroure commented 10 months ago

I am not sure Blender api bpy is thread safe. I will have a deeper look

vaner-org commented 10 months ago

I am not sure Blender api bpy is thread safe. I will have a deeper look

Thank you. GLTF export for my game character in very early stages takes close to five minutes each time, so multithreading, or even the enhancement you mentioned a few days ago would make things tremendously easier for me.

julienduroure commented 7 months ago

One of the 2 solutions (copy drivers) seems to be ok on Blender side now. See https://projects.blender.org/blender/blender/issues/111276#issuecomment-1166644

KnightNine commented 6 months ago

One of the 2 solutions (copy drivers) seems to be ok on Blender side now. See https://projects.blender.org/blender/blender/issues/111276#issuecomment-1166644

Would you mind walking me through how to implement this solution into my copy of blender? (if it's not already implemented.) I'm pretty lost on how this will help me with export times.

julienduroure commented 6 months ago

This option is now implemented. You have a new option in Animation > Optimization panel to disable other object when baking This option can now manage drivers on SK too