[Bf-extensions-cvs] [d0dee32d] master: glTF importer: manage texture wrap modes.

Julien Duroure noreply at git.blender.org
Tue Mar 17 08:25:38 CET 2020


Commit: d0dee32d2b5f653ef25843ad3bd542836ec788d8
Author: Julien Duroure
Date:   Tue Mar 17 08:25:00 2020 +0100
Branches: master
https://developer.blender.org/rBAd0dee32d2b5f653ef25843ad3bd542836ec788d8

glTF importer: manage texture wrap modes.

Thanks scurest!

===================================================================

M	io_scene_gltf2/__init__.py
M	io_scene_gltf2/blender/imp/gltf2_blender_texture.py

===================================================================

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



More information about the Bf-extensions-cvs mailing list