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:
Diffstat (limited to 'io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py')
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py160
1 files changed, 133 insertions, 27 deletions
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 04129996..402e06fa 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2018-2021 The glTF-Blender-IO authors.
+from copy import deepcopy
import bpy
from io_scene_gltf2.blender.exp.gltf2_blender_gather_cache import cached, cached_by_key
@@ -17,14 +18,17 @@ from io_scene_gltf2.io.exp.gltf2_io_user_extensions import export_user_extension
from io_scene_gltf2.io.com.gltf2_io_debug import print_console
@cached
-def get_material_cache_key(blender_material, export_settings):
+def get_material_cache_key(blender_material, active_uvmap_index, export_settings):
# Use id of material
# Do not use bpy.types that can be unhashable
# Do not use material name, that can be not unique (when linked)
- return ((id(blender_material),))
+ return (
+ (id(blender_material),),
+ (active_uvmap_index,)
+ )
@cached_by_key(key=get_material_cache_key)
-def gather_material(blender_material, export_settings):
+def gather_material(blender_material, active_uvmap_index, export_settings):
"""
Gather the material used by the blender primitive.
@@ -35,26 +39,79 @@ def gather_material(blender_material, export_settings):
if not __filter_material(blender_material, export_settings):
return None
- mat_unlit = __gather_material_unlit(blender_material, export_settings)
+ mat_unlit = __gather_material_unlit(blender_material, active_uvmap_index, export_settings)
if mat_unlit is not None:
return mat_unlit
orm_texture = __gather_orm_texture(blender_material, export_settings)
- material = gltf2_io.Material(
+ emissive_texture, uvmap_actives_emissive_texture = __gather_emissive_texture(blender_material, export_settings)
+ extensions, uvmap_actives_extensions = __gather_extensions(blender_material, export_settings)
+ normal_texture, uvmap_actives_normal_texture = __gather_normal_texture(blender_material, export_settings)
+ occlusion_texture, uvmap_actives_occlusion_texture = __gather_occlusion_texture(blender_material, orm_texture, export_settings)
+ pbr_metallic_roughness, uvmap_actives_pbr_metallic_roughness = __gather_pbr_metallic_roughness(blender_material, orm_texture, export_settings)
+
+ base_material = gltf2_io.Material(
alpha_cutoff=__gather_alpha_cutoff(blender_material, export_settings),
alpha_mode=__gather_alpha_mode(blender_material, export_settings),
double_sided=__gather_double_sided(blender_material, export_settings),
emissive_factor=__gather_emissive_factor(blender_material, export_settings),
- emissive_texture=__gather_emissive_texture(blender_material, export_settings),
- extensions=__gather_extensions(blender_material, export_settings),
+ emissive_texture=emissive_texture,
+ extensions=extensions,
extras=__gather_extras(blender_material, export_settings),
name=__gather_name(blender_material, export_settings),
- normal_texture=__gather_normal_texture(blender_material, export_settings),
- occlusion_texture=__gather_occlusion_texture(blender_material, orm_texture, export_settings),
- pbr_metallic_roughness=__gather_pbr_metallic_roughness(blender_material, orm_texture, export_settings)
+ normal_texture=normal_texture,
+ occlusion_texture=occlusion_texture,
+ pbr_metallic_roughness=pbr_metallic_roughness
)
+
+ # merge all uvmap_actives
+ uvmap_actives = []
+ if uvmap_actives_emissive_texture:
+ uvmap_actives.extend(uvmap_actives_emissive_texture)
+ if uvmap_actives_extensions:
+ uvmap_actives.extend(uvmap_actives_extensions)
+ if uvmap_actives_normal_texture:
+ uvmap_actives.extend(uvmap_actives_normal_texture)
+ if uvmap_actives_occlusion_texture:
+ uvmap_actives.extend(uvmap_actives_occlusion_texture)
+ if uvmap_actives_pbr_metallic_roughness:
+ uvmap_actives.extend(uvmap_actives_pbr_metallic_roughness)
+
+ # Because some part of material are shared (eg pbr_metallic_roughness), we must copy the material
+ # Texture must be shared, but not TextureInfo
+ material = deepcopy(base_material)
+ __get_new_material_texture_shared(base_material, material)
+
+ active_uvmap_index = active_uvmap_index if active_uvmap_index != 0 else None
+
+ for tex in uvmap_actives:
+ if tex == "emissiveTexture":
+ material.emissive_texture.tex_coord = active_uvmap_index
+ elif tex == "normalTexture":
+ material.normal_texture.tex_coord = active_uvmap_index
+ elif tex == "occlusionTexture":
+ material.occlusion_texture.tex_coord = active_uvmap_index
+ elif tex == "baseColorTexture":
+ material.pbr_metallic_roughness.base_color_texture.tex_coord = active_uvmap_index
+ elif tex == "metallicRoughnessTexture":
+ material.pbr_metallic_roughness.metallic_roughness_texture.tex_coord = active_uvmap_index
+ elif tex == "clearcoatTexture":
+ material.extensions["KHR_materials_clearcoat"].extension['clearcoatTexture'].tex_coord = active_uvmap_index
+ elif tex == "clearcoatRoughnessTexture":
+ material.extensions["KHR_materials_clearcoat"].extension['clearcoatRoughnessTexture'].tex_coord = active_uvmap_index
+ elif tex == "clearcoatNormalTexture": #TODO not tested yet
+ material.extensions["KHR_materials_clearcoat"].extension['clearcoatNormalTexture'].tex_coord = active_uvmap_index
+ elif tex == "transmissionTexture": #TODO not tested yet
+ material.extensions["KHR_materials_transmission"].extension['transmissionTexture'].tex_coord = active_uvmap_index
+
+ # If material is not using active UVMap, we need to return the same material,
+ # Even if multiples meshes are using different active UVMap
+ if len(uvmap_actives) == 0 and active_uvmap_index != -1:
+ material = gather_material(blender_material, -1, export_settings)
+
+
# If emissive is set, from an emissive node (not PBR)
# We need to set manually default values for
# pbr_metallic_roughness.baseColor
@@ -80,6 +137,25 @@ def gather_material(blender_material, export_settings):
# 'material'] + ' not found. Please assign glTF 2.0 material or enable Blinn-Phong material in export.')
+def __get_new_material_texture_shared(base, node):
+ if node is None:
+ return
+ if callable(node) is True:
+ return
+ if node.__str__().startswith('__'):
+ return
+ if type(node) in [gltf2_io.TextureInfo, gltf2_io.MaterialOcclusionTextureInfoClass, gltf2_io.MaterialNormalTextureInfoClass]:
+ node.index = base.index
+ else:
+ if hasattr(node, '__dict__'):
+ for attr, value in node.__dict__.items():
+ __get_new_material_texture_shared(getattr(base, attr), value)
+ else:
+ # For extensions (on a dict)
+ if type(node).__name__ == 'dict':
+ for i in node.keys():
+ __get_new_material_texture_shared(base[i], node[i])
+
def __filter_material(blender_material, export_settings):
return export_settings[gltf2_blender_export_keys.MATERIALS]
@@ -155,17 +231,20 @@ def __gather_emissive_texture(blender_material, export_settings):
emissive = gltf2_blender_get.get_socket(blender_material, "Emissive")
if emissive is None:
emissive = gltf2_blender_get.get_socket_old(blender_material, "Emissive")
- return gltf2_blender_gather_texture_info.gather_texture_info(emissive, (emissive,), export_settings)
+ emissive_texture, use_actives_uvmap_emissive = gltf2_blender_gather_texture_info.gather_texture_info(emissive, (emissive,), export_settings)
+ return emissive_texture, ["emissiveTexture"] if use_actives_uvmap_emissive else None
def __gather_extensions(blender_material, export_settings):
extensions = {}
# KHR_materials_clearcoat
+ actives_uvmaps = []
- clearcoat_extension = __gather_clearcoat_extension(blender_material, export_settings)
+ clearcoat_extension, use_actives_uvmap_clearcoat = __gather_clearcoat_extension(blender_material, export_settings)
if clearcoat_extension:
extensions["KHR_materials_clearcoat"] = clearcoat_extension
+ actives_uvmaps.extend(use_actives_uvmap_clearcoat)
# KHR_materials_transmission
@@ -173,7 +252,7 @@ def __gather_extensions(blender_material, export_settings):
if transmission_extension:
extensions["KHR_materials_transmission"] = transmission_extension
- return extensions if extensions else None
+ return extensions, actives_uvmaps if extensions else None
def __gather_extras(blender_material, export_settings):
@@ -190,10 +269,11 @@ def __gather_normal_texture(blender_material, export_settings):
normal = gltf2_blender_get.get_socket(blender_material, "Normal")
if normal is None:
normal = gltf2_blender_get.get_socket_old(blender_material, "Normal")
- return gltf2_blender_gather_texture_info.gather_material_normal_texture_info_class(
+ normal_texture, use_active_uvmap_normal = gltf2_blender_gather_texture_info.gather_material_normal_texture_info_class(
normal,
(normal,),
export_settings)
+ return normal_texture, ["normalTexture"] if use_active_uvmap_normal else None
def __gather_orm_texture(blender_material, export_settings):
@@ -231,7 +311,7 @@ def __gather_orm_texture(blender_material, export_settings):
return None
# Double-check this will past the filter in texture_info
- info = gltf2_blender_gather_texture_info.gather_texture_info(result[0], result, export_settings)
+ info, info_use_active_uvmap = gltf2_blender_gather_texture_info.gather_texture_info(result[0], result, export_settings)
if info is None:
return None
@@ -241,10 +321,11 @@ def __gather_occlusion_texture(blender_material, orm_texture, export_settings):
occlusion = gltf2_blender_get.get_socket(blender_material, "Occlusion")
if occlusion is None:
occlusion = gltf2_blender_get.get_socket_old(blender_material, "Occlusion")
- return gltf2_blender_gather_texture_info.gather_material_occlusion_texture_info_class(
+ occlusion_texture, use_active_uvmap_occlusion = gltf2_blender_gather_texture_info.gather_material_occlusion_texture_info_class(
occlusion,
orm_texture or (occlusion,),
export_settings)
+ return occlusion_texture, ["occlusionTexture"] if use_active_uvmap_occlusion else None
def __gather_pbr_metallic_roughness(blender_material, orm_texture, export_settings):
@@ -284,7 +365,7 @@ def __gather_clearcoat_extension(blender_material, export_settings):
clearcoat_enabled = True
if not clearcoat_enabled:
- return None
+ return None, None
if isinstance(clearcoat_roughness_socket, bpy.types.NodeSocket) and not clearcoat_roughness_socket.is_linked:
clearcoat_extension['clearcoatRoughnessFactor'] = clearcoat_roughness_socket.default_value
@@ -302,28 +383,38 @@ def __gather_clearcoat_extension(blender_material, export_settings):
elif has_clearcoat_roughness_texture:
clearcoat_roughness_slots = (clearcoat_roughness_socket,)
+ use_actives_uvmaps = []
+
if len(clearcoat_roughness_slots) > 0:
if has_clearcoat_texture:
- clearcoat_extension['clearcoatTexture'] = gltf2_blender_gather_texture_info.gather_texture_info(
+ clearcoat_texture, clearcoat_texture_use_active_uvmap = gltf2_blender_gather_texture_info.gather_texture_info(
clearcoat_socket,
clearcoat_roughness_slots,
export_settings,
)
+ clearcoat_extension['clearcoatTexture'] = clearcoat_texture
+ if clearcoat_texture_use_active_uvmap:
+ use_actives_uvmaps.append("clearcoatTexture")
if has_clearcoat_roughness_texture:
- clearcoat_extension['clearcoatRoughnessTexture'] = gltf2_blender_gather_texture_info.gather_texture_info(
+ clearcoat_roughness_texture, clearcoat_roughness_texture_use_active_uvmap = gltf2_blender_gather_texture_info.gather_texture_info(
clearcoat_roughness_socket,
clearcoat_roughness_slots,
export_settings,
)
-
+ clearcoat_extension['clearcoatRoughnessTexture'] = clearcoat_roughness_texture
+ if clearcoat_roughness_texture_use_active_uvmap:
+ use_actives_uvmaps.append("clearcoatRoughnessTexture")
if __has_image_node_from_socket(clearcoat_normal_socket):
- clearcoat_extension['clearcoatNormalTexture'] = gltf2_blender_gather_texture_info.gather_material_normal_texture_info_class(
+ clearcoat_normal_texture, clearcoat_normal_texture_use_active_uvmap = gltf2_blender_gather_texture_info.gather_material_normal_texture_info_class(
clearcoat_normal_socket,
(clearcoat_normal_socket,),
export_settings
)
+ clearcoat_extension['clearcoatNormalTexture'] = clearcoat_normal_texture
+ if clearcoat_normal_texture_use_active_uvmap:
+ use_actives_uvmaps.append("clearcoatNormalTexture")
- return Extension('KHR_materials_clearcoat', clearcoat_extension, False)
+ return Extension('KHR_materials_clearcoat', clearcoat_extension, False), use_actives_uvmaps
def __gather_transmission_extension(blender_material, export_settings):
transmission_enabled = False
@@ -350,7 +441,7 @@ def __gather_transmission_extension(blender_material, export_settings):
transmission_slots = (transmission_socket,)
if len(transmission_slots) > 0:
- combined_texture = gltf2_blender_gather_texture_info.gather_texture_info(
+ combined_texture, use_active_uvmap = gltf2_blender_gather_texture_info.gather_texture_info(
transmission_socket,
transmission_slots,
export_settings,
@@ -358,17 +449,19 @@ def __gather_transmission_extension(blender_material, export_settings):
if has_transmission_texture:
transmission_extension['transmissionTexture'] = combined_texture
- return Extension('KHR_materials_transmission', transmission_extension, False)
+ return Extension('KHR_materials_transmission', transmission_extension, False), ["transmissionTexture"] if use_active_uvmap else []
-def __gather_material_unlit(blender_material, export_settings):
+def __gather_material_unlit(blender_material, active_uvmap_index, export_settings):
gltf2_unlit = gltf2_blender_gather_materials_unlit
info = gltf2_unlit.detect_shadeless_material(blender_material, export_settings)
if info is None:
return None
- material = gltf2_io.Material(
+ base_color_texture, use_active_uvmap = gltf2_unlit.gather_base_color_texture(info, export_settings)
+
+ base_material = gltf2_io.Material(
alpha_cutoff=__gather_alpha_cutoff(blender_material, export_settings),
alpha_mode=__gather_alpha_mode(blender_material, export_settings),
double_sided=__gather_double_sided(blender_material, export_settings),
@@ -382,7 +475,7 @@ def __gather_material_unlit(blender_material, export_settings):
pbr_metallic_roughness=gltf2_io.MaterialPBRMetallicRoughness(
base_color_factor=gltf2_unlit.gather_base_color_factor(info, export_settings),
- base_color_texture=gltf2_unlit.gather_base_color_texture(info, export_settings),
+ base_color_texture=base_color_texture,
metallic_factor=0.0,
roughness_factor=0.9,
metallic_roughness_texture=None,
@@ -391,6 +484,19 @@ def __gather_material_unlit(blender_material, export_settings):
)
)
+ if use_active_uvmap is not None:
+ # Because some part of material are shared (eg pbr_metallic_roughness), we must copy the material
+ # Texture must be shared, but not TextureInfo
+ material = deepcopy(base_material)
+ __get_new_material_texture_shared(base_material, material)
+ material.pbr_metallic_roughness.base_color_texture.tex_coord = active_uvmap_index
+ elif use_active_uvmap is None and active_uvmap_index != -1:
+ # If material is not using active UVMap, we need to return the same material,
+ # Even if multiples meshes are using different active UVMap
+ material = gather_material(blender_material, -1, export_settings)
+ else:
+ material = base_material
+
export_user_extensions('gather_material_unlit_hook', export_settings, material, blender_material)
return material