diff options
author | Julien Duroure <julien.duroure@gmail.com> | 2020-01-29 23:57:22 +0300 |
---|---|---|
committer | Julien Duroure <julien.duroure@gmail.com> | 2020-01-29 23:57:22 +0300 |
commit | 2caaf64ab10be6f03e234fa5b533e341512fbed5 (patch) | |
tree | 887f6d0d7c58939c9558c81407486d38072f9d47 /io_scene_gltf2/blender/imp/gltf2_blender_material.py | |
parent | e88c7ee2a7c091520efe006795817638cd4dcbb0 (diff) |
glTF importer: rewrite material import
Diffstat (limited to 'io_scene_gltf2/blender/imp/gltf2_blender_material.py')
-rwxr-xr-x | io_scene_gltf2/blender/imp/gltf2_blender_material.py | 187 |
1 files changed, 52 insertions, 135 deletions
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_material.py b/io_scene_gltf2/blender/imp/gltf2_blender_material.py index 8d5dd245..c2b48c46 100755 --- a/io_scene_gltf2/blender/imp/gltf2_blender_material.py +++ b/io_scene_gltf2/blender/imp/gltf2_blender_material.py @@ -15,16 +15,9 @@ import bpy from ..com.gltf2_blender_extras import set_extras -from .gltf2_blender_pbrMetallicRoughness import BlenderPbr -from .gltf2_blender_KHR_materials_pbrSpecularGlossiness import BlenderKHR_materials_pbrSpecularGlossiness -from .gltf2_blender_KHR_materials_unlit import BlenderKHR_materials_unlit -from .gltf2_blender_map_emissive import BlenderEmissiveMap -from .gltf2_blender_map_normal import BlenderNormalMap -from .gltf2_blender_map_occlusion import BlenderOcclusionMap -from ..com.gltf2_blender_material_helpers import get_output_surface_input -from ..com.gltf2_blender_material_helpers import get_preoutput_node_output -from ..com.gltf2_blender_material_helpers import get_base_color_node -from ...io.com.gltf2_io import MaterialPBRMetallicRoughness +from .gltf2_blender_pbrMetallicRoughness import MaterialHelper, pbr_metallic_roughness +from .gltf2_blender_KHR_materials_pbrSpecularGlossiness import pbr_specular_glossiness +from .gltf2_blender_KHR_materials_unlit import unlit class BlenderMaterial(): @@ -37,141 +30,65 @@ class BlenderMaterial(): """Material creation.""" pymaterial = gltf.data.materials[material_idx] - if vertex_color is None: - if pymaterial.name is not None: - name = pymaterial.name - else: - name = "Material_" + str(material_idx) - else: - if pymaterial.name is not None: - name = pymaterial.name + "_" + vertex_color - else: - name = "Material_" + str(material_idx) + "_" + vertex_color + name = pymaterial.name + if name is None: + name = "Material_" + str(material_idx) + if vertex_color is not None: + name += "_" + vertex_color mat = bpy.data.materials.new(name) pymaterial.blender_material[vertex_color] = mat.name set_extras(mat, pymaterial.extras) + BlenderMaterial.set_double_sided(pymaterial, mat) + BlenderMaterial.set_alpha_mode(pymaterial, mat) + BlenderMaterial.set_viewport_color(pymaterial, mat, vertex_color) - mat.use_backface_culling = (pymaterial.double_sided != True) + mat.use_nodes = True + while mat.node_tree.nodes: # clear all nodes + mat.node_tree.nodes.remove(mat.node_tree.nodes[0]) + + mh = MaterialHelper(gltf, pymaterial, mat, vertex_color) - ignore_map = False - - if pymaterial.extensions is not None : - if 'KHR_materials_unlit' in pymaterial.extensions.keys(): - ignore_map = True - BlenderKHR_materials_unlit.create( - gltf, material_idx, - pymaterial.extensions['KHR_materials_unlit'], - mat.name, - vertex_color - ) - elif 'KHR_materials_pbrSpecularGlossiness' in pymaterial.extensions.keys(): - BlenderKHR_materials_pbrSpecularGlossiness.create( - gltf, pymaterial.extensions['KHR_materials_pbrSpecularGlossiness'], mat.name, vertex_color - ) + exts = pymaterial.extensions or {} + if 'KHR_materials_unlit' in exts: + unlit(mh) + elif 'KHR_materials_pbrSpecularGlossiness' in exts: + pbr_specular_glossiness(mh) else: - # create pbr material - if pymaterial.pbr_metallic_roughness is None: - # If no pbr material is set, we need to apply all default of pbr - pbr = {} - pbr["baseColorFactor"] = [1.0, 1.0, 1.0, 1.0] - pbr["metallicFactor"] = 1.0 - pbr["roughnessFactor"] = 1.0 - pymaterial.pbr_metallic_roughness = MaterialPBRMetallicRoughness.from_dict(pbr) - pymaterial.pbr_metallic_roughness.color_type = gltf.SIMPLE - pymaterial.pbr_metallic_roughness.metallic_type = gltf.SIMPLE - - BlenderPbr.create(gltf, pymaterial.pbr_metallic_roughness, mat.name, vertex_color) - - if ignore_map == False: - # add emission map if needed - if pymaterial.emissive_texture is not None: - BlenderEmissiveMap.create(gltf, material_idx, vertex_color) - elif pymaterial.emissive_factor is not None: - # add emissive factor only if there is not emissive texture - BlenderEmissiveMap.create(gltf, material_idx, vertex_color, factor_only=True) - - - # add normal map if needed - if pymaterial.normal_texture is not None: - BlenderNormalMap.create(gltf, material_idx, vertex_color) - - # add occlusion map if needed - # will be pack, but not used - if pymaterial.occlusion_texture is not None: - BlenderOcclusionMap.create(gltf, material_idx, vertex_color) - - if pymaterial.alpha_mode is not None and pymaterial.alpha_mode != 'OPAQUE': - BlenderMaterial.blender_alpha(gltf, material_idx, vertex_color, pymaterial.alpha_mode) + pbr_metallic_roughness(mh) @staticmethod - def blender_alpha(gltf, material_idx, vertex_color, alpha_mode): - """Set alpha.""" - pymaterial = gltf.data.materials[material_idx] - material = bpy.data.materials[pymaterial.blender_material[vertex_color]] + def set_double_sided(pymaterial, mat): + mat.use_backface_culling = (pymaterial.double_sided != True) - # Set alpha value in material + @staticmethod + def set_alpha_mode(pymaterial, mat): + alpha_mode = pymaterial.alpha_mode if alpha_mode == 'BLEND': - material.blend_method = 'BLEND' - elif alpha_mode == "MASK": - material.blend_method = 'CLIP' - alpha_cutoff = pymaterial.alpha_cutoff if pymaterial.alpha_cutoff is not None else 0.5 - material.alpha_threshold = alpha_cutoff - - node_tree = material.node_tree - # Add nodes for basic transparency - # Add mix shader between output and Principled BSDF - trans = node_tree.nodes.new('ShaderNodeBsdfTransparent') - trans.location = 750, -500 - mix = node_tree.nodes.new('ShaderNodeMixShader') - mix.location = 1000, 0 - - output_surface_input = get_output_surface_input(node_tree) - preoutput_node_output = get_preoutput_node_output(node_tree) - - link = output_surface_input.links[0] - node_tree.links.remove(link) - - # PBR => Mix input 1 - node_tree.links.new(preoutput_node_output, mix.inputs[1]) - - # Trans => Mix input 2 - node_tree.links.new(trans.outputs['BSDF'], mix.inputs[2]) - - # Mix => Output - node_tree.links.new(mix.outputs['Shader'], output_surface_input) - - # alpha blend factor - add = node_tree.nodes.new('ShaderNodeMath') - add.operation = 'ADD' - add.location = 750, -250 - - diffuse_factor = 1.0 - if pymaterial.extensions is not None and 'KHR_materials_pbrSpecularGlossiness' in pymaterial.extensions: - diffuse_factor = pymaterial.extensions['KHR_materials_pbrSpecularGlossiness']['diffuseFactor'][3] - elif pymaterial.pbr_metallic_roughness: - diffuse_factor = pymaterial.pbr_metallic_roughness.base_color_factor[3] - - add.inputs[0].default_value = abs(1.0 - diffuse_factor) - add.inputs[1].default_value = 0.0 - node_tree.links.new(add.outputs['Value'], mix.inputs[0]) - - # Take diffuse texture alpha into account if any - diffuse_texture = get_base_color_node(node_tree) - if diffuse_texture: - inverter = node_tree.nodes.new('ShaderNodeInvert') - inverter.location = 250, -250 - inverter.inputs[1].default_value = (1.0, 1.0, 1.0, 1.0) - node_tree.links.new(diffuse_texture.outputs['Alpha'], inverter.inputs[0]) - - mult = node_tree.nodes.new('ShaderNodeMath') - mult.operation = 'MULTIPLY' if pymaterial.alpha_mode == 'BLEND' else 'GREATER_THAN' - mult.location = 500, -250 - # Note that `1.0 - pymaterial.alpha_cutoff` is used due to the invert node above. - alpha_cutoff = 1.0 if pymaterial.alpha_mode == 'BLEND' else \ - 1.0 - pymaterial.alpha_cutoff if pymaterial.alpha_cutoff is not None else 0.5 - mult.inputs[1].default_value = alpha_cutoff - node_tree.links.new(inverter.outputs['Color'], mult.inputs[0]) - node_tree.links.new(mult.outputs['Value'], add.inputs[0]) + mat.blend_method = 'BLEND' + elif alpha_mode == 'MASK': + mat.blend_method = 'CLIP' + alpha_cutoff = pymaterial.alpha_cutoff + alpha_cutoff = alpha_cutoff if alpha_cutoff is not None else 0.5 + mat.alpha_threshold = alpha_cutoff + + @staticmethod + def set_viewport_color(pymaterial, mat, vertex_color): + # If there is no texture and no vertex color, use the base color as + # the color for the Solid view. + if vertex_color: + return + + exts = pymaterial.extensions or {} + if 'KHR_materials_pbrSpecularGlossiness' in exts: + # TODO + return + else: + pbr = pymaterial.pbr_metallic_roughness + if pbr is None or pbr.base_color_texture is not None: + return + color = pbr.base_color_factor or [1, 1, 1, 1] + + mat.diffuse_color = color |