Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Duroure <julien.duroure@gmail.com>2020-09-05 16:33:18 +0300
committerJulien Duroure <julien.duroure@gmail.com>2020-09-05 16:33:18 +0300
commit3a5aaa9b9999a0eada72076ba5b5bacc653e4528 (patch)
treee170b508072974a151c34ea4ea0fba70000a752a /io_scene_gltf2
parent109632093bd5f3c7754cf6d66cfe66579d734cb3 (diff)
glTF exporter: materials: export factors from MULTIPLY nodes
Diffstat (limited to 'io_scene_gltf2')
-rwxr-xr-xio_scene_gltf2/__init__.py2
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py9
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_materials_pbr_metallic_roughness.py60
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_get.py64
4 files changed, 87 insertions, 48 deletions
diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py
index 71bd75d9..df5be122 100755
--- a/io_scene_gltf2/__init__.py
+++ b/io_scene_gltf2/__init__.py
@@ -15,7 +15,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": (1, 4, 15),
+ "version": (1, 4, 16),
'blender': (2, 90, 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 3ad17fe2..0abe9256 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py
@@ -111,12 +111,13 @@ def __gather_emissive_factor(blender_material, export_settings):
if emissive_socket is None:
emissive_socket = gltf2_blender_get.get_socket_old(blender_material, "EmissiveFactor")
if isinstance(emissive_socket, bpy.types.NodeSocket):
- if emissive_socket.is_linked:
+ fac = gltf2_blender_get.get_factor_from_socket(emissive_socket, kind='RGB')
+ if fac is None and emissive_socket.is_linked:
# In glTF, the default emissiveFactor is all zeros, so if an emission texture is connected,
# we have to manually set it to all ones.
- return [1.0, 1.0, 1.0]
- else:
- return list(emissive_socket.default_value)[0:3]
+ fac = [1.0, 1.0, 1.0]
+ if fac == [0, 0, 0]: fac = None
+ return fac
return None
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 7913d175..05f94202 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
@@ -47,8 +47,11 @@ def __filter_pbr_material(blender_material, export_settings):
def __gather_base_color_factor(blender_material, export_settings):
+ rgb, alpha = None, None
+
alpha_socket = gltf2_blender_get.get_socket(blender_material, "Alpha")
- alpha = alpha_socket.default_value if alpha_socket is not None and not alpha_socket.is_linked else 1.0
+ if isinstance(alpha_socket, bpy.types.NodeSocket):
+ alpha = gltf2_blender_get.get_factor_from_socket(alpha_socket, kind='VALUE')
base_color_socket = gltf2_blender_get.get_socket(blender_material, "Base Color")
if base_color_socket is None:
@@ -57,38 +60,16 @@ def __gather_base_color_factor(blender_material, export_settings):
base_color_socket = gltf2_blender_get.get_socket_old(blender_material, "BaseColorFactor")
if base_color_socket is None:
base_color_socket = gltf2_blender_get.get_socket(blender_material, "Background")
- if not isinstance(base_color_socket, bpy.types.NodeSocket):
- return None
- if not base_color_socket.is_linked:
- return list(base_color_socket.default_value)[:3] + [alpha]
-
- texture_node = __get_tex_from_socket(base_color_socket)
- if texture_node is None:
- return None
-
- def is_valid_multiply_node(node):
- return isinstance(node, bpy.types.ShaderNodeMixRGB) and \
- node.blend_type == "MULTIPLY" and \
- len(node.inputs) == 3
-
- multiply_node = next((link.from_node for link in texture_node.path if is_valid_multiply_node(link.from_node)), None)
- if multiply_node is None:
- return None
-
- def is_factor_socket(socket):
- return isinstance(socket, bpy.types.NodeSocketColor) and \
- (not socket.is_linked or socket.links[0] not in texture_node.path)
+ if isinstance(base_color_socket, bpy.types.NodeSocket):
+ rgb = gltf2_blender_get.get_factor_from_socket(base_color_socket, kind='RGB')
- factor_socket = next((socket for socket in multiply_node.inputs if is_factor_socket(socket)), None)
- if factor_socket is None:
- return None
+ if rgb is None: rgb = [1.0, 1.0, 1.0]
+ if alpha is None: alpha = 1.0
- if factor_socket.is_linked:
- print_console("WARNING", "BaseColorFactor only supports sockets without links (in Node '{}')."
- .format(multiply_node.name))
- return None
+ rgba = [*rgb, alpha]
- return list(factor_socket.default_value)[:3] + [alpha]
+ if rgba == [1, 1, 1, 1]: return None
+ return rgba
def __gather_base_color_texture(blender_material, export_settings):
@@ -109,15 +90,6 @@ def __gather_base_color_texture(blender_material, export_settings):
return gltf2_blender_gather_texture_info.gather_texture_info(inputs, export_settings)
-def __get_tex_from_socket(blender_shader_socket: bpy.types.NodeSocket):
- result = gltf2_blender_search_node_tree.from_socket(
- blender_shader_socket,
- gltf2_blender_search_node_tree.FilterByType(bpy.types.ShaderNodeTexImage))
- if not result:
- return None
- return result[0]
-
-
def __gather_extensions(blender_material, export_settings):
return None
@@ -130,8 +102,9 @@ def __gather_metallic_factor(blender_material, export_settings):
metallic_socket = gltf2_blender_get.get_socket(blender_material, "Metallic")
if metallic_socket is None:
metallic_socket = gltf2_blender_get.get_socket_old(blender_material, "MetallicFactor")
- if isinstance(metallic_socket, bpy.types.NodeSocket) and not metallic_socket.is_linked:
- return metallic_socket.default_value
+ if isinstance(metallic_socket, bpy.types.NodeSocket):
+ fac = gltf2_blender_get.get_factor_from_socket(metallic_socket, kind='VALUE')
+ return fac if fac != 1 else None
return None
@@ -164,8 +137,9 @@ def __gather_roughness_factor(blender_material, export_settings):
roughness_socket = gltf2_blender_get.get_socket(blender_material, "Roughness")
if roughness_socket is None:
roughness_socket = gltf2_blender_get.get_socket_old(blender_material, "RoughnessFactor")
- if isinstance(roughness_socket, bpy.types.NodeSocket) and not roughness_socket.is_linked:
- return roughness_socket.default_value
+ if isinstance(roughness_socket, bpy.types.NodeSocket):
+ fac = gltf2_blender_get.get_factor_from_socket(roughness_socket, kind='VALUE')
+ return fac if fac != 1 else None
return None
def __has_image_node_from_socket(socket):
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_get.py b/io_scene_gltf2/blender/exp/gltf2_blender_get.py
index 4f66aa6a..27f4ae18 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_get.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_get.py
@@ -218,3 +218,67 @@ def get_node(data_path):
return None
return node_name[:(index)]
+
+
+def get_factor_from_socket(socket, kind):
+ """
+ For baseColorFactor, metallicFactor, etc.
+ Get a constant value from a socket, or a constant value
+ from a MULTIPLY node just before the socket.
+ kind is either 'RGB' or 'VALUE'.
+ """
+ fac = __get_const_from_socket(socket, kind)
+ if fac is not None:
+ return fac
+
+ node = __previous_node(socket)
+ if node is not None:
+ x1, x2 = None, None
+ if kind == 'RGB':
+ if node.type == 'MIX_RGB' and node.blend_type == 'MULTIPLY':
+ # TODO: handle factor in inputs[0]?
+ x1 = __get_const_from_socket(node.inputs[1], kind)
+ x2 = __get_const_from_socket(node.inputs[2], kind)
+ if kind == 'VALUE':
+ if node.type == 'MATH' and node.operation == 'MULTIPLY':
+ x1 = __get_const_from_socket(node.inputs[0], kind)
+ x2 = __get_const_from_socket(node.inputs[1], kind)
+ if x1 is not None and x2 is None: return x1
+ if x2 is not None and x1 is None: return x2
+
+ return None
+
+
+def __get_const_from_socket(socket, kind):
+ if not socket.is_linked:
+ if kind == 'RGB':
+ if socket.type != 'RGBA': return None
+ return list(socket.default_value)[:3]
+ if kind == 'VALUE':
+ if socket.type != 'VALUE': return None
+ return socket.default_value
+
+ # Handle connection to a constant RGB/Value node
+ prev_node = __previous_node(socket)
+ if prev_node is not None:
+ if kind == 'RGB' and prev_node.type == 'RGB':
+ return list(prev_node.outputs[0].default_value)[:3]
+ if kind == 'VALUE' and prev_node.type == 'VALUE':
+ return prev_node.outputs[0].default_value
+
+ return None
+
+
+def __previous_node(socket):
+ while True:
+ if not socket.is_linked:
+ return None
+
+ node = socket.links[0].from_node
+
+ # Skip over reroute nodes
+ if node.type == 'REROUTE':
+ socket = node.inputs[0]
+ continue
+
+ return node