diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py index 1b3c0cc2e04770cbadac9471faa0ffb10389b779..b290f94620e1e5c967ea3749a84a2a189e9829fb 100755 --- a/io_scene_gltf2/__init__.py +++ b/io_scene_gltf2/__init__.py @@ -4,7 +4,7 @@ bl_info = { 'name': 'glTF 2.0 format', 'author': 'Julien Duroure, Scurest, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors', - "version": (3, 2, 8), + "version": (3, 2, 9), 'blender': (3, 1, 0), 'location': 'File > Import-Export', 'description': 'Import-Export as glTF 2.0', diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py index 845024e576884157202f546481f6a42764efbd2d..71aec00d4ce86d3fa002812cf61e25fca27f8f74 100755 --- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py @@ -55,6 +55,12 @@ def gather_material(blender_material, export_settings): pbr_metallic_roughness=__gather_pbr_metallic_roughness(blender_material, orm_texture, export_settings) ) + # If emissive is set, from an emissive node (not PBR) + # We need to set manually default values for + # pbr_metallic_roughness.baseColor + if material.emissive_factor is not None and gltf2_blender_get.get_node_socket(blender_material, bpy.types.ShaderNodeBsdfPrincipled, "Base Color") is None: + material.pbr_metallic_roughness = gltf2_blender_gather_materials_pbr_metallic_roughness.get_default_pbr_for_emissive_node() + export_user_extensions('gather_material_hook', export_settings, material, blender_material) return material diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials_pbr_metallic_roughness.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials_pbr_metallic_roughness.py index 3e18dbad95707cd43c00fa955647e74505e5fbbb..9395aa434bafb1c96b151a9914f8e1a223ab91cb 100755 --- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials_pbr_metallic_roughness.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials_pbr_metallic_roughness.py @@ -153,3 +153,14 @@ def __has_image_node_from_socket(socket): if not result: return False return True + +def get_default_pbr_for_emissive_node(): + return gltf2_io.MaterialPBRMetallicRoughness( + base_color_factor=[0.0,0.0,0.0,1.0], + base_color_texture=None, + extensions=None, + extras=None, + metallic_factor=None, + metallic_roughness_texture=None, + roughness_factor=None + ) diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_get.py b/io_scene_gltf2/blender/exp/gltf2_blender_get.py index 940f6f0ae9736d44f0434817124fec6a72c21ef1..75e17b34694011581fb56c03c5e90b86648ef157 100755 --- a/io_scene_gltf2/blender/exp/gltf2_blender_get.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_get.py @@ -32,6 +32,21 @@ def get_object_from_datapath(blender_object, data_path: str): return prop +def get_node_socket(blender_material, type, name): + """ + For a given material input name, retrieve the corresponding node tree socket for a given node type. + + :param blender_material: a blender material for which to get the socket + :return: a blender NodeSocket for a given type + """ + nodes = [n for n in blender_material.node_tree.nodes if isinstance(n, type) and not n.mute] + nodes = [node for node in nodes if check_if_is_linked_to_active_output(node.outputs[0])] + inputs = sum([[input for input in node.inputs if input.name == name] for node in nodes], []) + if inputs: + return inputs[0] + return None + + def get_socket(blender_material: bpy.types.Material, name: str): """ For a given material input name, retrieve the corresponding node tree socket. @@ -46,13 +61,9 @@ def get_socket(blender_material: bpy.types.Material, name: str): if name == "Emissive": # Check for a dedicated Emission node first, it must supersede the newer built-in one # because the newer one is always present in all Principled BSDF materials. - type = bpy.types.ShaderNodeEmission - name = "Color" - nodes = [n for n in blender_material.node_tree.nodes if isinstance(n, type) and not n.mute] - nodes = [node for node in nodes if check_if_is_linked_to_active_output(node.outputs[0])] - inputs = sum([[input for input in node.inputs if input.name == name] for node in nodes], []) - if inputs: - return inputs[0] + emissive_socket = get_node_socket(blender_material, bpy.types.ShaderNodeEmission, "Color") + if emissive_socket: + return emissive_socket # If a dedicated Emission node was not found, fall back to the Principled BSDF Emission socket. name = "Emission" type = bpy.types.ShaderNodeBsdfPrincipled @@ -61,11 +72,8 @@ def get_socket(blender_material: bpy.types.Material, name: str): name = "Color" else: type = bpy.types.ShaderNodeBsdfPrincipled - nodes = [n for n in blender_material.node_tree.nodes if isinstance(n, type) and not n.mute] - nodes = [node for node in nodes if check_if_is_linked_to_active_output(node.outputs[0])] - inputs = sum([[input for input in node.inputs if input.name == name] for node in nodes], []) - if inputs: - return inputs[0] + + return get_node_socket(blender_material, type, name) return None