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/imp')
-rw-r--r--io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_ior.py12
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_pbrSpecularGlossiness.py17
-rw-r--r--io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_sheen.py88
-rw-r--r--io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_specular.py356
-rw-r--r--io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_transmission.py64
-rw-r--r--io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_unlit.py5
-rw-r--r--io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_volume.py82
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_gltf.py28
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_image.py2
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_material.py5
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_mesh.py56
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_pbrMetallicRoughness.py218
-rw-r--r--io_scene_gltf2/blender/imp/gltf2_blender_texture.py19
13 files changed, 914 insertions, 38 deletions
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_ior.py b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_ior.py
new file mode 100644
index 00000000..ab5b2e7e
--- /dev/null
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_ior.py
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: Apache-2.0
+# Copyright 2018-2021 The glTF-Blender-IO authors.
+
+from ...io.com.gltf2_io_constants import GLTF_IOR
+
+def ior(mh, ior_socket):
+ try:
+ ext = mh.pymat.extensions['KHR_materials_ior']
+ except Exception:
+ return
+ ior = ext.get('ior', GLTF_IOR)
+ ior_socket.default_value = ior
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_pbrSpecularGlossiness.py b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_pbrSpecularGlossiness.py
index bed63f7f..19a394b9 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_pbrSpecularGlossiness.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_pbrSpecularGlossiness.py
@@ -22,19 +22,24 @@ def pbr_specular_glossiness(mh):
mh.node_tree.links.new(add_node.inputs[0], glossy_node.outputs[0])
mh.node_tree.links.new(add_node.inputs[1], diffuse_node.outputs[0])
- emission_socket, alpha_socket = make_output_nodes(
+ emission_socket, alpha_socket, _, _ = make_output_nodes(
mh,
location=(370, 250),
+ additional_location=None, #No additional location needed for SpecGloss
shader_socket=add_node.outputs[0],
make_emission_socket=mh.needs_emissive(),
make_alpha_socket=not mh.is_opaque(),
+ make_volume_socket=None, # No possible to have KHR_materials_volume with specular/glossiness
+ make_velvet_socket=None # No possible to have KHR_materials_volume with specular/glossiness
)
- emission(
- mh,
- location=(-200, 860),
- color_socket=emission_socket,
- )
+ if emission_socket:
+ emission(
+ mh,
+ location=(-200, 860),
+ color_socket=emission_socket,
+ strength_socket=emission_socket.node.inputs['Strength']
+ )
base_color(
mh,
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_sheen.py b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_sheen.py
new file mode 100644
index 00000000..aa5cef75
--- /dev/null
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_sheen.py
@@ -0,0 +1,88 @@
+# SPDX-License-Identifier: Apache-2.0
+# Copyright 2018-2022 The glTF-Blender-IO authors.
+
+from ...io.com.gltf2_io import TextureInfo
+from .gltf2_blender_texture import texture
+from .gltf2_blender_image import BlenderImage
+from ..exp.gltf2_blender_image import TmpImageGuard
+import numpy as np
+import bpy
+
+def sheen( mh,
+ location_sheenColor,
+ location_sheenRoughness,
+ sheenColor_socket,
+ sheenRoughness_socket
+ ):
+
+ x_sheenColor, y_sheenColor = location_sheenColor
+ x_sheenRoughness, y_sheenRoughness = location_sheenRoughness
+
+ try:
+ ext = mh.pymat.extensions['KHR_materials_sheen']
+ except Exception:
+ return
+
+ sheenColorFactor = ext.get('sheenColorFactor', [0.0, 0.0, 0.0])
+ tex_info_color = ext.get('sheenColorTexture')
+ if tex_info_color is not None:
+ tex_info_color = TextureInfo.from_dict(tex_info_color)
+
+ sheenRoughnessFactor = ext.get('sheenRoughnessFactor', 0.0)
+ tex_info_roughness = ext.get('sheenRoughnessTexture')
+ if tex_info_roughness is not None:
+ tex_info_roughness = TextureInfo.from_dict(tex_info_roughness)
+
+ if tex_info_color is None:
+ sheenColorFactor.extend([1.0])
+ sheenColor_socket.default_value = sheenColorFactor
+ else:
+ # Mix sheenColor factor
+ sheenColorFactor = sheenColorFactor + [1.0]
+ if sheenColorFactor != [1.0, 1.0, 1.0, 1.0]:
+ node = mh.node_tree.nodes.new('ShaderNodeMixRGB')
+ node.label = 'sheenColor Factor'
+ node.location = x_sheenColor - 140, y_sheenColor
+ node.blend_type = 'MULTIPLY'
+ # Outputs
+ mh.node_tree.links.new(sheenColor_socket, node.outputs[0])
+ # Inputs
+ node.inputs['Fac'].default_value = 1.0
+ sheenColor_socket = node.inputs['Color1']
+ node.inputs['Color2'].default_value = sheenColorFactor
+ x_sheenColor -= 200
+
+ texture(
+ mh,
+ tex_info=tex_info_color,
+ label='SHEEN COLOR',
+ location=(x_sheenColor, y_sheenColor),
+ color_socket=sheenColor_socket
+ )
+
+ if tex_info_roughness is None:
+ sheenRoughness_socket.default_value = sheenRoughnessFactor
+ else:
+ # Mix sheenRoughness factor
+ if sheenRoughnessFactor != 1.0:
+ node = mh.node_tree.nodes.new('ShaderNodeMath')
+ node.label = 'shennRoughness Factor'
+ node.location = x_sheenRoughness - 140, y_sheenRoughness
+ node.operation = 'MULTIPLY'
+ # Outputs
+ mh.node_tree.links.new(sheenRoughness_socket, node.outputs[0])
+ # Inputs
+ sheenRoughness_socket = node.inputs[0]
+ node.inputs[1].default_value = sheenRoughnessFactor
+ x_sheenRoughness -= 200
+
+ texture(
+ mh,
+ tex_info=tex_info_roughness,
+ label='SHEEN ROUGHNESS',
+ location=(x_sheenRoughness, y_sheenRoughness),
+ is_data=True,
+ color_socket=None,
+ alpha_socket=sheenRoughness_socket
+ )
+ return \ No newline at end of file
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_specular.py b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_specular.py
new file mode 100644
index 00000000..3441b5ad
--- /dev/null
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_specular.py
@@ -0,0 +1,356 @@
+# SPDX-License-Identifier: Apache-2.0
+# Copyright 2018-2021 The glTF-Blender-IO authors.
+
+import bpy
+from ...io.com.gltf2_io import TextureInfo
+from .gltf2_blender_texture import texture
+from io_scene_gltf2.io.com.gltf2_io_constants import GLTF_IOR
+from .gltf2_blender_image import BlenderImage
+from ..exp.gltf2_blender_image import TmpImageGuard, make_temp_image_copy
+
+
+def specular(mh, location_specular,
+ location_specular_tint,
+ specular_socket,
+ specular_tint_socket,
+ original_specular_socket,
+ original_specularcolor_socket,
+ location_original_specular,
+ location_original_specularcolor):
+ x_specular, y_specular = location_specular
+ x_tint, y_tint = location_specular_tint
+
+ if specular_socket is None:
+ return
+ if specular_tint_socket is None:
+ return
+
+ try:
+ ext = mh.pymat.extensions['KHR_materials_specular']
+ except Exception:
+ return
+
+ import numpy as np
+
+ # Retrieve image names
+ try:
+ tex_info = mh.pymat.pbr_metallic_roughness.base_color_texture
+ pytexture = mh.gltf.data.textures[tex_info.index]
+ pyimg = mh.gltf.data.images[pytexture.source]
+ base_color_image_name = pyimg.blender_image_name
+ except:
+ base_color_image_name = None
+
+ # First check if we need a texture or not -> retrieve all info needed
+ specular_factor = ext.get('specularFactor', 1.0)
+ tex_specular_info = ext.get('specularTexture')
+ if tex_specular_info is not None:
+ tex_specular_info = TextureInfo.from_dict(tex_specular_info)
+
+ specular_color_factor = np.array(ext.get('specularColorFactor', [1.0, 1.0, 1.0])[:3])
+ tex_specular_color_info = ext.get('specularColorTexture')
+ if tex_specular_color_info is not None:
+ tex_specular_color_info = TextureInfo.from_dict(tex_specular_color_info)
+
+ base_color_not_linked = base_color_image_name is None
+ base_color = np.array(mh.pymat.pbr_metallic_roughness.base_color_factor or [1, 1, 1])
+ tex_base_color = mh.pymat.pbr_metallic_roughness.base_color_texture
+ base_color = base_color[:3]
+
+ try:
+ ext_transmission = mh.pymat.extensions['KHR_materials_transmission']
+ transmission_factor = ext_transmission.get('transmissionFactor', 0)
+ tex_transmission_info = ext_transmission.get('transmissionTexture')
+ if tex_transmission_info is not None:
+ tex_transmission_info = TextureInfo.from_dict(tex_transmission_info)
+ pytexture = mh.gltf.data.textures[tex_transmission_info.index]
+ pyimg = mh.gltf.data.images[pytexture.source]
+ transmission_image_name = pyimg.blender_image_name
+ else:
+ transmission_image_name = None
+ except Exception:
+ transmission_factor = 0
+ tex_transmission_info = None
+ transmission_image_name = None
+
+ transmission_not_linked = transmission_image_name is None
+
+ try:
+ ext_ior = mh.pymat.extensions['KHR_materials_ior']
+ ior = ext_ior.get('ior', GLTF_IOR)
+ except:
+ ior = GLTF_IOR
+
+ use_texture = tex_specular_info is not None or tex_specular_color_info is not None \
+ or transmission_not_linked is False or base_color_not_linked is False
+
+
+ # Before creating converted textures,
+ # Also plug non converted data into glTF PBR Non Converted Extensions node
+ original_specular( mh,
+ specular_factor,
+ tex_specular_info,
+ specular_color_factor,
+ tex_specular_color_info,
+ original_specular_socket,
+ original_specularcolor_socket,
+ location_original_specular,
+ location_original_specularcolor
+ )
+
+
+ if not use_texture:
+
+ def luminance(c):
+ return 0.3 * c[0] + 0.6 * c[1] + 0.1 * c[2]
+
+ def normalize(c):
+ assert(len(c) == 3)
+ l = luminance(c)
+ if l == 0:
+ return c
+ return np.array([c[0] / l, c[1] / l, c[2] / l])
+
+ f0_from_ior = ((ior - 1)/(ior + 1))**2
+ lum_specular_color = luminance(specular_color_factor)
+ blender_specular = ((lum_specular_color - transmission_factor) / (1 - transmission_factor)) * (1 / 0.08) * f0_from_ior
+ if not all([i == 0 for i in normalize(base_color) - 1]):
+ blender_specular_tint = luminance((normalize(specular_color_factor) - 1) / (normalize(base_color) - 1))
+ if blender_specular_tint < 0 or blender_specular_tint > 1:
+ # TODOExt Warning clamping
+ blender_specular_tint = np.maximum(np.minimum(blender_specular_tint, 1), 0)
+ else:
+ blender_specular_tint = 1.0
+
+ specular_socket.default_value = blender_specular
+ specular_tint_socket.default_value = blender_specular_tint
+ # Note: blender_specular can be greater 1. The Blender documentation permits this.
+
+ return
+ else:
+ # Need to create a texture
+ # First, retrieve and create all images needed
+
+ # Base Color is already created
+ # Transmission is already created
+ # specularTexture is just created by original specular function
+ specular_image_name = None
+ try:
+ pytexture = mh.gltf.data.textures[tex_specular_info.index]
+ pyimg = mh.gltf.data.images[pytexture.source]
+ specular_image_name = pyimg.blender_image_name
+ except:
+ specular_image_name = None
+
+
+ # specularColorTexture is just created by original specular function
+ specularcolor_image_name = None
+ try:
+ pytexture = mh.gltf.data.textures[tex_specular_color_info.index]
+ pyimg = mh.gltf.data.images[pytexture.source]
+ specularcolor_image_name = pyimg.blender_image_name
+ except:
+ specularcolor_image_name = None
+
+ stack3 = lambda v: np.dstack([v]*3)
+
+ texts = {
+ base_color_image_name : 'basecolor',
+ transmission_image_name : 'transmission',
+ specularcolor_image_name : 'speccolor',
+ specular_image_name: 'spec'
+ }
+ images = [(name, bpy.data.images[name]) for name in [base_color_image_name, transmission_image_name, specularcolor_image_name, specular_image_name] if name is not None]
+
+ width = max(image[1].size[0] for image in images)
+ height = max(image[1].size[1] for image in images)
+
+ buffers = {}
+ for name, image in images:
+ tmp_buf = np.empty(width * height * 4, np.float32)
+
+ if image.size[0] == width and image.size[1] == height:
+ image.pixels.foreach_get(tmp_buf)
+ else:
+ # Image is the wrong size; make a temp copy and scale it.
+ with TmpImageGuard() as guard:
+ make_temp_image_copy(guard, src_image=image)
+ tmp_image = guard.image
+ tmp_image.scale(width, height)
+ tmp_image.pixels.foreach_get(tmp_buf)
+
+ buffers[texts[name]] = np.reshape(tmp_buf, [width, height, 4])
+ buffers[texts[name]] = buffers[texts[name]][:,:,:3]
+
+ # Manage factors
+ if name == transmission_image_name:
+ buffers[texts[name]] = stack3(buffers[texts[name]][:,:,0]) # Transmission : keep only R channel
+
+ buffers[texts[name]] *= stack3(transmission_factor)
+
+ elif name == base_color_image_name:
+ buffers[texts[name]] *= base_color
+
+ elif name == specularcolor_image_name:
+ buffers[texts[name]] *= specular_color_factor
+
+ # Create buffer if there is no image
+ if 'basecolor' not in buffers.keys():
+ buffers['basecolor'] = np.full((width, height, 3), base_color)
+ if 'transmission' not in buffers.keys():
+ buffers['transmission'] = np.full((width, height, 3), transmission_factor)
+ if 'speccolor' not in buffers.keys():
+ buffers['speccolor'] = np.full((width, height, 3), specular_color_factor)
+
+ # Calculation
+
+ luminance = lambda c: 0.3 * c[:,:,0] + 0.6 * c[:,:,1] + 0.1 * c[:,:,2]
+ def normalize(c):
+ l = luminance(c)
+ if np.all(l == 0.0):
+ return np.array(c)
+ return c / stack3(l)
+
+ f0_from_ior = ((ior - 1)/(ior + 1))**2
+ lum_specular_color = stack3(luminance(buffers['speccolor']))
+ blender_specular = ((lum_specular_color - buffers['transmission']) / (1 - buffers['transmission'])) * (1 / 0.08) * f0_from_ior
+ if not np.all(normalize(buffers['basecolor']) - 1 == 0.0):
+ blender_specular_tint = luminance((normalize(buffers['speccolor']) - 1) / (normalize(buffers['basecolor']) - 1))
+ np.nan_to_num(blender_specular_tint, copy=False)
+ blender_specular_tint = np.clip(blender_specular_tint, 0.0, 1.0)
+ blender_specular_tint = stack3(blender_specular_tint)
+ else:
+ blender_specular_tint = stack3(np.ones((width, height)))
+
+ blender_specular = np.dstack((blender_specular, np.ones((width, height)))) # Set alpha to 1
+ blender_specular_tint = np.dstack((blender_specular_tint, np.ones((width, height)))) # Set alpha to 1
+
+ # Check if we really need to create a texture
+ blender_specular_tex_not_needed = np.all(np.isclose(blender_specular, blender_specular[0][0]))
+ blender_specular_tint_tex_not_needed = np.all(np.isclose(blender_specular_tint, blender_specular_tint[0][0]))
+
+ if blender_specular_tex_not_needed == True:
+ lum = lambda c: 0.3 * c[0] + 0.6 * c[1] + 0.1 * c[2]
+ specular_socket.default_value = lum(blender_specular[0][0][:3])
+ else:
+ blender_specular = np.reshape(blender_specular, width * height * 4)
+ # Create images in Blender, width and height are dummy values, then set packed file data
+ blender_image_spec = bpy.data.images.new('Specular', width, height)
+ blender_image_spec.pixels.foreach_set(np.float32(blender_specular))
+ blender_image_spec.pack()
+
+ # Create Textures in Blender
+ tex_info = tex_specular_info
+ if tex_info is None:
+ tex_info = tex_specular_color_info
+ if tex_info is None:
+ tex_info = tex_transmission_info
+ if tex_info is None:
+ tex_info = tex_base_color
+
+ texture(
+ mh,
+ tex_info=tex_info,
+ label='SPECULAR',
+ location=(x_specular, y_specular),
+ is_data=True,
+ color_socket=specular_socket,
+ forced_image=blender_image_spec
+ )
+
+ if blender_specular_tint_tex_not_needed == True:
+ lum = lambda c: 0.3 * c[0] + 0.6 * c[1] + 0.1 * c[2]
+ specular_tint_socket.default_value = lum(blender_specular_tint[0][0])
+ else:
+ blender_specular_tint = np.reshape(blender_specular_tint, width * height * 4)
+ # Create images in Blender, width and height are dummy values, then set packed file data
+ blender_image_tint = bpy.data.images.new('Specular Tint', width, height)
+ blender_image_tint.pixels.foreach_set(np.float32(blender_specular_tint))
+ blender_image_tint.pack()
+
+ # Create Textures in Blender
+ tex_info = tex_specular_color_info
+ if tex_info is None:
+ tex_info = tex_specular_info
+ if tex_info is None:
+ tex_info = tex_transmission_info
+ if tex_info is None:
+ tex_info = tex_base_color
+
+ texture(
+ mh,
+ tex_info=tex_info,
+ label='SPECULAR TINT',
+ location=(x_tint, y_tint),
+ is_data=True,
+ color_socket=specular_tint_socket,
+ forced_image=blender_image_tint
+ )
+
+def original_specular( mh,
+ specular_factor,
+ tex_specular_info,
+ specular_color_factor,
+ tex_specular_color_info,
+ original_specular_socket,
+ original_specularcolor_socket,
+ location_original_specular,
+ location_original_specularcolor
+ ):
+
+ x_specular, y_specular = location_original_specular
+ x_specularcolor, y_specularcolor = location_original_specularcolor
+
+ if tex_specular_info is None:
+ original_specular_socket.default_value = specular_factor
+ else:
+ # Mix specular factor
+ if specular_factor != 1.0:
+ node = mh.node_tree.nodes.new('ShaderNodeMath')
+ node.label = 'Specular Factor'
+ node.location = x_specular - 140, y_specular
+ node.operation = 'MULTIPLY'
+ # Outputs
+ mh.node_tree.links.new(original_specular_socket, node.outputs[0])
+ # Inputs
+ original_specular_socket = node.inputs[0]
+ node.inputs[1].default_value = specular_factor
+ x_specular -= 200
+
+ texture(
+ mh,
+ tex_info=tex_specular_info,
+ label='SPECULAR',
+ location=(x_specular, y_specular),
+ is_data=True,
+ color_socket=None,
+ alpha_socket=original_specular_socket
+ )
+
+ if tex_specular_color_info is None:
+ specular_color_factor = list(specular_color_factor)
+ specular_color_factor.extend([1.0])
+ original_specularcolor_socket.default_value = specular_color_factor
+ else:
+ specular_color_factor = list(specular_color_factor) + [1.0]
+ if specular_color_factor != [1.0, 1.0, 1.0, 1.0]:
+ # Mix specularColorFactor
+ node = mh.node_tree.nodes.new('ShaderNodeMixRGB')
+ node.label = 'SpecularColor Factor'
+ node.location = x_specularcolor - 140, y_specularcolor
+ node.blend_type = 'MULTIPLY'
+ # Outputs
+ mh.node_tree.links.new(original_specularcolor_socket, node.outputs[0])
+ # Inputs
+ node.inputs['Fac'].default_value = 1.0
+ original_specularcolor_socket = node.inputs['Color1']
+ node.inputs['Color2'].default_value = specular_color_factor
+ x_specularcolor -= 200
+
+ texture(
+ mh,
+ tex_info=tex_specular_color_info,
+ label='SPECULAR COLOR',
+ location=(x_specularcolor, y_specularcolor),
+ color_socket=original_specularcolor_socket,
+ ) \ No newline at end of file
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_transmission.py b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_transmission.py
new file mode 100644
index 00000000..dab25d14
--- /dev/null
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_transmission.py
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: Apache-2.0
+# Copyright 2018-2022 The glTF-Blender-IO authors.
+
+
+from ...io.com.gltf2_io import TextureInfo, MaterialNormalTextureInfoClass
+from .gltf2_blender_texture import texture
+
+
+# [Texture] => [Separate R] => [Transmission Factor] =>
+def transmission(mh, location, transmission_socket):
+ x, y = location
+ try:
+ ext = mh.pymat.extensions['KHR_materials_transmission']
+ except Exception:
+ return
+ transmission_factor = ext.get('transmissionFactor', 0)
+
+ # Default value is 0, so no transmission
+ if transmission_factor == 0:
+ return
+
+ tex_info = ext.get('transmissionTexture')
+ if tex_info is not None:
+ tex_info = TextureInfo.from_dict(tex_info)
+
+ if transmission_socket is None:
+ return
+
+ if tex_info is None:
+ transmission_socket.default_value = transmission_factor
+ return
+
+ # Mix transmission factor
+ if transmission_factor != 1:
+ node = mh.node_tree.nodes.new('ShaderNodeMath')
+ node.label = 'Transmission Factor'
+ node.location = x - 140, y
+ node.operation = 'MULTIPLY'
+ # Outputs
+ mh.node_tree.links.new(transmission_socket, node.outputs[0])
+ # Inputs
+ transmission_socket = node.inputs[0]
+ node.inputs[1].default_value = transmission_factor
+
+ x -= 200
+
+ # Separate RGB
+ node = mh.node_tree.nodes.new('ShaderNodeSeparateColor')
+ node.location = x - 150, y - 75
+ # Outputs
+ mh.node_tree.links.new(transmission_socket, node.outputs['Red'])
+ # Inputs
+ transmission_socket = node.inputs[0]
+
+ x -= 200
+
+ texture(
+ mh,
+ tex_info=tex_info,
+ label='TRANSMISSION',
+ location=(x, y),
+ is_data=True,
+ color_socket=transmission_socket,
+ )
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_unlit.py b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_unlit.py
index 48ad46fd..1ffdc7e4 100644
--- a/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_unlit.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_unlit.py
@@ -24,12 +24,15 @@ def unlit(mh):
mh.node_tree.links.new(mix_node.inputs[1], transparent_node.outputs[0])
mh.node_tree.links.new(mix_node.inputs[2], emission_node.outputs[0])
- _emission_socket, alpha_socket = make_output_nodes(
+ _emission_socket, alpha_socket, _, _ = make_output_nodes(
mh,
location=(420, 280) if mh.is_opaque() else (150, 130),
+ additional_location=None, #No additional location needed for Unlit
shader_socket=mix_node.outputs[0],
make_emission_socket=False,
make_alpha_socket=not mh.is_opaque(),
+ make_volume_socket=None, # Not possible to have KHR_materials_volume with unlit
+ make_velvet_socket=None #Not possible to have KHR_materials_sheen with unlit
)
base_color(
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_volume.py b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_volume.py
new file mode 100644
index 00000000..f909c7f6
--- /dev/null
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_volume.py
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: Apache-2.0
+# Copyright 2018-2021 The glTF-Blender-IO authors.
+
+from ...io.com.gltf2_io import TextureInfo, MaterialNormalTextureInfoClass
+from .gltf2_blender_texture import texture
+
+def volume(mh, location, volume_socket, thickness_socket):
+ # implementation based on https://github.com/KhronosGroup/glTF-Blender-IO/issues/1454#issuecomment-928319444
+ try:
+ ext = mh.pymat.extensions['KHR_materials_volume']
+ except Exception:
+ return
+
+ # Attenuation Color
+ attenuationColor = \
+ mh.pymat.extensions['KHR_materials_volume'] \
+ .get('attenuationColor')
+ # glTF is color3, Blender adds alpha
+ if attenuationColor is None:
+ attenuationColor = [1.0, 1.0, 1.0, 1.0]
+ else:
+ attenuationColor.extend([1.0])
+ volume_socket.node.inputs[0].default_value = attenuationColor
+
+ # Attenuation Distance / Density
+ attenuationDistance = mh.pymat.extensions['KHR_materials_volume'].get('attenuationDistance')
+ if attenuationDistance is None:
+ density = 0
+ else:
+ density = 1.0 / attenuationDistance
+ volume_socket.node.inputs[1].default_value = density
+
+ # thicknessFactor / thicknessTexture
+ x, y = location
+ try:
+ ext = mh.pymat.extensions['KHR_materials_volume']
+ except Exception:
+ return
+ thickness_factor = ext.get('thicknessFactor', 0)
+ tex_info = ext.get('thicknessTexture')
+ if tex_info is not None:
+ tex_info = TextureInfo.from_dict(tex_info)
+
+ if thickness_socket is None:
+ return
+
+ if tex_info is None:
+ thickness_socket.default_value = thickness_factor
+ return
+
+ # Mix thickness factor
+ if thickness_factor != 1:
+ node = mh.node_tree.nodes.new('ShaderNodeMath')
+ node.label = 'Thickness Factor'
+ node.location = x - 140, y
+ node.operation = 'MULTIPLY'
+ # Outputs
+ mh.node_tree.links.new(thickness_socket, node.outputs[0])
+ # Inputs
+ thickness_socket = node.inputs[0]
+ node.inputs[1].default_value = thickness_factor
+
+ x -= 200
+
+ # Separate RGB
+ node = mh.node_tree.nodes.new('ShaderNodeSeparateColor')
+ node.location = x - 150, y - 75
+ # Outputs
+ mh.node_tree.links.new(thickness_socket, node.outputs['Green'])
+ # Inputs
+ thickness_socket = node.inputs[0]
+
+ x -= 200
+
+ texture(
+ mh,
+ tex_info=tex_info,
+ label='THICKNESS',
+ location=(x, y),
+ is_data=True,
+ color_socket=thickness_socket,
+ )
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py b/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py
index f2556465..33713b97 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py
@@ -4,6 +4,8 @@
import bpy
from mathutils import Vector, Quaternion, Matrix
from .gltf2_blender_scene import BlenderScene
+from ..com.gltf2_blender_ui import gltf2_KHR_materials_variants_variant, gltf2_KHR_materials_variants_primitive, gltf2_KHR_materials_variants_default_material
+from .gltf2_blender_material import BlenderMaterial
class BlenderGlTF():
@@ -180,6 +182,10 @@ class BlenderGlTF():
mesh.shapekey_names.append(shapekey_name)
+ # Manage KHR_materials_variants
+ BlenderGlTF.manage_material_variants(gltf)
+
+
@staticmethod
def find_unused_name(haystack, desired_name):
"""Finds a name not in haystack and <= 63 UTF-8 bytes.
@@ -201,3 +207,25 @@ class BlenderGlTF():
suffix = '.%03d' % cntr
cntr += 1
+
+
+ @staticmethod
+ def manage_material_variants(gltf):
+ if not (gltf.data.extensions is not None and 'KHR_materials_variants' in gltf.data.extensions.keys()):
+ gltf.KHR_materials_variants = False
+ return
+
+ gltf.KHR_materials_variants = True
+ # If there is no KHR_materials_variants data in scene, create it
+ if bpy.context.preferences.addons['io_scene_gltf2'].preferences.KHR_materials_variants_ui is False:
+ bpy.context.preferences.addons['io_scene_gltf2'].preferences.KHR_materials_variants_ui = True
+ # Setting preferences as dirty, to be sure that option is saved
+ bpy.context.preferences.is_dirty = True
+
+ if len(bpy.data.scenes[0].gltf2_KHR_materials_variants_variants) > 0:
+ bpy.data.scenes[0].gltf2_KHR_materials_variants_variants.clear()
+
+ for idx_variant, variant in enumerate(gltf.data.extensions['KHR_materials_variants']['variants']):
+ var = bpy.data.scenes[0].gltf2_KHR_materials_variants_variants.add()
+ var.name = variant['name']
+ var.variant_idx = idx_variant
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_image.py b/io_scene_gltf2/blender/imp/gltf2_blender_image.py
index 4f9af799..abce0354 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_image.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_image.py
@@ -83,7 +83,7 @@ def create_from_data(gltf, img_idx):
img_data = BinaryData.get_image_data(gltf, img_idx)
if img_data is None:
return
- img_name = 'Image_%d' % img_idx
+ img_name = gltf.data.images[img_idx].name or 'Image_%d' % img_idx
# Create image, width and height are dummy values
blender_image = bpy.data.images.new(img_name, 8, 8)
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_material.py b/io_scene_gltf2/blender/imp/gltf2_blender_material.py
index 1d18c65d..9a582f7e 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_material.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_material.py
@@ -48,6 +48,11 @@ class BlenderMaterial():
else:
pbr_metallic_roughness(mh)
+ # Manage KHR_materials_variants
+ # We need to store link between material idx in glTF and Blender Material id
+ if gltf.KHR_materials_variants is True:
+ gltf.variant_mapping[str(material_idx) + str(vertex_color)] = mat
+
import_user_extensions('gather_import_material_after_hook', gltf, pymaterial, vertex_color, mat)
@staticmethod
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py b/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
index a3c1bd34..b886dd25 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
@@ -11,6 +11,7 @@ from .gltf2_blender_material import BlenderMaterial
from ...io.com.gltf2_io_debug import print_console
from .gltf2_io_draco_compression_extension import decode_primitive
from io_scene_gltf2.io.imp.gltf2_io_user_extensions import import_user_extensions
+from ..com.gltf2_blender_ui import gltf2_KHR_materials_variants_primitive, gltf2_KHR_materials_variants_variant, gltf2_KHR_materials_variants_default_material
class BlenderMesh():
@@ -343,12 +344,19 @@ def do_primitives(gltf, mesh_idx, skin_idx, mesh, ob):
# ----
# Assign materials to faces
has_materials = any(prim.material is not None for prim in pymesh.primitives)
+ # Even if no primitive have material, we need to create slots if some primitives have some variant
+ if has_materials is False:
+ has_materials = any(prim.extensions is not None and 'KHR_materials_variants' in prim.extensions.keys() for prim in pymesh.primitives)
+
+ has_variant = prim.extensions is not None and 'KHR_materials_variants' in prim.extensions.keys() \
+ and 'mappings' in prim.extensions['KHR_materials_variants'].keys()
+
if has_materials:
material_indices = np.empty(num_faces, dtype=np.uint32)
empty_material_slot_index = None
f = 0
- for prim in pymesh.primitives:
+ for idx_prim, prim in enumerate(pymesh.primitives):
if prim.material is not None:
# Get the material
pymaterial = gltf.data.materials[prim.material]
@@ -358,19 +366,55 @@ def do_primitives(gltf, mesh_idx, skin_idx, mesh, ob):
material_name = pymaterial.blender_material[vertex_color]
# Put material in slot (if not there)
- if material_name not in mesh.materials:
+ if not has_variant:
+ if material_name not in mesh.materials:
+ mesh.materials.append(bpy.data.materials[material_name])
+ material_index = mesh.materials.find(material_name)
+ else:
+ # In case of variant, do not merge slots
mesh.materials.append(bpy.data.materials[material_name])
- material_index = mesh.materials.find(material_name)
+ material_index = len(mesh.materials) - 1
else:
- if empty_material_slot_index is None:
+ if not has_variant:
+ if empty_material_slot_index is None:
+ mesh.materials.append(None)
+ empty_material_slot_index = len(mesh.materials) - 1
+ material_index = empty_material_slot_index
+ else:
+ # In case of variant, do not merge slots
mesh.materials.append(None)
- empty_material_slot_index = len(mesh.materials) - 1
- material_index = empty_material_slot_index
+ material_index = len(mesh.materials) - 1
material_indices[f:f + prim.num_faces].fill(material_index)
f += prim.num_faces
+ # Manage variants
+ if has_variant:
+
+ # Store default material
+ default_mat = mesh.gltf2_variant_default_materials.add()
+ default_mat.material_slot_index = material_index
+ default_mat.default_material = bpy.data.materials[material_name] if prim.material is not None else None
+
+ for mapping in prim.extensions['KHR_materials_variants']['mappings']:
+ # Store, for each variant, the material link to this primitive
+
+ variant_primitive = mesh.gltf2_variant_mesh_data.add()
+ variant_primitive.material_slot_index = material_index
+ if 'material' not in mapping.keys():
+ # Default material
+ variant_primitive.material = None
+ else:
+ vertex_color = 'COLOR_0' if 'COLOR_0' in prim.attributes else None
+ if str(mapping['material']) + str(vertex_color) not in gltf.variant_mapping.keys():
+ BlenderMaterial.create(gltf, mapping['material'], vertex_color)
+ variant_primitive.material = gltf.variant_mapping[str(mapping['material']) + str(vertex_color)]
+
+ for variant in mapping['variants']:
+ vari = variant_primitive.variants.add()
+ vari.variant.variant_idx = variant
+
mesh.polygons.foreach_set('material_index', material_indices)
# ----
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_pbrMetallicRoughness.py b/io_scene_gltf2/blender/imp/gltf2_blender_pbrMetallicRoughness.py
index 4c32c35d..b6b8e19f 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_pbrMetallicRoughness.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_pbrMetallicRoughness.py
@@ -1,13 +1,19 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2018-2021 The glTF-Blender-IO authors.
+from re import M
import bpy
from ...io.com.gltf2_io import TextureInfo, MaterialPBRMetallicRoughness
from ..com.gltf2_blender_material_helpers import get_gltf_node_name, create_settings_group
from .gltf2_blender_texture import texture
from .gltf2_blender_KHR_materials_clearcoat import \
clearcoat, clearcoat_roughness, clearcoat_normal
-
+from .gltf2_blender_KHR_materials_transmission import transmission
+from .gltf2_blender_KHR_materials_ior import ior
+from .gltf2_blender_KHR_materials_volume import volume
+from .gltf2_blender_KHR_materials_specular import specular
+from .gltf2_blender_KHR_materials_sheen import sheen
+from ...io.com.gltf2_io_constants import GLTF_IOR
class MaterialHelper:
"""Helper class. Stores material stuff to be passed around everywhere."""
@@ -20,6 +26,7 @@ class MaterialHelper:
if pymat.pbr_metallic_roughness is None:
pymat.pbr_metallic_roughness = \
MaterialPBRMetallicRoughness.from_dict({})
+ self.settings_node = None
def is_opaque(self):
alpha_mode = self.pymat.alpha_mode
@@ -36,15 +43,52 @@ def pbr_metallic_roughness(mh: MaterialHelper):
"""Creates node tree for pbrMetallicRoughness materials."""
pbr_node = mh.node_tree.nodes.new('ShaderNodeBsdfPrincipled')
pbr_node.location = 10, 300
-
- make_output_nodes(
+ additional_location = 40, -370 # For occlusion and/or volume / original PBR extensions
+
+ # Set IOR to 1.5, this is the default in glTF
+ # This value may be overridden later if IOR extension is set on file
+ pbr_node.inputs['IOR'].default_value = GLTF_IOR
+
+ if mh.pymat.occlusion_texture is not None or (mh.pymat.extensions and 'KHR_materials_specular' in mh.pymat.extensions):
+ if mh.settings_node is None:
+ mh.settings_node = make_settings_node(mh)
+ mh.settings_node.location = additional_location
+ mh.settings_node.width = 180
+ additional_location = additional_location[0], additional_location[1] - 150
+
+ need_volume_node = False
+ if mh.pymat.extensions and 'KHR_materials_volume' in mh.pymat.extensions:
+ if 'thicknessFactor' in mh.pymat.extensions['KHR_materials_volume'] \
+ and mh.pymat.extensions['KHR_materials_volume']['thicknessFactor'] != 0.0:
+
+ need_volume_node = True
+
+ # We also need glTF Material Output Node, to set thicknessFactor and thicknessTexture
+ mh.settings_node = make_settings_node(mh)
+ mh.settings_node.location = additional_location
+ mh.settings_node.width = 180
+ volume_location = additional_location
+ additional_location = additional_location[0], additional_location[1] - 150
+
+ need_velvet_node = False
+ if mh.pymat.extensions and 'KHR_materials_sheen' in mh.pymat.extensions:
+ need_velvet_node = True
+
+ _, _, volume_socket, velvet_node = make_output_nodes(
mh,
location=(250, 260),
+ additional_location=additional_location,
shader_socket=pbr_node.outputs[0],
- make_emission_socket=False,
- make_alpha_socket=False,
+ make_emission_socket=False, # is managed by Principled shader node
+ make_alpha_socket=False, # is managed by Principled shader node
+ make_volume_socket=need_volume_node,
+ make_velvet_socket=need_velvet_node
)
+
+ if mh.pymat.extensions and 'KHR_materials_sheen':
+ pass #TOTOEXT
+
locs = calc_locations(mh)
emission(
@@ -75,13 +119,10 @@ def pbr_metallic_roughness(mh: MaterialHelper):
)
if mh.pymat.occlusion_texture is not None:
- node = make_settings_node(mh)
- node.location = 40, -370
- node.width = 180
occlusion(
mh,
location=locs['occlusion'],
- occlusion_socket=node.inputs['Occlusion'],
+ occlusion_socket=mh.settings_node.inputs['Occlusion'],
)
clearcoat(
@@ -102,6 +143,46 @@ def pbr_metallic_roughness(mh: MaterialHelper):
normal_socket=pbr_node.inputs['Clearcoat Normal'],
)
+ transmission(
+ mh,
+ location=locs['transmission'],
+ transmission_socket=pbr_node.inputs['Transmission']
+ )
+
+ if need_volume_node:
+ volume(
+ mh,
+ location=locs['volume_thickness'],
+ volume_socket=volume_socket,
+ thickness_socket=mh.settings_node.inputs[1] if mh.settings_node else None
+ )
+
+ specular(
+ mh,
+ location_specular=locs['specularTexture'],
+ location_specular_tint=locs['specularColorTexture'],
+ specular_socket=pbr_node.inputs['Specular'],
+ specular_tint_socket=pbr_node.inputs['Specular Tint'],
+ original_specular_socket=mh.settings_node.inputs[2] if mh.settings_node else None,
+ original_specularcolor_socket=mh.settings_node.inputs[3] if mh.settings_node else None,
+ location_original_specular=locs['original_specularTexture'],
+ location_original_specularcolor=locs['original_specularColorTexture']
+ )
+
+ if need_velvet_node:
+ sheen(
+ mh,
+ location_sheenColor=locs['sheenColorTexture'],
+ location_sheenRoughness=locs['sheenRoughnessTexture'],
+ sheenColor_socket=velvet_node.inputs[0],
+ sheenRoughness_socket=velvet_node.inputs[1]
+ )
+
+ ior(
+ mh,
+ ior_socket=pbr_node.inputs['IOR']
+ )
+
def calc_locations(mh):
"""Calculate locations to place each bit of the node graph at."""
@@ -116,18 +197,53 @@ def calc_locations(mh):
except Exception:
clearcoat_ext = {}
+ try:
+ transmission_ext = mh.pymat.exntesions['KHR_materials_transmission']
+ except:
+ transmission_ext = {}
+
+ try:
+ volume_ext = mh.pymat.extensions['KHR_materials_volume']
+ except Exception:
+ volume_ext = {}
+
+ try:
+ specular_ext = mh.pymat.extensions['KHR_materials_specular']
+ except:
+ specular_ext = {}
+
+ try:
+ sheen_ext = mh.pymat.extensions['KHR_materials_sheen']
+ except:
+ sheen_ext = {}
+
+ locs['sheenColorTexture'] = (x, y)
+ if 'sheenColorTexture' in sheen_ext:
+ y -= height
+ locs['sheenRoughnessTexture'] = (x, y)
+ if 'sheenRoughnessTexture' in sheen_ext:
+ y -= height
locs['base_color'] = (x, y)
if mh.pymat.pbr_metallic_roughness.base_color_texture is not None or mh.vertex_color:
y -= height
locs['metallic_roughness'] = (x, y)
if mh.pymat.pbr_metallic_roughness.metallic_roughness_texture is not None:
y -= height
+ locs['specularTexture'] = (x, y)
+ if 'specularTexture' in specular_ext:
+ y -= height
+ locs['specularColorTexture'] = (x, y)
+ if 'specularColorTexture' in specular_ext:
+ y -= height
locs['clearcoat'] = (x, y)
if 'clearcoatTexture' in clearcoat_ext:
y -= height
locs['clearcoat_roughness'] = (x, y)
if 'clearcoatRoughnessTexture' in clearcoat_ext:
y -= height
+ locs['transmission'] = (x, y)
+ if 'transmissionTexture' in transmission_ext:
+ y -= height
locs['emission'] = (x, y)
if mh.pymat.emissive_texture is not None:
y -= height
@@ -140,6 +256,22 @@ def calc_locations(mh):
locs['occlusion'] = (x, y)
if mh.pymat.occlusion_texture is not None:
y -= height
+ locs['volume_thickness'] = (x, y)
+ if 'thicknessTexture' in volume_ext:
+ y -= height
+ locs['original_specularTexture'] = (x, y)
+ if 'specularTexture' in specular_ext:
+ y -= height
+ locs['original_specularColorTexture'] = (x, y)
+ if 'specularColorTexture' in specular_ext:
+ y -= height
+ locs['original_sheenColorTexture'] = (x, y)
+ if 'sheenColorTexture' in sheen_ext:
+ y -= height
+ locs['original_sheenRoughnessTexture'] = (x, y)
+ if 'sheenRoughnessTexture' in sheen_ext:
+ y -= height
+
# Center things
total_height = -y
@@ -157,21 +289,29 @@ def calc_locations(mh):
# [Texture] => [Emissive Factor] =>
-def emission(mh: MaterialHelper, location, color_socket, strength_socket=None):
+def emission(mh: MaterialHelper, location, color_socket, strength_socket):
x, y = location
emissive_factor = mh.pymat.emissive_factor or [0, 0, 0]
+ strength = 1
+ try:
+ # Get strength from KHR_materials_emissive_strength if exists
+ strength = mh.pymat.extensions['KHR_materials_emissive_strength']['emissiveStrength']
+ except Exception:
+ pass
+
if color_socket is None:
return
if mh.pymat.emissive_texture is None:
color_socket.default_value = emissive_factor + [1]
+ strength_socket.default_value = strength
return
# Put grayscale emissive factors into the Emission Strength
e0, e1, e2 = emissive_factor
if strength_socket and e0 == e1 == e2:
- strength_socket.default_value = e0
+ strength_socket.default_value = e0 * strength
# Otherwise, use a multiply node for it
else:
@@ -189,6 +329,8 @@ def emission(mh: MaterialHelper, location, color_socket, strength_socket=None):
x -= 200
+ strength_socket.default_value = strength
+
texture(
mh,
tex_info=mh.pymat.emissive_texture,
@@ -466,17 +608,22 @@ def occlusion(mh: MaterialHelper, location, occlusion_socket):
)
-# => [Add Emission] => [Mix Alpha] => [Material Output]
+# => [Add Emission] => [Mix Alpha] => [Material Output] if needed, only for SpecGlossiness
+# => [Volume] => [Add Shader] => [Material Output] if needed
+# => [Velvet] => [Add Shader] => [Material Output] if needed
def make_output_nodes(
mh: MaterialHelper,
location,
+ additional_location,
shader_socket,
make_emission_socket,
make_alpha_socket,
+ make_volume_socket,
+ make_velvet_socket, # For sheen
):
"""
Creates the Material Output node and connects shader_socket to it.
- If requested, it can also create places to hookup the emission/alpha
+ If requested, it can also create places to hookup the emission/alpha.sheen
in between shader_socket and the Output node too.
:return: a pair containing the sockets you should put emission and alpha
@@ -484,6 +631,7 @@ def make_output_nodes(
"""
x, y = location
emission_socket = None
+ velvet_node = None
alpha_socket = None
# Create an Emission node and add it to the shader.
@@ -512,6 +660,31 @@ def make_output_nodes(
x += 380
y += 125
+ # Create an Velvet node add add it to the shader
+ # Note that you can not have Emission & Velvet at the same time
+ if make_velvet_socket:
+ # Velvet
+ node = mh.node_tree.nodes.new("ShaderNodeBsdfVelvet")
+ node.location = x + 50, y + 250
+ # Node
+ velvet_node = node
+ # Outputs
+ velvet_output = node.outputs[0]
+
+ # Add
+ node = mh.node_tree.nodes.new('ShaderNodeAddShader')
+ node.location = x + 250, y + 160
+ # Inputs
+ mh.node_tree.links.new(node.inputs[0], velvet_output)
+ mh.node_tree.links.new(node.inputs[1], shader_socket)
+ # Outputs
+ shader_socket = node.outputs[0]
+
+
+ x += 380
+ y += 125
+
+
# Mix with a Transparent BSDF. Mixing factor is the alpha value.
if make_alpha_socket:
# Transparent BSDF
@@ -535,12 +708,23 @@ def make_output_nodes(
y -= 210
# Material output
- node = mh.node_tree.nodes.new('ShaderNodeOutputMaterial')
- node.location = x + 70, y + 10
+ node_output = mh.node_tree.nodes.new('ShaderNodeOutputMaterial')
+ node_output.location = x + 70, y + 10
+
# Outputs
- mh.node_tree.links.new(node.inputs[0], shader_socket)
+ mh.node_tree.links.new(node_output.inputs[0], shader_socket)
+
+ # Volume Node
+ volume_socket = None
+ if make_volume_socket:
+ node = mh.node_tree.nodes.new('ShaderNodeVolumeAbsorption')
+ node.location = additional_location
+ # Outputs
+ mh.node_tree.links.new(node_output.inputs[1], node.outputs[0])
+ volume_socket = node.outputs[0]
+
- return emission_socket, alpha_socket
+ return emission_socket, alpha_socket, volume_socket, velvet_node
def make_settings_node(mh):
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_texture.py b/io_scene_gltf2/blender/imp/gltf2_blender_texture.py
index 24c9df7c..12e6d594 100644
--- a/io_scene_gltf2/blender/imp/gltf2_blender_texture.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_texture.py
@@ -17,6 +17,7 @@ def texture(
color_socket,
alpha_socket=None,
is_data=False,
+ forced_image=None
):
"""Creates nodes for a TextureInfo and hooks up the color/alpha outputs."""
x, y = location
@@ -36,12 +37,15 @@ def texture(
tex_img.location = x - 240, y
tex_img.label = label
# Get image
- if pytexture.source is not None:
- BlenderImage.create(mh.gltf, pytexture.source)
- pyimg = mh.gltf.data.images[pytexture.source]
- blender_image_name = pyimg.blender_image_name
- if blender_image_name:
- tex_img.image = bpy.data.images[blender_image_name]
+ if forced_image is None:
+ if pytexture.source is not None:
+ BlenderImage.create(mh.gltf, pytexture.source)
+ pyimg = mh.gltf.data.images[pytexture.source]
+ blender_image_name = pyimg.blender_image_name
+ if blender_image_name:
+ tex_img.image = bpy.data.images[blender_image_name]
+ else:
+ tex_img.image = forced_image
# Set colorspace for data images
if is_data:
if tex_img.image:
@@ -49,7 +53,8 @@ def texture(
# Set filtering
set_filtering(tex_img, pysampler)
# Outputs
- mh.node_tree.links.new(color_socket, tex_img.outputs['Color'])
+ if color_socket is not None:
+ mh.node_tree.links.new(color_socket, tex_img.outputs['Color'])
if alpha_socket is not None:
mh.node_tree.links.new(alpha_socket, tex_img.outputs['Alpha'])
# Inputs