Setup:
So I have a script running that exports thousands of models from Blender to a .gltf file(s). These models are big, about 200MB each, and the goal is to export about 6,000 of them. What my script does is select the objects in the Blender file scene, then export them with this function:
for obj in bpy.data.collections[some_collection].all_objects:
obj.select_set(True)
bpy.ops.export_scene.gltf(
filepath=f"{Save_Path_To_Model_File}.gltf",
check_existing=True,
export_format='GLTF_SEPARATE',
use_selection=True)
Materials are also selected in a similar way and are unique for each export:
for obj in bpy.data.collections[some_collection].all_objects:
selected_object = bpy.data.objects.get(obj.name)
selected_object.active_material = bpy.data.materials[some_material]
The issue:
After this code runs for about 17 loops, exporting 17 models, Blender crashes and an error message appears saying that Blender has run out of VRAM: RuntimeError: Error: System is out of GPU and shared host memory
Most of the time Blender just shuts down and doesn't display this message in the System Console when it reboots so I haven't been able to get the full message. But I'll edit it in this post if I manage to get it.
Traceback from the .crash.txt file when exporting .gltf files:
RuntimeError: Error: Python: Traceback (most recent call last):
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\__init__.py", line 628, in execute
return gltf2_blender_export.save(context, export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_export.py", line 35, in save
json, buffer = __export(export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_export.py", line 52, in __export
__gather_gltf(exporter, export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_export.py", line 66, in __gather_gltf
active_scene_idx, scenes, animations = gltf2_blender_gather.gather_gltf2(export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather.py", line 30, in gather_gltf2
scenes.append(__gather_scene(blender_scene, export_settings))
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_cache.py", line 38, in wrapper_cached
result = func(*args, **kwargs)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather.py", line 67, in __gather_scene
node = gltf2_blender_gather_nodes.gather_node(
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_nodes.py", line 31, in gather_node
children=__gather_children(vnode, blender_object, export_settings),
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_nodes.py", line 109, in __gather_children
child_node = gather_node(vtree.nodes[child], export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_nodes.py", line 31, in gather_node
children=__gather_children(vnode, blender_object, export_settings),
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_nodes.py", line 73, in __gather_children
node = gather_node(c, export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_nodes.py", line 31, in gather_node
children=__gather_children(vnode, blender_object, export_settings),
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_nodes.py", line 73, in __gather_children
node = gather_node(c, export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_nodes.py", line 35, in gather_node
mesh=__gather_mesh(vnode, blender_object, export_settings),
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_nodes.py", line 246, in __gather_mesh
result = gltf2_blender_gather_mesh.gather_mesh(blender_mesh,
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_cache.py", line 38, in wrapper_cached
result = func(*args, **kwargs)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_mesh.py", line 61, in gather_mesh
primitives=__gather_primitives(blender_mesh, uuid_for_skined_data, vertex_groups, modifiers, materials, export_settings),
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_mesh.py", line 147, in __gather_primitives
return gltf2_blender_gather_primitives.gather_primitives(blender_mesh,
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_cache.py", line 38, in wrapper_cached
result = func(*args, **kwargs)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_primitives.py", line 81, in gather_primitives
material = gltf2_blender_gather_materials.gather_material(
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_cache.py", line 38, in wrapper_cached
result = func(*args, **kwargs)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_materials.py", line 53, in gather_material
pbr_metallic_roughness, uvmap_actives_pbr_metallic_roughness = __gather_pbr_metallic_roughness(blender_material, orm_texture, export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_materials.py", line 334, in __gather_pbr_metallic_roughness
return gltf2_blender_gather_materials_pbr_metallic_roughness.gather_material_pbr_metallic_roughness(
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_cache.py", line 38, in wrapper_cached
result = func(*args, **kwargs)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_materials_pbr_metallic_roughness.py", line 19, in gather_material_pbr_metallic_roughness
metallic_roughness_texture, use_active_uvmap_metallic_roughness_texture = __gather_metallic_roughness_texture(blender_material, orm_texture, export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_materials_pbr_metallic_roughness.py", line 140, in __gather_metallic_roughness_texture
return gltf2_blender_gather_texture_info.gather_texture_info(
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_texture_info.py", line 23, in gather_texture_info
return __gather_texture_info_helper(primary_socket, blender_shader_sockets, 'DEFAULT', export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_cache.py", line 38, in wrapper_cached
result = func(*args, **kwargs)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_texture_info.py", line 46, in __gather_texture_info_helper
'index': __gather_index(blender_shader_sockets, export_settings),
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_texture_info.py", line 129, in __gather_index
return glt
Interestingly enough, this crash report cuts off the traceback. I investigated the file it crashed and this is line 129 as mentioned above:
So as far as I know this doesn't even seem to be the full traceback which is odd.
System Specs:
- GPU: RTX 3080 ti + GeForce GTX 1660
- RAM: 4x16GB = 64Gb
- CPU: Intel Core i7-7700 3.60GHz
I've ran multiple tests with this setup and crashes every time. As the software is running the system memory slowly creeps up to 100% in Task Manager, then Blender crashes. I've used GPU + CPU compute, only GPU compute using only my 3080 ti, but nothing seems to change.
My team and I believe the textures are the source of the issue, but we aren't sure. The reason we suspect the textures is because the external texture folder is about 11.5GB.
My Question:
Blender is obviously retaining unneeded files/information in memory when exporting this many files (most likely texture/material files). Why doesn't it just delete whatever files it is storing so that it doesn't pass my system memory limit? Is there anything I can do with the Blender Python API to stop this from happening? Maybe by deleting files from RAM after the models have been generated?
I also noticed this in Edit > System > Memory & Limits:
Is there a setting here^ I can possibly utilize to resolve my issue?
Thank you for reading this post and for your answers. I really appreciate you taking the time looking this over and helping me find the answer. Please let me know in a comment if there are any more details you would like me to provide.
Edit: With further testing I have found that this issue only applies to exporting .gltf and .glb files. .fbx files export perfectly, do not increase memory over time, and do not result in a crash due to VRAM/RAM overflow. This seems like a very serious issue if and possibly a bug in Blenders GLTF/GLB file exporter. Am I wrong to assume this? I'm going to make a post on the devtalk.blender.org site about this.
Traceback from the .crash.txt file when exporting .glb files:
RuntimeError: Error: Python: Traceback (most recent call last):
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\__init__.py", line 628, in execute
return gltf2_blender_export.save(context, export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_export.py", line 35, in save
json, buffer = __export(export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_export.py", line 52, in __export
__gather_gltf(exporter, export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_export.py", line 66, in __gather_gltf
active_scene_idx, scenes, animations = gltf2_blender_gather.gather_gltf2(export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather.py", line 30, in gather_gltf2
scenes.append(__gather_scene(blender_scene, export_settings))
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_cache.py", line 38, in wrapper_cached
result = func(*args, **kwargs)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather.py", line 67, in __gather_scene
node = gltf2_blender_gather_nodes.gather_node(
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_nodes.py", line 31, in gather_node
children=__gather_children(vnode, blender_object, export_settings),
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_nodes.py", line 109, in __gather_children
child_node = gather_node(vtree.nodes[child], export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_nodes.py", line 31, in gather_node
children=__gather_children(vnode, blender_object, export_settings),
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_nodes.py", line 73, in __gather_children
node = gather_node(c, export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_nodes.py", line 31, in gather_node
children=__gather_children(vnode, blender_object, export_settings),
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_nodes.py", line 73, in __gather_children
node = gather_node(c, export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_nodes.py", line 35, in gather_node
mesh=__gather_mesh(vnode, blender_object, export_settings),
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_nodes.py", line 246, in __gather_mesh
result = gltf2_blender_gather_mesh.gather_mesh(blender_mesh,
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_cache.py", line 38, in wrapper_cached
result = func(*args, **kwargs)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_mesh.py", line 61, in gather_mesh
primitives=__gather_primitives(blender_mesh, uuid_for_skined_data, vertex_groups, modifiers, materials, export_settings),
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_mesh.py", line 147, in __gather_primitives
return gltf2_blender_gather_primitives.gather_primitives(blender_mesh,
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_cache.py", line 38, in wrapper_cached
result = func(*args, **kwargs)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_primitives.py", line 81, in gather_primitives
material = gltf2_blender_gather_materials.gather_material(
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_cache.py", line 38, in wrapper_cached
result = func(*args, **kwargs)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_materials.py", line 53, in gather_material
pbr_metallic_roughness, uvmap_actives_pbr_metallic_roughness = __gather_pbr_metallic_roughness(blender_material, orm_texture, export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_materials.py", line 334, in __gather_pbr_metallic_roughness
return gltf2_blender_gather_materials_pbr_metallic_roughness.gather_material_pbr_metallic_roughness(
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_cache.py", line 38, in wrapper_cached
result = func(*args, **kwargs)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_materials_pbr_metallic_roughness.py", line 19, in gather_material_pbr_metallic_roughness
metallic_roughness_texture, use_active_uvmap_metallic_roughness_texture = __gather_metallic_roughness_texture(blender_material, orm_texture, export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_materials_pbr_metallic_roughness.py", line 140, in __gather_metallic_roughness_texture
return gltf2_blender_gather_texture_info.gather_texture_info(
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_texture_info.py", line 23, in gather_texture_info
return __gather_texture_info_helper(primary_socket, blender_shader_sockets, 'DEFAULT', export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_cache.py", line 38, in wrapper_cached
result = func(*args, **kwargs)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_texture_info.py", line 46, in __gather_texture_info_helper
'index': __gather_index(blender_shader_sockets, export_settings),
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_texture_info.py", line 129, in __gather_index
return gltf2_blender_gather_texture.gather_texture(blender_shader_sockets, export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_cache.py", line 38, in wrapper_cached
result = func(*args, **kwargs)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_texture.py", line 36, in gather_texture
source=__gather_source(blender_shader_sockets, export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_texture.py", line 80, in __gather_source
return gltf2_blender_gather_image.gather_image(blender_shader_sockets, export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_cache.py", line 38, in wrapper_cached
result = func(*args, **kwargs)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_image.py", line 43, in gather_image
buffer_view = __gather_buffer_view(image_data, mime_type, name, export_settings)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_cache.py", line 38, in wrapper_cached
result = func(*args, **kwargs)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_gather_image.py", line 101, in __gather_buffer_view
return gltf2_io_binary_data.BinaryData(data=image_data.encode(mime_type))
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_image.py", line 117, in encode
return self.__encode_unhappy()
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\addons\io_scene_gltf2\blender\exp\gltf2_blender_image.py", line 141, in __encode_unhappy
out_buf = np.ones(width * height * 4, np.float32)
File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\python\lib\site-packages\numpy\core\numeric.py", line 204, in ones
a = empty(shape, dtype, order)
numpy.core._exceptions._ArrayMemoryError: Unable to allocate 256. MiB for an array with shape (67108864,) and data type float32
Location: C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\modules\bpy\ops.py:115 # Error
# backtrace
Exception Record:
ExceptionCode : EXCEPTION_ACCESS_VIOLATION
Exception Address : 0x00007FF69DFC7690
Exception Module : blender.exe
Exception Flags : 0x00000000
Exception Parameters : 0x2
Parameters[0] : 0x0000000000000000
Parameters[1] : 0x0000000000000000
Stack trace:
blender.exe :0x00007FF69DFC7690 Symbols not available
Loaded Modules :
# Python backtrace
*I have no idea what these tracebacks mean btw