Import_3ds: Improved distance cue node setup
[blender-addons.git] / io_scene_gltf2 / blender / exp / material / gltf2_blender_gather_materials.py
blob8177843c7ec421df8caa94f2765da35f25980fee
1 # SPDX-FileCopyrightText: 2018-2022 The glTF-Blender-IO authors
3 # SPDX-License-Identifier: Apache-2.0
5 from copy import deepcopy
6 import bpy
8 from ....io.com import gltf2_io
9 from ....io.com.gltf2_io_extensions import Extension
10 from ....io.exp.gltf2_io_user_extensions import export_user_extensions
11 from ...com.gltf2_blender_extras import generate_extras
12 from ..gltf2_blender_gather_cache import cached, cached_by_key
13 from . import gltf2_blender_gather_materials_unlit
14 from . import gltf2_blender_gather_texture_info
15 from . import gltf2_blender_gather_materials_pbr_metallic_roughness
16 from .extensions.gltf2_blender_gather_materials_volume import export_volume
17 from .extensions.gltf2_blender_gather_materials_emission import export_emission_factor, \
18 export_emission_texture, export_emission_strength_extension
19 from .extensions.gltf2_blender_gather_materials_sheen import export_sheen
20 from .extensions.gltf2_blender_gather_materials_specular import export_specular
21 from .extensions.gltf2_blender_gather_materials_transmission import export_transmission
22 from .extensions.gltf2_blender_gather_materials_clearcoat import export_clearcoat
23 from .extensions.gltf2_blender_gather_materials_anisotropy import export_anisotropy
24 from .extensions.gltf2_blender_gather_materials_ior import export_ior
25 from .gltf2_blender_search_node_tree import \
26 has_image_node_from_socket, \
27 get_socket_from_gltf_material_node, \
28 get_socket, \
29 get_node_socket, \
30 get_material_nodes, \
31 NodeSocket, \
32 get_vertex_color_info
34 @cached
35 def get_material_cache_key(blender_material, export_settings):
36 # Use id of material
37 # Do not use bpy.types that can be unhashable
38 # Do not use material name, that can be not unique (when linked)
39 # We use here the id of original material as for apply modifier, the material has a new id
40 # So, when no modifier applied => original is the same id
41 # And when modifier applied => new one is different id, but original is still the same
42 return (
43 (id(blender_material.original),),
46 @cached_by_key(key=get_material_cache_key)
47 def gather_material(blender_material, export_settings):
48 """
49 Gather the material used by the blender primitive.
51 :param blender_material: the blender material used in the glTF primitive
52 :param export_settings:
53 :return: a glTF material
54 """
55 if not __filter_material(blender_material, export_settings):
56 return None, {"uv_info": {}, "vc_info": {'color': None, 'alpha': None, 'color_type': None, 'alpha_type': None}, "udim_info": {}}
58 # Reset exported images / textures nodes
59 export_settings['exported_texture_nodes'] = []
60 if blender_material.node_tree and blender_material.use_nodes:
61 nodes = get_material_nodes(blender_material.node_tree, [blender_material.node_tree], bpy.types.ShaderNodeTexImage)
62 else:
63 nodes = []
64 for node in nodes:
65 if node[0].get("used", None) is not None:
66 del(node[0]['used'])
68 mat_unlit, uvmap_info, vc_info, udim_info = __export_unlit(blender_material, export_settings)
69 if mat_unlit is not None:
70 export_user_extensions('gather_material_hook', export_settings, mat_unlit, blender_material)
71 return mat_unlit, {"uv_info": uvmap_info, "vc_info": vc_info, "udim_info": udim_info}
73 orm_texture = __gather_orm_texture(blender_material, export_settings)
75 emissive_factor = __gather_emissive_factor(blender_material, export_settings)
76 emissive_texture, uvmap_info_emissive, udim_info_emissive = __gather_emissive_texture(blender_material, export_settings)
77 extensions, uvmap_info_extensions, udim_info_extensions = __gather_extensions(blender_material, emissive_factor, export_settings)
78 normal_texture, uvmap_info_normal, udim_info_normal = __gather_normal_texture(blender_material, export_settings)
79 occlusion_texture, uvmap_info_occlusion, udim_occlusion = __gather_occlusion_texture(blender_material, orm_texture, export_settings)
80 pbr_metallic_roughness, uvmap_info_pbr_metallic_roughness, vc_info, udim_info_prb_mr = __gather_pbr_metallic_roughness(blender_material, orm_texture, export_settings)
82 if any([i>1.0 for i in emissive_factor or []]) is True:
83 # Strength is set on extension
84 emission_strength = max(emissive_factor)
85 emissive_factor = [f / emission_strength for f in emissive_factor]
88 material = gltf2_io.Material(
89 alpha_cutoff=__gather_alpha_cutoff(blender_material, export_settings),
90 alpha_mode=__gather_alpha_mode(blender_material, export_settings),
91 double_sided=__gather_double_sided(blender_material, extensions, export_settings),
92 emissive_factor=emissive_factor,
93 emissive_texture=emissive_texture,
94 extensions=extensions,
95 extras=__gather_extras(blender_material, export_settings),
96 name=__gather_name(blender_material, export_settings),
97 normal_texture=normal_texture,
98 occlusion_texture=occlusion_texture,
99 pbr_metallic_roughness=pbr_metallic_roughness
102 uvmap_infos = {}
103 udim_infos = {}
105 # Get all textures nodes that are not used in the material
106 if export_settings['gltf_unused_textures'] is True:
107 if blender_material.node_tree and blender_material.use_nodes:
108 nodes = get_material_nodes(blender_material.node_tree, [blender_material.node_tree], bpy.types.ShaderNodeTexImage)
109 else:
110 nodes = []
111 cpt_additional = 0
112 for node in nodes:
113 if node[0].get("used", None) is not None:
114 del(node[0]['used'])
115 continue
117 s = NodeSocket(node[0].outputs[0], node[1])
118 tex, uv_info_additional, udim_info, _ = gltf2_blender_gather_texture_info.gather_texture_info(s, (s,), export_settings)
119 if tex is not None:
120 export_settings['exported_images'][node[0].image.name] = 1 # Fully used
121 uvmap_infos.update({'additional' + str(cpt_additional): uv_info_additional})
122 udim_infos.update({'additional' + str(cpt_additional): udim_info})
123 cpt_additional += 1
124 export_settings['additional_texture_export'].append(tex)
126 # Reset
127 if blender_material.node_tree and blender_material.use_nodes:
128 nodes = get_material_nodes(blender_material.node_tree, [blender_material.node_tree], bpy.types.ShaderNodeTexImage)
129 else:
130 nodes = []
131 for node in nodes:
132 if node[0].get("used", None) is not None:
133 del(node[0]['used'])
135 uvmap_infos.update(uvmap_info_emissive)
136 uvmap_infos.update(uvmap_info_extensions)
137 uvmap_infos.update(uvmap_info_normal)
138 uvmap_infos.update(uvmap_info_occlusion)
139 uvmap_infos.update(uvmap_info_pbr_metallic_roughness)
141 udim_infos = {}
142 udim_infos.update(udim_info_prb_mr)
143 udim_infos.update(udim_info_normal)
144 udim_infos.update(udim_info_emissive)
145 udim_infos.update(udim_occlusion)
146 udim_infos.update(udim_info_extensions)
149 # If emissive is set, from an emissive node (not PBR)
150 # We need to set manually default values for
151 # pbr_metallic_roughness.baseColor
152 if material.emissive_factor is not None and get_node_socket(blender_material.node_tree, bpy.types.ShaderNodeBsdfPrincipled, "Base Color").socket is None:
153 material.pbr_metallic_roughness = gltf2_blender_gather_materials_pbr_metallic_roughness.get_default_pbr_for_emissive_node()
155 export_user_extensions('gather_material_hook', export_settings, material, blender_material)
157 # Now we have exported the material itself, we need to store some additional data
158 # This will be used when trying to export some KHR_animation_pointer
160 if len(export_settings['current_paths']) > 0:
161 export_settings['KHR_animation_pointer']['materials'][id(blender_material)] = {}
162 export_settings['KHR_animation_pointer']['materials'][id(blender_material)]['paths'] = export_settings['current_paths'].copy()
163 export_settings['KHR_animation_pointer']['materials'][id(blender_material)]['glTF_material'] = material
165 export_settings['current_paths'] = {}
167 return material, {"uv_info": uvmap_infos, "vc_info": vc_info, "udim_info": udim_infos}
170 def get_new_material_texture_shared(base, node):
171 if node is None:
172 return
173 if callable(node) is True:
174 return
175 if node.__str__().startswith('__'):
176 return
177 if type(node) in [gltf2_io.TextureInfo, gltf2_io.MaterialOcclusionTextureInfoClass, gltf2_io.MaterialNormalTextureInfoClass]:
178 node.index = base.index
179 else:
180 if hasattr(node, '__dict__'):
181 for attr, value in node.__dict__.items():
182 get_new_material_texture_shared(getattr(base, attr), value)
183 else:
184 # For extensions (on a dict)
185 if type(node).__name__ == 'dict':
186 for i in node.keys():
187 get_new_material_texture_shared(base[i], node[i])
189 def __filter_material(blender_material, export_settings):
190 return export_settings['gltf_materials']
193 def __gather_alpha_cutoff(blender_material, export_settings):
194 if blender_material.blend_method == 'CLIP':
196 path_ = {}
197 path_['length'] = 1
198 path_['path'] = "/materials/XXX/alphaCutoff"
199 export_settings['current_paths']['alpha_threshold'] = path_
201 return blender_material.alpha_threshold
202 return None
205 def __gather_alpha_mode(blender_material, export_settings):
206 if blender_material.blend_method == 'CLIP':
207 return 'MASK'
208 elif blender_material.blend_method in ['BLEND', 'HASHED']:
209 return 'BLEND'
210 return None
213 def __gather_double_sided(blender_material, extensions, export_settings):
215 # If user create a volume extension, we force double sided to False
216 if 'KHR_materials_volume' in extensions:
217 return False
219 if not blender_material.use_backface_culling:
220 return True
221 return None
224 def __gather_emissive_factor(blender_material, export_settings):
225 return export_emission_factor(blender_material, export_settings)
227 def __gather_emissive_texture(blender_material, export_settings):
228 return export_emission_texture(blender_material, export_settings)
231 def __gather_extensions(blender_material, emissive_factor, export_settings):
232 extensions = {}
234 uvmap_infos = {}
235 udim_infos = {}
237 # KHR_materials_clearcoat
238 clearcoat_extension, uvmap_info, udim_info_clearcoat = export_clearcoat(blender_material, export_settings)
239 if clearcoat_extension:
240 extensions["KHR_materials_clearcoat"] = clearcoat_extension
241 uvmap_infos.update(uvmap_info)
242 udim_infos.update(udim_info_clearcoat)
244 # KHR_materials_transmission
246 transmission_extension, uvmap_info, udim_info_transmission = export_transmission(blender_material, export_settings)
247 if transmission_extension:
248 extensions["KHR_materials_transmission"] = transmission_extension
249 uvmap_infos.update(uvmap_info)
250 udim_infos.update(udim_info_transmission)
252 # KHR_materials_emissive_strength
253 emissive_strength_extension = export_emission_strength_extension(emissive_factor, export_settings)
254 if emissive_strength_extension:
255 extensions["KHR_materials_emissive_strength"] = emissive_strength_extension
257 # KHR_materials_volume
259 volume_extension, uvmap_info, udim_info = export_volume(blender_material, export_settings)
260 if volume_extension:
261 extensions["KHR_materials_volume"] = volume_extension
262 uvmap_infos.update(uvmap_info)
263 udim_infos.update(udim_info)
265 # KHR_materials_specular
266 specular_extension, uvmap_info, udim_info = export_specular(blender_material, export_settings)
267 if specular_extension:
268 extensions["KHR_materials_specular"] = specular_extension
269 uvmap_infos.update(uvmap_info)
270 udim_infos.update(udim_info)
272 # KHR_materials_sheen
273 sheen_extension, uvmap_info, udim_info = export_sheen(blender_material, export_settings)
274 if sheen_extension:
275 extensions["KHR_materials_sheen"] = sheen_extension
276 uvmap_infos.update(uvmap_info)
277 udim_infos.update(udim_info)
279 # KHR_materials_anisotropy
280 anisotropy_extension, uvmap_info, udim_info = export_anisotropy(blender_material, export_settings)
281 if anisotropy_extension:
282 extensions["KHR_materials_anisotropy"] = anisotropy_extension
283 uvmap_infos.update(uvmap_info)
284 udim_infos.update(udim_info)
286 # KHR_materials_ior
287 # Keep this extension at the end, because we export it only if some others are exported
288 ior_extension = export_ior(blender_material, extensions, export_settings)
289 if ior_extension:
290 extensions["KHR_materials_ior"] = ior_extension
292 return extensions, uvmap_infos, udim_infos
295 def __gather_extras(blender_material, export_settings):
296 if export_settings['gltf_extras']:
297 return generate_extras(blender_material)
298 return None
301 def __gather_name(blender_material, export_settings):
302 return blender_material.name
305 def __gather_normal_texture(blender_material, export_settings):
306 normal = get_socket(blender_material.node_tree, blender_material.use_nodes, "Normal")
307 normal_texture, uvmap_info, udim_info, _ = gltf2_blender_gather_texture_info.gather_material_normal_texture_info_class(
308 normal,
309 (normal,),
310 export_settings)
312 if len(export_settings['current_texture_transform']) != 0:
313 for k in export_settings['current_texture_transform'].keys():
314 path_ = {}
315 path_['length'] = export_settings['current_texture_transform'][k]['length']
316 path_['path'] = export_settings['current_texture_transform'][k]['path'].replace("YYY", "normalTexture/extensions")
317 path_['vector_type'] = export_settings['current_texture_transform'][k]['vector_type']
318 export_settings['current_paths'][k] = path_
320 export_settings['current_texture_transform'] = {}
322 if len(export_settings['current_normal_scale']) != 0:
323 for k in export_settings['current_normal_scale'].keys():
324 path_ = {}
325 path_['length'] = export_settings['current_normal_scale'][k]['length']
326 path_['path'] = export_settings['current_normal_scale'][k]['path'].replace("YYY", "normalTexture")
327 export_settings['current_paths'][k] = path_
329 export_settings['current_normal_scale'] = {}
331 return normal_texture, {"normalTexture" : uvmap_info}, {'normalTexture': udim_info } if len(udim_info.keys()) > 0 else {}
334 def __gather_orm_texture(blender_material, export_settings):
335 # Check for the presence of Occlusion, Roughness, Metallic sharing a single image.
336 # If not fully shared, return None, so the images will be cached and processed separately.
338 occlusion = get_socket(blender_material.node_tree, blender_material.use_nodes, "Occlusion")
339 if occlusion.socket is None or not has_image_node_from_socket(occlusion, export_settings):
340 occlusion = get_socket_from_gltf_material_node(blender_material.node_tree, blender_material.use_nodes, "Occlusion")
341 if occlusion.socket is None or not has_image_node_from_socket(occlusion, export_settings):
342 return None
344 metallic_socket = get_socket(blender_material.node_tree, blender_material.use_nodes, "Metallic")
345 roughness_socket = get_socket(blender_material.node_tree, blender_material.use_nodes, "Roughness")
347 hasMetal = metallic_socket.socket is not None and has_image_node_from_socket(metallic_socket, export_settings)
348 hasRough = roughness_socket.socket is not None and has_image_node_from_socket(roughness_socket, export_settings)
350 # Warning: for default socket, do not use NodeSocket object, because it will break cache
351 # Using directlty the Blender socket object
352 if not hasMetal and not hasRough:
353 metallic_roughness = get_socket_from_gltf_material_node(blender_material.node_tree, blender_material.use_nodes, "MetallicRoughness")
354 if metallic_roughness.socket is None or not has_image_node_from_socket(metallic_roughness, export_settings):
355 return None
356 result = (occlusion, metallic_roughness)
357 elif not hasMetal:
358 result = (occlusion, roughness_socket)
359 elif not hasRough:
360 result = (occlusion, metallic_socket)
361 else:
362 result = (occlusion, roughness_socket, metallic_socket)
364 if not gltf2_blender_gather_texture_info.check_same_size_images(result, export_settings):
365 export_settings['log'].info(
366 "Occlusion and metal-roughness texture will be exported separately "
367 "(use same-sized images if you want them combined)"
369 return None
371 # Double-check this will past the filter in texture_info
372 info, _, _, _ = gltf2_blender_gather_texture_info.gather_texture_info(result[0], result, export_settings)
373 if info is None:
374 return None
376 if len(export_settings['current_texture_transform']) != 0:
377 for k in export_settings['current_texture_transform'].keys():
378 path_ = {}
379 path_['length'] = export_settings['current_texture_transform'][k]['length']
380 path_['path'] = export_settings['current_texture_transform'][k]['path'].replace("YYY", "occlusionTexture/extensions")
381 path_['vector_type'] = export_settings['current_texture_transform'][k]['vector_type']
382 export_settings['current_paths'][k] = path_
384 #This case can't happen because we are going to keep only 1 UVMap
385 export_settings['log'].warning("This case should not happen, please report a bug")
386 for k in export_settings['current_texture_transform'].keys():
387 path_ = {}
388 path_['length'] = export_settings['current_texture_transform'][k]['length']
389 path_['path'] = export_settings['current_texture_transform'][k]['path'].replace("YYY", "pbrMetallicRoughness/metallicRoughnessTexture/extensions")
390 path_['vector_type'] = export_settings['current_texture_transform'][k]['vector_type']
391 export_settings['current_paths'][k] = path_
393 export_settings['current_texture_transform'] = {}
395 return result
397 def __gather_occlusion_texture(blender_material, orm_texture, export_settings):
398 occlusion = get_socket(blender_material.node_tree, blender_material.use_nodes, "Occlusion")
399 if occlusion.socket is None:
400 occlusion = get_socket_from_gltf_material_node(blender_material.node_tree, blender_material.use_nodes, "Occlusion")
401 if occlusion.socket is None:
402 return None, {}, {}
403 occlusion_texture, uvmap_info, udim_info, _ = gltf2_blender_gather_texture_info.gather_material_occlusion_texture_info_class(
404 occlusion,
405 orm_texture or (occlusion,),
406 export_settings)
408 if len(export_settings['current_occlusion_strength']) != 0:
409 for k in export_settings['current_occlusion_strength'].keys():
410 path_ = {}
411 path_['length'] = export_settings['current_occlusion_strength'][k]['length']
412 path_['path'] = export_settings['current_occlusion_strength'][k]['path']
413 path_['reverse'] = export_settings['current_occlusion_strength'][k]['reverse']
414 export_settings['current_paths'][k] = path_
416 export_settings['current_occlusion_strength'] = {}
418 if len(export_settings['current_texture_transform']) != 0:
419 for k in export_settings['current_texture_transform'].keys():
420 path_ = {}
421 path_['length'] = export_settings['current_texture_transform'][k]['length']
422 path_['path'] = export_settings['current_texture_transform'][k]['path'].replace("YYY", "occlusionTexture/extensions")
423 path_['vector_type'] = export_settings['current_texture_transform'][k]['vector_type']
424 export_settings['current_paths'][k] = path_
426 export_settings['current_texture_transform'] = {}
428 return occlusion_texture, \
429 {"occlusionTexture" : uvmap_info}, {'occlusionTexture': udim_info } if len(udim_info.keys()) > 0 else {}
432 def __gather_pbr_metallic_roughness(blender_material, orm_texture, export_settings):
433 return gltf2_blender_gather_materials_pbr_metallic_roughness.gather_material_pbr_metallic_roughness(
434 blender_material,
435 orm_texture,
436 export_settings)
438 def __export_unlit(blender_material, export_settings):
439 gltf2_unlit = gltf2_blender_gather_materials_unlit
441 info = gltf2_unlit.detect_shadeless_material(blender_material.node_tree, blender_material.use_nodes, export_settings)
442 if info is None:
443 return None, {}, {"color": None, "alpha": None, "color_type": None, "alpha_type": None}, {}
445 base_color_texture, uvmap_info, udim_info = gltf2_unlit.gather_base_color_texture(info, export_settings)
447 vc_info = get_vertex_color_info(info.get('rgb_socket'), info.get('alpha_socket'), export_settings)
449 material = gltf2_io.Material(
450 alpha_cutoff=__gather_alpha_cutoff(blender_material, export_settings),
451 alpha_mode=__gather_alpha_mode(blender_material, export_settings),
452 double_sided=__gather_double_sided(blender_material, {}, export_settings),
453 extensions={"KHR_materials_unlit": Extension("KHR_materials_unlit", {}, required=False)},
454 extras=__gather_extras(blender_material, export_settings),
455 name=__gather_name(blender_material, export_settings),
456 emissive_factor=None,
457 emissive_texture=None,
458 normal_texture=None,
459 occlusion_texture=None,
461 pbr_metallic_roughness=gltf2_io.MaterialPBRMetallicRoughness(
462 base_color_factor=gltf2_unlit.gather_base_color_factor(info, export_settings),
463 base_color_texture=base_color_texture,
464 metallic_factor=0.0,
465 roughness_factor=0.9,
466 metallic_roughness_texture=None,
467 extensions=None,
468 extras=None,
472 export_user_extensions('gather_material_unlit_hook', export_settings, material, blender_material)
474 # Now we have exported the material itself, we need to store some additional data
475 # This will be used when trying to export some KHR_animation_pointer
477 if len(export_settings['current_paths']) > 0:
478 export_settings['KHR_animation_pointer']['materials'][id(blender_material)] = {}
479 export_settings['KHR_animation_pointer']['materials'][id(blender_material)]['paths'] = export_settings['current_paths'].copy()
480 export_settings['KHR_animation_pointer']['materials'][id(blender_material)]['glTF_material'] = material
482 export_settings['current_paths'] = {}
484 return material, uvmap_info, vc_info, udim_info
486 def get_active_uvmap_index(blender_mesh):
487 # retrieve active render UVMap
488 active_uvmap_idx = 0
489 for i in range(len(blender_mesh.uv_layers)):
490 if blender_mesh.uv_layers[i].active_render is True:
491 active_uvmap_idx = i
492 break
493 return active_uvmap_idx
496 def get_final_material(mesh, blender_material, attr_indices, base_material, uvmap_info, export_settings):
498 # First, we need to calculate all index of UVMap
500 indices = {}
501 additional_indices = 0
503 for m, v in uvmap_info.items():
505 if m.startswith("additional") and additional_indices <= int(m[10:]):
506 additional_indices = +1
508 if not 'type' in v.keys():
509 continue
511 if v['type'] == 'Fixed':
512 i = mesh.uv_layers.find(v['value'])
513 if i >= 0:
514 indices[m] = i
515 else:
516 # Using active index
517 indices[m] = get_active_uvmap_index(mesh)
518 elif v['type'] == 'Active':
519 indices[m] = get_active_uvmap_index(mesh)
520 elif v['type'] == "Attribute":
521 indices[m] = attr_indices[v['value']]
523 # Now we have all needed indices, let's create a set that can be used for caching, so containing all possible textures
524 all_textures = get_all_textures(additional_indices)
526 caching_indices = []
527 for tex in all_textures:
528 caching_indices.append(indices.get(tex, None))
530 caching_indices = [i if i != 0 else None for i in caching_indices]
531 caching_indices = tuple(caching_indices)
533 material = __get_final_material_with_indices(blender_material, base_material, caching_indices, export_settings)
535 return material
538 @cached
539 def caching_material_tex_indices(blender_material, material, caching_indices, export_settings):
540 return (
541 (id(blender_material),),
542 (caching_indices,)
545 @cached_by_key(key=caching_material_tex_indices)
546 def __get_final_material_with_indices(blender_material, base_material, caching_indices, export_settings):
548 if base_material is None:
549 return None
551 if all([i is None for i in caching_indices]):
552 return base_material
554 material = deepcopy(base_material)
555 get_new_material_texture_shared(base_material, material)
557 for tex, ind in zip(get_all_textures(len(caching_indices) - len(get_all_textures())), caching_indices):
559 if ind is None:
560 continue
562 # Need to check if texture is not None, because it can be the case for UDIM on non managed UDIM textures
563 if tex == "emissiveTexture":
564 if material.emissive_texture: material.emissive_texture.tex_coord = ind
565 elif tex == "normalTexture":
566 if material.normal_texture: material.normal_texture.tex_coord = ind
567 elif tex == "occlusionTexture":
568 if material.occlusion_texture: material.occlusion_texture.tex_coord = ind
569 elif tex == "baseColorTexture":
570 if material.pbr_metallic_roughness.base_color_texture: material.pbr_metallic_roughness.base_color_texture.tex_coord = ind
571 elif tex == "metallicRoughnessTexture":
572 if material.pbr_metallic_roughness.metallic_roughness_texture: material.pbr_metallic_roughness.metallic_roughness_texture.tex_coord = ind
573 elif tex == "clearcoatTexture":
574 if material.extensions["KHR_materials_clearcoat"].extension['clearcoatTexture']: material.extensions["KHR_materials_clearcoat"].extension['clearcoatTexture'].tex_coord = ind
575 elif tex == "clearcoatRoughnessTexture":
576 if material.extensions["KHR_materials_clearcoat"].extension['clearcoatRoughnessTexture']: material.extensions["KHR_materials_clearcoat"].extension['clearcoatRoughnessTexture'].tex_coord = ind
577 elif tex == "clearcoatNormalTexture":
578 if material.extensions["KHR_materials_clearcoat"].extension['clearcoatNormalTexture']: material.extensions["KHR_materials_clearcoat"].extension['clearcoatNormalTexture'].tex_coord = ind
579 elif tex == "transmissionTexture":
580 if material.extensions["KHR_materials_transmission"].extension['transmissionTexture']: material.extensions["KHR_materials_transmission"].extension['transmissionTexture'].tex_coord = ind
581 elif tex == "specularTexture":
582 if material.extensions["KHR_materials_specular"].extension['specularTexture']: material.extensions["KHR_materials_specular"].extension['specularTexture'].tex_coord = ind
583 elif tex == "specularColorTexture":
584 if material.extensions["KHR_materials_specular"].extension['specularColorTexture']: material.extensions["KHR_materials_specular"].extension['specularColorTexture'].tex_coord = ind
585 elif tex == "sheenColorTexture":
586 if material.extensions["KHR_materials_sheen"].extension['sheenColorTexture']: material.extensions["KHR_materials_sheen"].extension['sheenColorTexture'].tex_coord = ind
587 elif tex == "sheenRoughnessTexture":
588 if material.extensions["KHR_materials_sheen"].extension['sheenRoughnessTexture']: material.extensions["KHR_materials_sheen"].extension['sheenRoughnessTexture'].tex_coord = ind
589 elif tex == "thicknessTexture":
590 if material.extensions["KHR_materials_volume"].extension['thicknessTexture']: material.extensions["KHR_materials_volume"].extension['thicknessTexture'].tex_ccord = ind
591 elif tex == "anisotropyTexture":
592 if material.extensions["KHR_materials_anisotropy"].extension['anisotropyTexture']: material.extensions["KHR_materials_anisotropy"].extension['anisotropyTexture'].tex_coord = ind
593 elif tex.startswith("additional"):
594 export_settings['additional_texture_export'][export_settings['additional_texture_export_current_idx'] + int(tex[10:])].tex_coord = ind
595 else:
596 export_settings['log'].error("some Textures tex coord are not managed")
598 export_settings['additional_texture_export_current_idx'] = len(export_settings['additional_texture_export'])
600 return material
603 def get_material_from_idx(material_idx, materials, export_settings):
604 mat = None
605 if export_settings['gltf_materials'] == "EXPORT" and material_idx is not None:
606 if materials:
607 i = material_idx if material_idx < len(materials) else -1
608 mat = materials[i]
609 return mat
611 def get_base_material(material_idx, materials, export_settings):
613 export_settings['current_paths'] = {}
615 material = None
616 material_info = {
617 "uv_info": {},
618 "vc_info": {
619 "color": None,
620 "alpha": None,
621 "color_type": None,
622 "alpha_type": None
624 "udim_info": {}
627 mat = get_material_from_idx(material_idx, materials, export_settings)
628 if mat is not None:
629 material, material_info = gather_material(
630 mat,
631 export_settings
634 if material is None:
635 # If no material, the mesh can still have vertex color
636 # So, retrieving it
637 material_info["vc_info"] = {"color_type": "active", "alpha_type": "active"}
639 return material, material_info
641 def get_all_textures(idx=0):
642 # Make sure to have all texture here, always in same order
643 tab = []
645 tab.append("emissiveTexture")
646 tab.append("normalTexture")
647 tab.append("occlusionTexture")
648 tab.append("baseColorTexture")
649 tab.append("metallicRoughnessTexture")
650 tab.append("clearcoatTexture")
651 tab.append("clearcoatRoughnessTexture")
652 tab.append("clearcoatNormalTexture")
653 tab.append("transmissionTexture")
654 tab.append("specularTexture")
655 tab.append("specularColorTexture")
656 tab.append("sheenColorTexture")
657 tab.append("sheenRoughnessTexture")
658 tab.append("thicknessTexture")
659 tab.append("anisotropyTexture")
661 for i in range(idx):
662 tab.append("additional" + str(i))
664 return tab