godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
88.88k stars 20.15k forks source link

Odd behavior in meshes with blendshapes when importing #54719

Open ModularNucleus opened 2 years ago

ModularNucleus commented 2 years ago

Godot version

v4.0.dev.calinou [bd31af37b]

System information

Windows 10, GLES3.0, Nvidia GTX 1060 6GB, Nvidia studio driver 471.68

Issue description

When importing a glb file, it seems that meshes with blendshapes are not saved as mesh resources, unless the materials are also extracted. Notice in the video that the "test_character6_body" mesh is not imported/saved in the first attempt. Only when importing a second time with extracted materials does the mesh resource show up in the file dock as a saved mesh resource. While extracting the materials allows the mesh with blendshapes to be saved, the resulting project crashes godot.

https://user-images.githubusercontent.com/91982860/140647699-3133f929-a1dd-47ef-a203-6a3662789ada.mp4

Steps to reproduce

  1. Open the MRP
  2. Import the GLB with the advanced importer and save the resources - but without extracting materials
  3. Observe that the mesh with blendshapes, "test_character6_body" is not saved
  4. Reimport the GLB with the advanced importer and this time extracte the materials
  5. Observe that the mesh with blendshapes, "test_character6_body" is now saved
  6. Godot crashes

Minimal reproduction project

Godot Nightly Blendshapes Import Test pre-import.zip

KoBeWi commented 2 years ago

Seems still valid in alpha 9, except the crash part.

MJacred commented 2 years ago

Still valid in alpha 13 (no crashing)

Furthermore, I got the following errors while following along the steps in the video

  modules/gltf/register_types.cpp:92 - FBX file import is enabled, but no FBX2glTF path is configured. FBX files will not be imported.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:702 - Condition "!mesh" is true.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:683 - Condition "!mesh" is true.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:213 - Condition "!mesh" is true.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:217 - deleting mesh with active instances
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:702 - Condition "!mesh" is true.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:683 - Condition "!mesh" is true.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:213 - Condition "!mesh" is true.
  drivers/vulkan/rendering_device_vulkan.cpp:8744 - Attempted to free invalid ID: 447028786102348
  drivers/vulkan/rendering_device_vulkan.cpp:8744 - Attempted to free invalid ID: 447101800546385
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:217 - deleting mesh with active instances
  Transient parent has another exclusive child.
  Can't unwrap mesh with blend shapes.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:702 - Condition "!mesh" is true.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:683 - Condition "!mesh" is true.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:213 - Condition "!mesh" is true.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:217 - deleting mesh with active instances
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:702 - Condition "!mesh" is true.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:683 - Condition "!mesh" is true.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:213 - Condition "!mesh" is true.
  drivers/vulkan/rendering_device_vulkan.cpp:8744 - Attempted to free invalid ID: 502141806444618
  drivers/vulkan/rendering_device_vulkan.cpp:8744 - Attempted to free invalid ID: 502189051084852
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:217 - deleting mesh with active instances
  Transient parent has another exclusive child.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:702 - Condition "!mesh" is true.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:683 - Condition "!mesh" is true.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:213 - Condition "!mesh" is true.
  drivers/vulkan/rendering_device_vulkan.cpp:8744 - Attempted to free invalid ID: 518140559622216
  drivers/vulkan/rendering_device_vulkan.cpp:8744 - Attempted to free invalid ID: 518144854589526
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:217 - deleting mesh with active instances

After deleting (via Godot's FileSystem) all files except the environment, icon and *.glb file (ie. resetting to before test start), then going back to Godot project list and going back into project and trying to repeat the process, I get these errors

  modules/gltf/register_types.cpp:92 - FBX file import is enabled, but no FBX2glTF path is configured. FBX files will not be imported.
  Cannot open file 'res://Hair_Middle.tres'.
  Failed loading resource: res://Hair_Middle.tres. Make sure resources have been imported by opening the project in the editor at least once.
  Cannot open file 'res://Hair_Middle.tres'.
  Failed loading resource: res://Hair_Middle.tres. Make sure resources have been imported by opening the project in the editor at least once.
  Cannot open file 'res://Weapon.tres'.
  Failed loading resource: res://Weapon.tres. Make sure resources have been imported by opening the project in the editor at least once.
  Cannot open file 'res://body.tres'.
  Failed loading resource: res://body.tres. Make sure resources have been imported by opening the project in the editor at least once.
  Cannot open file 'res://shoes.tres'.
  Failed loading resource: res://shoes.tres. Make sure resources have been imported by opening the project in the editor at least once.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:702 - Condition "!mesh" is true.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:683 - Condition "!mesh" is true.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:213 - Condition "!mesh" is true.
  servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:217 - deleting mesh with active instances

In the second try, setting the Save Paths was not possible -> they had the state "already saving". And the materials cannot be extracted, because they already were (well, the import-file thinks that). Therefore, re-importing is not possible anymore.

I deleted test_character6.glb.import file (and test_character6.glb.unwrap_cache), then I could re-import it again.

System

lyuma commented 1 year ago

I'm still a bit confused how blendshapes and meshes / materials are related.

I think we should forbid extracting meshes unless either materials are extracted, or textures are extracted, or both, but I want to understand a bit more why this is happening.

I can't find the issue (it's possible it wasn't filed as an issue yet), but I had a suspicion there's another major issue here in which the extract materials is extracting the uncompressed temporary textures used in the advanced import dialog. So that's also a related issue to look into.

the extract workflows still have some bugs right now.

There's another interesting issue here by the way. Reimporting a mesh with blendshapes is visible in the scene seems to cause some strange errors.

ERROR: Attempted to free invalid ID: 657602442690676
   at: RenderingDeviceVulkan::_free_internal (drivers\vulkan\rendering_device_vulkan.cpp:8394)
ERROR: Attempted to free invalid ID: 657619622559808
   at: RenderingDeviceVulkan::_free_internal (drivers\vulkan\rendering_device_vulkan.cpp:8394)
ERROR: Attempted to free invalid ID: 749308584394890
   at: RenderingDeviceVulkan::_free_internal (drivers\vulkan\rendering_device_vulkan.cpp:8394)
ERROR: Attempted to free invalid ID: 749317174329491
   at: RenderingDeviceVulkan::_free_internal (drivers\vulkan\rendering_device_vulkan.cpp:8394)
ERROR: Storage buffer supplied (binding: 2) is invalid.
   at: (drivers\vulkan\rendering_device_vulkan.cpp:5706)
ERROR: Storage buffer supplied (binding: 2) is invalid.
   at: (drivers\vulkan\rendering_device_vulkan.cpp:5706)
ERROR: Index p_shape = 0 is out of bounds ((int)mi->blend_weights.size() = 0).
   at: RendererRD::MeshStorage::mesh_instance_set_blend_shape_weight (servers\rendering\renderer_rd\storage_rd\mesh_storage.cpp:840)
ERROR: Index p_shape = 1 is out of bounds ((int)mi->blend_weights.size() = 0).
   at: RendererRD::MeshStorage::mesh_instance_set_blend_shape_weight (servers\rendering\renderer_rd\storage_rd\mesh_storage.cpp:840)
ERROR: Index p_shape = 2 is out of bounds ((int)mi->blend_weights.size() = 0).
   at: RendererRD::MeshStorage::mesh_instance_set_blend_shape_weight (servers\rendering\renderer_rd\storage_rd\mesh_storage.cpp:840)
ERROR: Attempt to disconnect a nonexistent connection from 'Skeleton3D:<Skeleton3D#3743198276766>'. Signal: 'bone_pose_changed', callable: 'BoneAttachment3D::on_bone_pose_update'.
   at: (core\object\object.cpp:1327)
ERROR: Attempt to disconnect a nonexistent connection from 'Skeleton3D:<Skeleton3D#3743198276766>'. Signal: 'bone_pose_changed', callable: 'BoneAttachment3D::on_bone_pose_update'.
   at: (core\object\object.cpp:1327)
ERROR: Signal 'bone_pose_changed' is already connected to given callable 'BoneAttachment3D::on_bone_pose_update' in that object.
   at: (core\object\object.cpp:1270)
ERROR: Signal 'bone_pose_changed' is already connected to given callable 'BoneAttachment3D::on_bone_pose_update' in that object.
   at: (core\object\object.cpp:1270)
ERROR: Attempted to free invalid ID: 653066957226008
   at: RenderingDeviceVulkan::_free_internal (drivers\vulkan\rendering_device_vulkan.cpp:8394)
ERROR: Can't unwrap mesh with blend shapes.
   at: (scene\resources\importer_mesh.cpp:1105)
ERROR: Attempted to free invalid ID: 815412426047546
   at: RenderingDeviceVulkan::_free_internal (drivers\vulkan\rendering_device_vulkan.cpp:8394)
ERROR: Attempted to free invalid ID: 815425310949429
   at: RenderingDeviceVulkan::_free_internal (drivers\vulkan\rendering_device_vulkan.cpp:8394)
ERROR: Storage buffer supplied (binding: 2) is invalid.
   at: (drivers\vulkan\rendering_device_vulkan.cpp:5706)
ERROR: Index p_shape = 0 is out of bounds ((int)mi->blend_weights.size() = 0).
   at: RendererRD::MeshStorage::mesh_instance_set_blend_shape_weight (servers\rendering\renderer_rd\storage_rd\mesh_storage.cpp:840)
ERROR: Index p_shape = 1 is out of bounds ((int)mi->blend_weights.size() = 0).
   at: RendererRD::MeshStorage::mesh_instance_set_blend_shape_weight (servers\rendering\renderer_rd\storage_rd\mesh_storage.cpp:840)
ERROR: Index p_shape = 2 is out of bounds ((int)mi->blend_weights.size() = 0).
   at: RendererRD::MeshStorage::mesh_instance_set_blend_shape_weight (servers\rendering\renderer_rd\storage_rd\mesh_storage.cpp:840)

I will say I haven't run into the crash yet. I might not have played with this project enough, or perhaps the crash got fixed. I'll have to test more. The errors are strange.

ModularNucleus commented 1 year ago

In RC5 I cannot quite reproduce the original issue (mesh not saving without etracting materials) nor the original crash. The mesh with blendshapes, "test_character6_body" does get extracted and saved as a mesh resource (visible in the file system)

However, as lyuma notes, there is still some odd behaviour:

If I create a new inherited scene from the .glb, then - with the inheriting scene open - attempt to reimport the .glb, it will leave Godot hanging at the "saving" pop-up.

https://user-images.githubusercontent.com/91982860/221651386-2f869683-a927-46b0-87bf-316bf8e98d2c.mp4

If I delete the imported resources along with the .import file - or, alternatively move the .glb file into a new project - (that is, start over with the import process), and then import the file and extract the mesh resources, I cannot right click on the .glb and create an inherited scene. If I reimport, then I can right click and create an inherited scene - but this leaves Godot hanging.

https://user-images.githubusercontent.com/91982860/221652647-0f775798-9044-4724-a15f-892193ebef15.mp4

Perhaps related to #74059

lyuma commented 1 year ago

The blend weights issue seems to be related to how the MeshInstance3D::_mesh_changed callback is handled in response to the changed signal fired from emit_changed in the ArrayMesh class, such as add_surface

The error is emitted by mesh_instance_set_blend_shape_weight in MeshStorage, itself called by instance_set_blend_shape_weight in RendererSceneCull.

It seems that somehow, even though the Mesh resource has informed RenderingServer about the blend shapes and the surfaces, the blend_weights array has somehow not been resized to the correct size, or something is happening in the wrong order.

Ultimately, the blend weights error seems like logspam and probably a red herring. In my case, I worked around the logspam by creating a new Mesh and switching the mesh instances to point to the new Mesh after it was fully created (that way nobody was connected to the changed signal), rather than editing it on the fly.

Anyway not sure if this offers much insight into the actual issue, but since my research took me this far I thought I'd report back.