blender2ogre: duplicate materials Topic is solved

Problems building or running the engine, queries about how to use features etc.
slapin
Bronze Sponsor
Bronze Sponsor
Posts: 250
Joined: Fri May 23, 2025 5:04 pm
x 16

blender2ogre: duplicate materials

Post by slapin »

Hi, all!
I have a lot of meshes which use the same material to reduce draw calls.The material is exported by blender2ogre and put into file. Many files...
Ogre is not too happy about this and I have to grep the .material files and delete duplicates... which I am not too happy about. Is there some way to make export see that there is already a material and not export it again? Renaming materials makes them different materials which is not a solution as creates another problems. I export many files with command lines as part of cmake rule...

rpgplayerrobin
Orc Shaman
Posts: 788
Joined: Wed Mar 18, 2009 3:03 am
x 447

Re: blender2ogre: duplicate materials

Post by rpgplayerrobin »

  1. Using the same material does not automatically reduce draw calls unless you batch all those meshes together either with instancing or making them into one giant mesh. But if you are using Ogre Next, it does do it automatically, so I guess you are using that?

  2. Can you share the Blender file that exports the many materials so that we can also see the exact issue? Because the cause of this issue can be anything unless we can see what actually happens.

slapin
Bronze Sponsor
Bronze Sponsor
Posts: 250
Joined: Fri May 23, 2025 5:04 pm
x 16

Re: blender2ogre: duplicate materials

Post by slapin »

No, I use 1.x master branch. It is not 1 blend file,it is like 50 of them. Just using the same material over all files, static geometry. I get 39 drawcalls so I guess some kind of automatic batching works.
I can't use Ogre-next as I need older hw support.

paroj
OGRE Team Member
OGRE Team Member
Posts: 2238
Joined: Sun Mar 30, 2014 2:51 pm
x 1217

Re: blender2ogre: duplicate materials

Post by paroj »

rpgplayerrobin wrote: Thu Sep 25, 2025 4:24 pm
  1. Using the same material does not automatically reduce draw calls unless you batch all those meshes together either with instancing or making them into one giant mesh. But if you are using Ogre Next, it does do it automatically, so I guess you are using that?

  2. Can you share the Blender file that exports the many materials so that we can also see the exact issue? Because the cause of this issue can be anything unless we can see what actually happens.

FYI https://www.ogre3d.org/2022/10/29/ogre- ... instancing

slapin
Bronze Sponsor
Bronze Sponsor
Posts: 250
Joined: Fri May 23, 2025 5:04 pm
x 16

Re: blender2ogre: duplicate materials

Post by slapin »

I guess what happens is when I export foo.scene, foo1.scene and foo2.scene, foo.material, foo1.material and foo2.material get created, but
material name there is the same which confuses Ogre. When I delete foo1.material and foo2.material everything works as expected.
I'd like to have some automation option to not specially look for material duplicates like these as it is cumbersome and error-prone...
Would be nice if I could specify placeholder material which would not be exported and already exported one used instead...
The workaround for now is to do it twice - export all materials first time, then delete all .material files, then export one .blend again with materials.
Because I export to the same directory the problem ever happens only to .material files, so it is easier to resolve.

rpgplayerrobin
Orc Shaman
Posts: 788
Joined: Wed Mar 18, 2009 3:03 am
x 447

Re: blender2ogre: duplicate materials

Post by rpgplayerrobin »

paroj wrote: Thu Sep 25, 2025 6:54 pm
rpgplayerrobin wrote: Thu Sep 25, 2025 4:24 pm
  1. Using the same material does not automatically reduce draw calls unless you batch all those meshes together either with instancing or making them into one giant mesh. But if you are using Ogre Next, it does do it automatically, so I guess you are using that?

  2. Can you share the Blender file that exports the many materials so that we can also see the exact issue? Because the cause of this issue can be anything unless we can see what actually happens.

FYI https://www.ogre3d.org/2022/10/29/ogre- ... instancing

Nice!

I guess what happens is when I export foo.scene, foo1.scene and foo2.scene, foo.material, foo1.material and foo2.material get created, but
material name there is the same which confuses Ogre. When I delete foo1.material and foo2.material everything works as expected.
I'd like to have some automation option to not specially look for material duplicates like these as it is cumbersome and error-prone...
Would be nice if I could specify placeholder material which would not be exported and already exported one used instead...
The workaround for now is to do it twice - export all materials first time, then delete all .material files, then export one .blend again with materials.
Because I export to the same directory the problem ever happens only to .material files, so it is easier to resolve.

I tried it myself. I created two different Blender projects, created a new mesh in both and gave them both a material with the same name (in two different files), and then I exported them by exporting the scene.
I did not get it to mimic your behavior, for me it only creates the material file once even if I export it twice from two different Blender files.
This is exactly why you should give us something that shows us the error, otherwise it is very hard to help, since I don't see any error on my end right now.

You don't have to share all 50 Blender files, only two that shows the error.

slapin
Bronze Sponsor
Bronze Sponsor
Posts: 250
Joined: Fri May 23, 2025 5:04 pm
x 16

Re: blender2ogre: duplicate materials

Post by slapin »

Hi, all!
Sorry for delay with answer, got sick and needed time to recover. And after that I had all payments expired, including domains prolongation and had to recover the damage. You can't get sick in this world, ever.

Looking at the code it is kind of impossible to behave any other way.
Blend files: https://cloud.slapin.net/s/7KRXqcNARTxWQAg
How I export them:

Code: Select all

# CmakeLists.txt
file(GLOB VEHICLES_SRC ${CMAKE_SOURCE_DIR}/assets/blender/vehicles/*.blend)
set(VEHICLE_OUTPUT_FILES)
foreach(VEHICLE_FILE ${VEHICLES_SRC})
	get_filename_component(FILE_NAME ${VEHICLE_FILE} NAME_WE)
	set(VEHICLE_OUTPUT_FILE ${CMAKE_BINARY_DIR}/resources/vehicles/${FILE_NAME}.glb)
	add_custom_command(
		OUTPUT ${VEHICLE_OUTPUT_FILE}
		COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/resources/vehicles
		COMMAND ${BLENDER} ${VEHICLE_FILE}
			-b -Y -P
			${CMAKE_SOURCE_DIR}/assets/blender/scripts/export_buildings.py
			-- ${VEHICLE_OUTPUT_FILE}
		COMMAND touch ${VEHICLE_OUTPUT_FILE}
		DEPENDS ${VEHICLE_FILE})
	list(APPEND VEHICLE_OUTPUT_FILES ${VEHICLE_OUTPUT_FILE})
endforeach()

Code: Select all

#!/usr/bin/env python

import os, sys, time
import bpy
from math import pi
import glob
import shutil
from mathutils import Vector, Matrix
from math import radians, pi

argv = sys.argv
argv = argv[argv.index("--") + 1:]

sys.path.insert(0, os.getcwd() + "/assets/blender/scripts")
sys.path.insert(1, os.getcwd() + "/assets/blender/scripts/blender2ogre")
import io_ogre

gltf_file = argv[0]
print("Exporting to " + gltf_file)
basepath = os.getcwd()
#    bpy.ops.export_scene.gltf(filepath="", check_existing=True,
#     export_import_convert_lighting_mode='SPEC', gltf_export_id="",
#     export_format='GLB', ui_tab='GENERAL', export_copyright="", export_image_format='AUTO',
#     export_texture_dir="", export_jpeg_quality=75, export_keep_originals=False,
#     export_texcoords=True, export_normals=True, export_draco_mesh_compression_enable=False,
#     export_draco_mesh_compression_level=6, export_draco_position_quantization=14,
#     export_draco_normal_quantization=10, export_draco_texcoord_quantization=12,
#     export_draco_color_quantization=10, export_draco_generic_quantization=12, export_tangents=False,
#     export_materials='EXPORT', export_original_specular=False, export_colors=True,
#     export_attributes=False, use_mesh_edges=False, use_mesh_vertices=False, export_cameras=False,
#     use_selection=False, use_visible=False, use_renderable=False,
#     use_active_collection_with_nested=True, use_active_collection=False, use_active_scene=False,
#     export_extras=False, export_yup=True, export_apply=False, export_animations=True,
#     export_frame_range=False, export_frame_step=1, export_force_sampling=True, export_animation_mode='ACTIONS',
#     export_nla_strips_merged_animation_name="Animation", export_def_bones=False,
#     export_hierarchy_flatten_bones=False, export_optimize_animation_size=True,
#     export_optimize_animation_keep_anim_armature=True, export_optimize_animation_keep_anim_object=False,
#     export_negative_frame='SLIDE', export_anim_slide_to_zero=False, export_bake_animation=False,
#     export_anim_single_armature=True, export_reset_pose_bones=True, export_current_frame=False,
#     export_rest_position_armature=True, export_anim_scene_split_object=True, export_skins=True,
#     export_all_influences=False, export_morph=True, export_morph_normal=True,
#     export_morph_tangent=False, export_morph_animation=True, export_morph_reset_sk_data=True,
#     export_lights=False, export_nla_strips=True, will_save_settings=False, filter_glob="*.glb")

for obj in bpy.data.objects:
    if obj.name.endswith("-col"):
            bpy.data.objects.remove(obj)

scene_file = gltf_file.replace(".glb", "").replace(".gltf", "") + ".scene"
bpy.ops.ogre.export(filepath=scene_file,
        EX_SWAP_AXIS='xz-y',
        EX_V2_MESH_TOOL_VERSION='v2',
        EX_EXPORT_XML_DELETE=True,
        EX_SCENE=True,
        EX_SELECTED_ONLY=False,
        EX_EXPORT_HIDDEN=False,
        EX_FORCE_CAMERA=False,
        EX_FORCE_LIGHTS=False,
        EX_NODE_ANIMATION=True,
        EX_MATERIALS=True,
        EX_SEPARATE_MATERIALS=False,
        EX_COPY_SHADER_PROGRAMS=True,
        EX_MESH=True,
        EX_LOD_LEVELS=3,
        EX_LOD_DISTANCE=100,
        EX_LOD_PERCENT=40
)

bpy.ops.export_scene.gltf(filepath=gltf_file,
        use_selection=False,
        check_existing=False,
        export_format='GLB',
        export_texture_dir='textures', export_texcoords=True,
        export_normals=True,
        export_tangents=True,
        export_materials='EXPORT',
        export_colors=True,
        use_mesh_edges=False,
        use_mesh_vertices=False,
        export_cameras=False,
        use_visible=False,
        use_renderable=False,
        export_yup=True,
        export_apply=True,
        export_animations=True,
        export_force_sampling=True,
        export_def_bones=False,
        export_current_frame=False,
        export_morph=True,
        export_morph_animation=False,
        export_morph_normal=True,
        export_morph_tangent=True,
        export_lights=False,
        export_skins=True)

bpy.ops.wm.read_homefile(use_empty=True)
time.sleep(2)
bpy.ops.wm.quit_blender()
slapin
Bronze Sponsor
Bronze Sponsor
Posts: 250
Joined: Fri May 23, 2025 5:04 pm
x 16

Re: blender2ogre: duplicate materials

Post by slapin »

@rpgplayerrobin ^

rpgplayerrobin
Orc Shaman
Posts: 788
Joined: Wed Mar 18, 2009 3:03 am
x 447

Re: blender2ogre: duplicate materials

Post by rpgplayerrobin »

  1. This is very custom, since you are using a custom script and then a build thingy with it.
    It would probably take me hours to even understand what it is actually doing and what causes your issue.
    You are also seem to export to glb, which I don't do, I only export objects to the Ogre mesh format.
    When I did the tests myself, I only exported by using the default Ogre Blender export dialogue, and the bug that you describe does not happen for me from that one.
    If your current custom script has issues, make a minimal reproducible custom export script and a minimal Blender file or two to reproduce the bug, because this is a bit too much to know what to do with.

  2. Regarding when you wrote "Looking at the code it is kind of impossible to behave any other way.", what code is it you are referring to? Have you already found the culprit?

  3. Are you exporting the many Blender files to different directories? In that case I understand that your material files get duplicates, but I guess it is not that simple, because in that case there is nothing to solve, because that would not be a bug. In that case I would just solve it in the application later on by adding a resource group listener to skip loading materials that already exists with the same name.

slapin
Bronze Sponsor
Bronze Sponsor
Posts: 250
Joined: Fri May 23, 2025 5:04 pm
x 16

Re: blender2ogre: duplicate materials

Post by slapin »

  1. I currently just brute force check material files for duplicate materials which is kind of very crude fix for the problem...
    I do export to both glb and Ogre's scene + mesh but I wonder if that can cause problems... At least I did not find a difference... Need to experiment with that but I will be very surprised you can't have same name for materials inside glbs... Also glbs do not create material files and deleting duplicate material files solves the problem. With my export I see boat.material and raft.material created with 'raft' material inside.
    If I delete boat.material the problem is solved. But if asset count increases I will need to find some more permanent solution to the problem...
    The script is actually quite minimal, just run

    Code: Select all

    blender -b  boat.blend -P scripts/export_buildings.py -- /tmp/exports/boat.glb
    blender -b raft.blend -P scripts/export_buildings.py -- /tmp/exports/raft.glb
    

    and see the files created. The direct usage of blender2ogre can be removed at top of the script

    Code: Select all

    sys.path.insert(0, os.getcwd() + "/assets/blender/scripts")
    sys.path.insert(1, os.getcwd() + "/assets/blender/scripts/blender2ogre")
    import io_ogre
    

    as if plugin is enabled the export line will just work, otherwise it is just 2 export commands.

  2. I did not find any code which would look up already defined materials. That is why.

  3. I export all the blends to the same directory in hope to share same-named resources.

Last edited by slapin on Sun Oct 05, 2025 4:31 pm, edited 1 time in total.
User avatar
sercero
Bronze Sponsor
Bronze Sponsor
Posts: 535
Joined: Sun Jan 18, 2015 4:20 pm
Location: Buenos Aires, Argentina
x 198

Re: blender2ogre: duplicate materials

Post by sercero »

Are you constantly changing the materials?

Why not export the materials all at once and then export only meshes when they change?

I also wonder if you tried exporting with the option to put all the materials in one file.

slapin
Bronze Sponsor
Bronze Sponsor
Posts: 250
Joined: Fri May 23, 2025 5:04 pm
x 16

Re: blender2ogre: duplicate materials

Post by slapin »

  1. I often change materials. models et al. Please elaborate on what you're asking about.
  2. Nothing is wrong about that, one of my ideas was a material library approach, i.e. I have export pass for materials-only, deleting everything except for materials, combine them in single special .material file removing duplicates. Then export normally deleting all the .material files. But that is yet to be done. If blender2ogre would support material library directly that would be great...
  3. No, probably I could not find that option...
rpgplayerrobin
Orc Shaman
Posts: 788
Joined: Wed Mar 18, 2009 3:03 am
x 447

Re: blender2ogre: duplicate materials

Post by rpgplayerrobin »

I now tried it with your script, I did this in a .bat file:

Code: Select all

"C:\Program Files\Blender Foundation\Blender 4.4\blender.exe" -b boat.blend -P export_buildings.py -- "C:\Users\MYUSER\Desktop\test\exports\boat.glb"
"C:\Program Files\Blender Foundation\Blender 4.4\blender.exe" -b raft.blend -P export_buildings.py -- "C:\Users\MYUSER\Desktop\test\exports\raft.glb"
pause

Then I downloaded boat.blend and raft.blend and put it in the same directory as that script.
Then I copied your .py script and removed the 3 lines you mentioned, and put it in the same directory.

My result in the export directory became this, and I don't see any material duplications:

Code: Select all

.png
boat.material
boat.scene
boat-deck.mesh
boat-hull.mesh
boat-rudder.mesh
mast-horiz.mesh
mast-main.mesh
OgreMeshUpgrader.log
OgreXMLConverter.log
raft.material
raft.mesh
raft.scene
sail-plain.mesh

I also tried running it two times, but the result was exactly the same.

In that case, it means that the minimal reproducable example does not reproduce the bug you mentioned, or it might be that my Blender version is different (4.4) or it may be that the Ogre exporter version is different.

rpgplayerrobin
Orc Shaman
Posts: 788
Joined: Wed Mar 18, 2009 3:03 am
x 447

Re: blender2ogre: duplicate materials

Post by rpgplayerrobin »

Actually, when I checked through the files contents, I guess I understand the issue you are facing.
Both boat.material and raft.material contain the exact same text:

Code: Select all

// generated by blender2ogre 0.9.0 on 2025-10-06 00:40:59
material raft {
    receive_shadows on
    technique {
        pass {
            diffuse 0.8 0.8 0.8 1.0
            specular 1.0 0.0 0 0 0

        // additional maps - requires RTSS
        rtshader_system {
            lighting_stage metal_roughness
        }

        // - base_color_texture
        texture_unit {
            texture .png
            tex_address_mode wrap
            colour_op modulate
        }
    }
}
}

Opening the individual Blender files and exporting them showed me the exact same issue, when exporting it as a scene.
But, if I just altered it to use separate materials when exporting with the dialogue, it works correctly (just 1 total material: raft.material, as expected).

So I tried just to change the py file from:
EX_SEPARATE_MATERIALS=False
To:
EX_SEPARATE_MATERIALS=True

And it then seem to work, since the material name is the scene name otherwise, but now its the actual material name.

slapin
Bronze Sponsor
Bronze Sponsor
Posts: 250
Joined: Fri May 23, 2025 5:04 pm
x 16

Re: blender2ogre: duplicate materials

Post by slapin »

Thanks a lot for your help!