glTF importer: Manage KHR_texture_transform extension

This commit is contained in:
Julien Duroure 2019-04-19 18:06:25 +02:00
parent 022fb9d09a
commit e4165cee8b
9 changed files with 88 additions and 19 deletions

View File

@ -15,7 +15,7 @@
bl_info = {
'name': 'glTF 2.0 format',
'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
"version": (0, 9, 0),
"version": (0, 9, 1),
'blender': (2, 80, 0),
'location': 'File > Import-Export',
'description': 'Import-Export as glTF 2.0',

View File

@ -14,6 +14,7 @@
import bpy
from .gltf2_blender_texture import BlenderTextureInfo
from ..com.gltf2_blender_conversion import texture_transform_gltf_to_blender
class BlenderKHR_materials_pbrSpecularGlossiness():
@ -86,7 +87,7 @@ class BlenderKHR_materials_pbrSpecularGlossiness():
math_vc_B = node_tree.nodes.new('ShaderNodeMath')
math_vc_B.operation = 'MULTIPLY'
BlenderTextureInfo.create(gltf, pbrSG['diffuseTexture']['index'])
BlenderTextureInfo.create(gltf, pbrSG['diffuseTexture'], dict_=True)
# create UV Map / Mapping / Texture nodes / separate & math and combine
text_node = node_tree.nodes.new('ShaderNodeTexImage')
@ -122,6 +123,13 @@ class BlenderKHR_materials_pbrSpecularGlossiness():
mapping = node_tree.nodes.new('ShaderNodeMapping')
mapping.location = -1500, 500
mapping.vector_type = 'POINT'
tex_transform = text_node.image['tex_transform'][str(pbrSG['diffuseTexture']['index'])]
mapping.translation[0] = texture_transform_gltf_to_blender(tex_transform)['offset'][0]
mapping.translation[1] = texture_transform_gltf_to_blender(tex_transform)['offset'][1]
mapping.rotation[2] = texture_transform_gltf_to_blender(tex_transform)['rotation']
mapping.scale[0] = texture_transform_gltf_to_blender(tex_transform)['scale'][0]
mapping.scale[1] = texture_transform_gltf_to_blender(tex_transform)['scale'][1]
uvmap = node_tree.nodes.new('ShaderNodeUVMap')
uvmap.location = -2000, 500
@ -162,7 +170,7 @@ class BlenderKHR_materials_pbrSpecularGlossiness():
elif pbrSG['diffuse_type'] == gltf.TEXTURE:
BlenderTextureInfo.create(gltf, pbrSG['diffuseTexture']['index'])
BlenderTextureInfo.create(gltf, pbrSG['diffuseTexture'], dict_=True)
# TODO alpha ?
if vertex_color:
@ -209,6 +217,13 @@ class BlenderKHR_materials_pbrSpecularGlossiness():
mapping.location = -2500, 500
else:
mapping.location = -1500, 500
mapping.vector_type = 'POINT'
tex_transform = text_node.image['tex_transform'][str(pbrSG['diffuseTexture']['index'])]
mapping.translation[0] = texture_transform_gltf_to_blender(tex_transform)['offset'][0]
mapping.translation[1] = texture_transform_gltf_to_blender(tex_transform)['offset'][1]
mapping.rotation[2] = texture_transform_gltf_to_blender(tex_transform)['rotation']
mapping.scale[0] = texture_transform_gltf_to_blender(tex_transform)['scale'][0]
mapping.scale[1] = texture_transform_gltf_to_blender(tex_transform)['scale'][1]
uvmap = node_tree.nodes.new('ShaderNodeUVMap')
if vertex_color:
@ -260,7 +275,7 @@ class BlenderKHR_materials_pbrSpecularGlossiness():
node_tree.links.new(glossy.inputs[0], combine.outputs[0])
elif pbrSG['specgloss_type'] == gltf.TEXTURE:
BlenderTextureInfo.create(gltf, pbrSG['specularGlossinessTexture']['index'])
BlenderTextureInfo.create(gltf, pbrSG['specularGlossinessTexture'], dict_=True)
spec_text = node_tree.nodes.new('ShaderNodeTexImage')
if gltf.data.images[
gltf.data.textures[pbrSG['specularGlossinessTexture']['index']].source
@ -275,6 +290,13 @@ class BlenderKHR_materials_pbrSpecularGlossiness():
spec_mapping = node_tree.nodes.new('ShaderNodeMapping')
spec_mapping.location = -1000, 0
spec_mapping.vector_type = 'POINT'
tex_transform = spec_text.image['tex_transform'][str(pbrSG['specularGlossinessTexture']['index'])]
spec_mapping.translation[0] = texture_transform_gltf_to_blender(tex_transform)['offset'][0]
spec_mapping.translation[1] = texture_transform_gltf_to_blender(tex_transform)['offset'][1]
spec_mapping.rotation[2] = texture_transform_gltf_to_blender(tex_transform)['rotation']
spec_mapping.scale[0] = texture_transform_gltf_to_blender(tex_transform)['scale'][0]
spec_mapping.scale[1] = texture_transform_gltf_to_blender(tex_transform)['scale'][1]
spec_uvmap = node_tree.nodes.new('ShaderNodeUVMap')
spec_uvmap.location = -1500, 0
@ -292,8 +314,7 @@ class BlenderKHR_materials_pbrSpecularGlossiness():
node_tree.links.new(spec_text.inputs[0], spec_mapping.outputs[0])
elif pbrSG['specgloss_type'] == gltf.TEXTURE_FACTOR:
BlenderTextureInfo.create(gltf, pbrSG['specularGlossinessTexture']['index'])
BlenderTextureInfo.create(gltf, pbrSG['specularGlossinessTexture'], dict_=True)
spec_text = node_tree.nodes.new('ShaderNodeTexImage')
if gltf.data.images[
@ -312,6 +333,14 @@ class BlenderKHR_materials_pbrSpecularGlossiness():
spec_mapping = node_tree.nodes.new('ShaderNodeMapping')
spec_mapping.location = -1000, 0
spec_mapping.vector_type = 'POINT'
tex_transform = spec_text.image['tex_transform'][str(pbrSG['specularGlossinessTexture']['index'])]
spec_mapping.translation[0] = texture_transform_gltf_to_blender(tex_transform)['offset'][0]
spec_mapping.translation[1] = texture_transform_gltf_to_blender(tex_transform)['offset'][1]
spec_mapping.rotation[2] = texture_transform_gltf_to_blender(tex_transform)['rotation']
spec_mapping.scale[0] = texture_transform_gltf_to_blender(tex_transform)['scale'][0]
spec_mapping.scale[1] = texture_transform_gltf_to_blender(tex_transform)['scale'][1]
spec_uvmap = node_tree.nodes.new('ShaderNodeUVMap')
spec_uvmap.location = -1500, 0

View File

@ -52,7 +52,7 @@ class BlenderImage():
return False, None, None
@staticmethod
def create(gltf, img_idx):
def create(gltf, img_idx, tex_index, tex_transform):
"""Image creation."""
img = gltf.data.images[img_idx]
@ -70,10 +70,13 @@ class BlenderImage():
if img_.filepath == path:
# Already loaded, not needed to reload it
img.blender_image_name = img_.name
img_['tex_transform'][str(tex_index)] = tex_transform
return
blender_image = bpy.data.images.load(path)
blender_image.name = img_name
blender_image['tex_transform'] = {}
blender_image['tex_transform'][str(tex_index)] = tex_transform
img.blender_image_name = blender_image.name
return
@ -83,6 +86,7 @@ class BlenderImage():
if hasattr(img_, "gltf_index") and img_['gltf_index'] == img_idx:
file_creation_needed = False
img.blender_image_name = img_.name
img_['tex_transform'][tex_index] = tex_transform
break
if file_creation_needed is True:
@ -96,6 +100,8 @@ class BlenderImage():
blender_image = bpy.data.images.load(tmp_image.name)
blender_image.pack()
blender_image.name = img_name
blender_image['tex_transform'] = {}
blender_image['tex_transform'][str(tex_index)] = tex_transform
img.blender_image_name = blender_image.name
blender_image['gltf_index'] = img_idx
os.remove(tmp_image.name)

View File

@ -37,7 +37,7 @@ class BlenderEmissiveMap():
node_tree = material.node_tree
if factor_only is False:
BlenderTextureInfo.create(gltf, pymaterial.emissive_texture.index)
BlenderTextureInfo.create(gltf, pymaterial.emissive_texture)
# check if there is some emissive_factor on material
if pymaterial.emissive_factor is None:

View File

@ -35,7 +35,7 @@ class BlenderNormalMap():
material = bpy.data.materials[pymaterial.blender_material[vertex_color]]
node_tree = material.node_tree
BlenderTextureInfo.create(gltf, pymaterial.normal_texture.index)
BlenderTextureInfo.create(gltf, pymaterial.normal_texture)
# retrieve principled node and output node
principled = None

View File

@ -32,7 +32,7 @@ class BlenderOcclusionMap():
"""Nodetree creation."""
pymaterial = gltf.data.materials[material_idx]
BlenderTextureInfo.create(gltf, pymaterial.occlusion_texture.index)
BlenderTextureInfo.create(gltf, pymaterial.occlusion_texture)
# Pack texture, but doesn't use it for now. Occlusion is calculated from Cycles.
if gltf.data.images[gltf.data.textures[

View File

@ -14,6 +14,7 @@
import bpy
from .gltf2_blender_texture import BlenderTextureInfo
from ..com.gltf2_blender_conversion import texture_transform_gltf_to_blender
class BlenderPbr():
@ -101,7 +102,7 @@ class BlenderPbr():
vc_mult_node.blend_type = 'MULTIPLY'
vc_mult_node.inputs['Fac'].default_value = 1.0
BlenderTextureInfo.create(gltf, pypbr.base_color_texture.index)
BlenderTextureInfo.create(gltf, pypbr.base_color_texture)
# create UV Map / Mapping / Texture nodes / separate & math and combine
text_node = node_tree.nodes.new('ShaderNodeTexImage')
@ -126,6 +127,14 @@ class BlenderPbr():
mapping = node_tree.nodes.new('ShaderNodeMapping')
mapping.location = -1500, 500
mapping.vector_type = 'POINT'
tex_transform = text_node.image['tex_transform'][str(pypbr.base_color_texture.index)]
mapping.translation[0] = texture_transform_gltf_to_blender(tex_transform)['offset'][0]
mapping.translation[1] = texture_transform_gltf_to_blender(tex_transform)['offset'][1]
mapping.rotation[2] = texture_transform_gltf_to_blender(tex_transform)['rotation']
mapping.scale[0] = texture_transform_gltf_to_blender(tex_transform)['scale'][0]
mapping.scale[1] = texture_transform_gltf_to_blender(tex_transform)['scale'][1]
uvmap = node_tree.nodes.new('ShaderNodeUVMap')
uvmap.location = -2000, 500
@ -151,7 +160,7 @@ class BlenderPbr():
elif pypbr.color_type == gltf.TEXTURE:
BlenderTextureInfo.create(gltf, pypbr.base_color_texture.index)
BlenderTextureInfo.create(gltf, pypbr.base_color_texture)
# TODO alpha ?
if vertex_color:
@ -183,6 +192,13 @@ class BlenderPbr():
mapping.location = -2500, 500
else:
mapping.location = -1500, 500
mapping.vector_type = 'POINT'
tex_transform = text_node.image['tex_transform'][str(pypbr.base_color_texture.index)]
mapping.translation[0] = texture_transform_gltf_to_blender(tex_transform)['offset'][0]
mapping.translation[1] = texture_transform_gltf_to_blender(tex_transform)['offset'][1]
mapping.rotation[2] = texture_transform_gltf_to_blender(tex_transform)['rotation']
mapping.scale[0] = texture_transform_gltf_to_blender(tex_transform)['scale'][0]
mapping.scale[1] = texture_transform_gltf_to_blender(tex_transform)['scale'][1]
uvmap = node_tree.nodes.new('ShaderNodeUVMap')
if vertex_color:
@ -216,7 +232,7 @@ class BlenderPbr():
main_node.inputs[7].default_value = pypbr.roughness_factor
elif pypbr.metallic_type == gltf.TEXTURE:
BlenderTextureInfo.create(gltf, pypbr.metallic_roughness_texture.index)
BlenderTextureInfo.create(gltf, pypbr.metallic_roughness_texture)
metallic_text = node_tree.nodes.new('ShaderNodeTexImage')
metallic_text.image = bpy.data.images[gltf.data.images[
gltf.data.textures[pypbr.metallic_roughness_texture.index].source
@ -249,7 +265,7 @@ class BlenderPbr():
elif pypbr.metallic_type == gltf.TEXTURE_FACTOR:
BlenderTextureInfo.create(gltf, pypbr.metallic_roughness_texture.index)
BlenderTextureInfo.create(gltf, pypbr.metallic_roughness_texture)
metallic_text = node_tree.nodes.new('ShaderNodeTexImage')
metallic_text.image = bpy.data.images[gltf.data.images[
gltf.data.textures[pypbr.metallic_roughness_texture.index].source
@ -273,6 +289,13 @@ class BlenderPbr():
metallic_mapping = node_tree.nodes.new('ShaderNodeMapping')
metallic_mapping.location = -1000, 0
metallic_mapping.vector_type = 'POINT'
tex_transform = metallic_text.image['tex_transform'][str(pypbr.metallic_roughness_texture.index)]
metallic_mapping.translation[0] = texture_transform_gltf_to_blender(tex_transform)['offset'][0]
metallic_mapping.translation[1] = texture_transform_gltf_to_blender(tex_transform)['offset'][1]
metallic_mapping.rotation[2] = texture_transform_gltf_to_blender(tex_transform)['rotation']
metallic_mapping.scale[0] = texture_transform_gltf_to_blender(tex_transform)['scale'][0]
metallic_mapping.scale[1] = texture_transform_gltf_to_blender(tex_transform)['scale'][1]
metallic_uvmap = node_tree.nodes.new('ShaderNodeUVMap')
metallic_uvmap.location = -1500, 0

View File

@ -21,10 +21,20 @@ class BlenderTextureInfo():
raise RuntimeError("%s should not be instantiated" % cls)
@staticmethod
def create(gltf, pytextureinfo_idx):
def create(gltf, pytextureinfo, dict_=False):
"""Create Texture info."""
BlenderTexture.create(gltf, pytextureinfo_idx)
extension_text_transform_used = {}
if dict_ is True: # coming from KHR_materials_pbrSpecularGlossiness
if 'extensions' in pytextureinfo.keys() \
and 'KHR_texture_transform' in pytextureinfo['extensions'].keys():
extension_text_transform_used = pytextureinfo['extensions']['KHR_texture_transform']
BlenderTexture.create(gltf, pytextureinfo['index'], extension_text_transform_used)
else:
if pytextureinfo.extensions is not None \
and 'KHR_texture_transform' in pytextureinfo.extensions.keys():
extension_text_transform_used = pytextureinfo.extensions['KHR_texture_transform']
BlenderTexture.create(gltf, pytextureinfo.index, extension_text_transform_used)
class BlenderTexture():
"""Blender Texture."""
@ -32,8 +42,8 @@ class BlenderTexture():
raise RuntimeError("%s should not be instantiated" % cls)
@staticmethod
def create(gltf, pytexture_idx):
def create(gltf, pytexture_idx, tex_transform):
"""Create texture."""
pytexture = gltf.data.textures[pytexture_idx]
BlenderImage.create(gltf, pytexture.source)
BlenderImage.create(gltf, pytexture.source, pytexture_idx, tex_transform)

View File

@ -45,7 +45,8 @@ class glTFImporter():
self.extensions_managed = [
'KHR_materials_pbrSpecularGlossiness',
'KHR_lights_punctual',
'KHR_materials_unlit'
'KHR_materials_unlit',
'KHR_texture_transform'
]
# TODO : merge with io_constants