diff options
author | Julien Duroure <julien.duroure@gmail.com> | 2020-03-17 10:25:00 +0300 |
---|---|---|
committer | Julien Duroure <julien.duroure@gmail.com> | 2020-03-17 10:25:00 +0300 |
commit | d0dee32d2b5f653ef25843ad3bd542836ec788d8 (patch) | |
tree | cde4492d22b135825e6e9cdae1e3837541ab5d57 /io_scene_gltf2 | |
parent | f3683cf7bf74606d053cfda019c804185af74a3c (diff) |
glTF importer: manage texture wrap modes.
Thanks scurest!
Diffstat (limited to 'io_scene_gltf2')
-rwxr-xr-x | io_scene_gltf2/__init__.py | 2 | ||||
-rw-r--r-- | io_scene_gltf2/blender/imp/gltf2_blender_texture.py | 119 |
2 files changed, 78 insertions, 43 deletions
diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py index 62639ea9..6e9d73b9 100755 --- a/io_scene_gltf2/__init__.py +++ b/io_scene_gltf2/__init__.py @@ -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": (1, 2, 45), + "version": (1, 2, 46), 'blender': (2, 82, 7), 'location': 'File > Import-Export', 'description': 'Import-Export as glTF 2.0', diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_texture.py b/io_scene_gltf2/blender/imp/gltf2_blender_texture.py index 678fd2af..58d101d0 100644 --- a/io_scene_gltf2/blender/imp/gltf2_blender_texture.py +++ b/io_scene_gltf2/blender/imp/gltf2_blender_texture.py @@ -30,13 +30,19 @@ def texture( ): """Creates nodes for a TextureInfo and hooks up the color/alpha outputs.""" x, y = location + pytexture = mh.gltf.data.textures[tex_info.index] + if pytexture.sampler is not None: + pysampler = mh.gltf.data.samplers[pytexture.sampler] + else: + pysampler = Sampler.from_dict({}) + + needs_uv_map = False # whether to create UVMap node # Image Texture tex_img = mh.node_tree.nodes.new('ShaderNodeTexImage') tex_img.location = x - 240, y tex_img.label = label # Get image - pytexture = mh.gltf.data.textures[tex_info.index] if pytexture.source is not None: BlenderImage.create(mh.gltf, pytexture.source) pyimg = mh.gltf.data.images[pytexture.source] @@ -47,13 +53,8 @@ def texture( if is_data: if tex_img.image: tex_img.image.colorspace_settings.is_data = True - # Set wrapping/filtering - if pytexture.sampler is not None: - pysampler = mh.gltf.data.samplers[pytexture.sampler] - else: - pysampler = Sampler.from_dict({}) + # Set filtering set_filtering(tex_img, pysampler) - set_wrap_mode(tex_img, pysampler) # Outputs mh.node_tree.links.new(color_socket, tex_img.outputs['Color']) if alpha_socket is not None: @@ -63,6 +64,73 @@ def texture( x -= 340 + # Do wrapping + wrap_s = pysampler.wrap_s + wrap_t = pysampler.wrap_t + if wrap_s is None: + wrap_s = TextureWrap.Repeat + if wrap_t is None: + wrap_t = TextureWrap.Repeat + # If wrapping is REPEATxREPEAT or CLAMPxCLAMP, just set tex_img.extension + if (wrap_s, wrap_t) == (TextureWrap.Repeat, TextureWrap.Repeat): + tex_img.extension = 'REPEAT' + elif (wrap_s, wrap_t) == (TextureWrap.ClampToEdge, TextureWrap.ClampToEdge): + tex_img.extension = 'EXTEND' + else: + # Otherwise separate the UV components and use math nodes to compute + # the wrapped UV coordinates + # => [Separate XYZ] => [Wrap for S] => [Combine XYZ] => + # => [Wrap for T] => + + tex_img.extension = 'EXTEND' # slightly better errors near the edge than REPEAT + + # Combine XYZ + com_uv = mh.node_tree.nodes.new('ShaderNodeCombineXYZ') + com_uv.location = x - 140, y - 100 + mh.node_tree.links.new(uv_socket, com_uv.outputs[0]) + u_socket = com_uv.inputs[0] + v_socket = com_uv.inputs[1] + x -= 200 + + for i in [0, 1]: + wrap = [wrap_s, wrap_t][i] + socket = [u_socket, v_socket][i] + if wrap == TextureWrap.Repeat: + # WRAP node for REPEAT + math = mh.node_tree.nodes.new('ShaderNodeMath') + math.location = x - 140, y + 30 - i*200 + math.operation = 'WRAP' + math.inputs[1].default_value = 0 + math.inputs[2].default_value = 1 + mh.node_tree.links.new(socket, math.outputs[0]) + socket = math.inputs[0] + elif wrap == TextureWrap.MirroredRepeat: + # PINGPONG node for MIRRORED_REPEAT + math = mh.node_tree.nodes.new('ShaderNodeMath') + math.location = x - 140, y + 30 - i*200 + math.operation = 'PINGPONG' + math.inputs[1].default_value = 1 + mh.node_tree.links.new(socket, math.outputs[0]) + socket = math.inputs[0] + else: + # Pass-through CLAMP since the tex_img node is set to EXTEND + pass + if i == 0: + u_socket = socket + else: + v_socket = socket + x -= 200 + + # Separate XYZ + sep_uv = mh.node_tree.nodes.new('ShaderNodeSeparateXYZ') + sep_uv.location = x - 140, y - 100 + mh.node_tree.links.new(u_socket, sep_uv.outputs[0]) + mh.node_tree.links.new(v_socket, sep_uv.outputs[1]) + uv_socket = sep_uv.inputs[0] + x -= 200 + + needs_uv_map = True + # UV Transform (for KHR_texture_transform) needs_tex_transform = 'KHR_texture_transform' in (tex_info.extensions or {}) if needs_tex_transform: @@ -83,6 +151,7 @@ def texture( mapping.inputs['Scale'].default_value[1] = transform['scale'][1] x -= 260 + needs_uv_map = True # UV Map uv_idx = tex_info.tex_coord or 0 @@ -90,7 +159,7 @@ def texture( uv_idx = tex_info.extensions['KHR_texture_transform']['texCoord'] except Exception: pass - if uv_idx != 0 or needs_tex_transform: + if uv_idx != 0 or needs_uv_map: uv_map = mh.node_tree.nodes.new('ShaderNodeUVMap') uv_map.location = x - 160, y - 70 uv_map.uv_map = 'UVMap' if uv_idx == 0 else 'UVMap.%03d' % uv_idx @@ -117,37 +186,3 @@ def set_filtering(tex_img, pysampler): tex_img.interpolation = 'Closest' else: tex_img.interpolation = 'Linear' - -def set_wrap_mode(tex_img, pysampler): - """Set the extension on an Image Texture node from the pysampler.""" - wrap_s = pysampler.wrap_s - wrap_t = pysampler.wrap_t - - if wrap_s is None: - wrap_s = TextureWrap.Repeat - if wrap_t is None: - wrap_t = TextureWrap.Repeat - - # The extension property on the Image Texture node can only handle the case - # where both directions are the same and are either REPEAT or CLAMP_TO_EDGE. - if (wrap_s, wrap_t) == (TextureWrap.Repeat, TextureWrap.Repeat): - extension = TextureWrap.Repeat - elif (wrap_s, wrap_t) == (TextureWrap.ClampToEdge, TextureWrap.ClampToEdge): - extension = TextureWrap.ClampToEdge - else: - print_console('WARNING', - 'texture wrap mode unsupported: (%s, %s)' % (wrap_name(wrap_s), wrap_name(wrap_t)), - ) - # Default to repeat - extension = TextureWrap.Repeat - - if extension == TextureWrap.Repeat: - tex_img.extension = 'REPEAT' - elif extension == TextureWrap.ClampToEdge: - tex_img.extension = 'EXTEND' - -def wrap_name(wrap): - if wrap == TextureWrap.ClampToEdge: return 'CLAMP_TO_EDGE' - if wrap == TextureWrap.MirroredRepeat: return 'MIRRORED_REPEAT' - if wrap == TextureWrap.Repeat: return 'REPEAT' - return 'UNKNOWN (%s)' % wrap |