1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
# SPDX-License-Identifier: Apache-2.0
# Copyright 2018-2021 The glTF-Blender-IO authors.
import bpy
from io_scene_gltf2.io.com import gltf2_io
from io_scene_gltf2.blender.exp import gltf2_blender_gather_texture_info, gltf2_blender_search_node_tree
from io_scene_gltf2.blender.exp import gltf2_blender_get
from io_scene_gltf2.blender.exp.gltf2_blender_gather_cache import cached
from io_scene_gltf2.io.exp.gltf2_io_user_extensions import export_user_extensions
@cached
def gather_material_pbr_metallic_roughness(blender_material, orm_texture, export_settings):
if not __filter_pbr_material(blender_material, export_settings):
return None, None
base_color_texture, use_active_uvmap_base_color_texture = __gather_base_color_texture(blender_material, export_settings)
metallic_roughness_texture, use_active_uvmap_metallic_roughness_texture = __gather_metallic_roughness_texture(blender_material, orm_texture, export_settings)
material = gltf2_io.MaterialPBRMetallicRoughness(
base_color_factor=__gather_base_color_factor(blender_material, export_settings),
base_color_texture=base_color_texture,
extensions=__gather_extensions(blender_material, export_settings),
extras=__gather_extras(blender_material, export_settings),
metallic_factor=__gather_metallic_factor(blender_material, export_settings),
metallic_roughness_texture=metallic_roughness_texture,
roughness_factor=__gather_roughness_factor(blender_material, export_settings)
)
# merge all use_active_uvmap infos
uvmap_actives = []
if use_active_uvmap_base_color_texture is True:
uvmap_actives.append("baseColorTexture")
if use_active_uvmap_metallic_roughness_texture is True:
uvmap_actives.append("metallicRoughnessTexture")
export_user_extensions('gather_material_pbr_metallic_roughness_hook', export_settings, material, blender_material, orm_texture)
return material, uvmap_actives
def __filter_pbr_material(blender_material, export_settings):
return True
def __gather_base_color_factor(blender_material, export_settings):
if not blender_material.use_nodes:
return [*blender_material.diffuse_color[:3], 1.0]
rgb, alpha = None, None
alpha_socket = gltf2_blender_get.get_socket(blender_material, "Alpha")
if isinstance(alpha_socket, bpy.types.NodeSocket):
if export_settings['gltf_image_format'] != "NONE":
alpha = gltf2_blender_get.get_factor_from_socket(alpha_socket, kind='VALUE')
else:
alpha = gltf2_blender_get.get_const_from_default_value_socket(alpha_socket, kind='VALUE')
base_color_socket = gltf2_blender_get.get_socket(blender_material, "Base Color")
if base_color_socket is None:
base_color_socket = gltf2_blender_get.get_socket(blender_material, "BaseColor")
if base_color_socket is None:
base_color_socket = gltf2_blender_get.get_socket_old(blender_material, "BaseColorFactor")
if isinstance(base_color_socket, bpy.types.NodeSocket):
if export_settings['gltf_image_format'] != "NONE":
rgb = gltf2_blender_get.get_factor_from_socket(base_color_socket, kind='RGB')
else:
rgb = gltf2_blender_get.get_const_from_default_value_socket(base_color_socket, kind='RGB')
if rgb is None: rgb = [1.0, 1.0, 1.0]
if alpha is None: alpha = 1.0
rgba = [*rgb, alpha]
if rgba == [1, 1, 1, 1]: return None
return rgba
def __gather_base_color_texture(blender_material, export_settings):
base_color_socket = gltf2_blender_get.get_socket(blender_material, "Base Color")
if base_color_socket is None:
base_color_socket = gltf2_blender_get.get_socket(blender_material, "BaseColor")
if base_color_socket is None:
base_color_socket = gltf2_blender_get.get_socket_old(blender_material, "BaseColor")
alpha_socket = gltf2_blender_get.get_socket(blender_material, "Alpha")
# keep sockets that have some texture : color and/or alpha
inputs = tuple(
socket for socket in [base_color_socket, alpha_socket]
if socket is not None and __has_image_node_from_socket(socket)
)
if not inputs:
return None, None
return gltf2_blender_gather_texture_info.gather_texture_info(inputs[0], inputs, export_settings)
def __gather_extensions(blender_material, export_settings):
return None
def __gather_extras(blender_material, export_settings):
return None
def __gather_metallic_factor(blender_material, export_settings):
if not blender_material.use_nodes:
return blender_material.metallic
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):
fac = gltf2_blender_get.get_factor_from_socket(metallic_socket, kind='VALUE')
return fac if fac != 1 else None
return None
def __gather_metallic_roughness_texture(blender_material, orm_texture, export_settings):
metallic_socket = gltf2_blender_get.get_socket(blender_material, "Metallic")
roughness_socket = gltf2_blender_get.get_socket(blender_material, "Roughness")
hasMetal = metallic_socket is not None and __has_image_node_from_socket(metallic_socket)
hasRough = roughness_socket is not None and __has_image_node_from_socket(roughness_socket)
if not hasMetal and not hasRough:
metallic_roughness = gltf2_blender_get.get_socket_old(blender_material, "MetallicRoughness")
if metallic_roughness is None or not __has_image_node_from_socket(metallic_roughness):
return None, None
texture_input = (metallic_roughness,)
elif not hasMetal:
texture_input = (roughness_socket,)
elif not hasRough:
texture_input = (metallic_socket,)
else:
texture_input = (metallic_socket, roughness_socket)
return gltf2_blender_gather_texture_info.gather_texture_info(
texture_input[0],
orm_texture or texture_input,
export_settings,
)
def __gather_roughness_factor(blender_material, export_settings):
if not blender_material.use_nodes:
return blender_material.roughness
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):
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):
result = gltf2_blender_search_node_tree.from_socket(
socket,
gltf2_blender_search_node_tree.FilterByType(bpy.types.ShaderNodeTexImage))
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
)
|