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/exp/gltf2_blender_gather_sampler.py')
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_sampler.py99
1 files changed, 88 insertions, 11 deletions
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_sampler.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_sampler.py
index abbd7e94..40dfdb16 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_sampler.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_sampler.py
@@ -17,18 +17,25 @@ from io_scene_gltf2.io.com import gltf2_io
from io_scene_gltf2.blender.exp.gltf2_blender_gather_cache import cached
from io_scene_gltf2.io.exp.gltf2_io_user_extensions import export_user_extensions
from io_scene_gltf2.io.com.gltf2_io_constants import TextureFilter, TextureWrap
+from io_scene_gltf2.blender.exp.gltf2_blender_get import (
+ previous_node,
+ previous_socket,
+ get_const_from_socket,
+)
@cached
def gather_sampler(blender_shader_node: bpy.types.Node, export_settings):
+ wrap_s, wrap_t = __gather_wrap(blender_shader_node, export_settings)
+
sampler = gltf2_io.Sampler(
extensions=__gather_extensions(blender_shader_node, export_settings),
extras=__gather_extras(blender_shader_node, export_settings),
mag_filter=__gather_mag_filter(blender_shader_node, export_settings),
min_filter=__gather_min_filter(blender_shader_node, export_settings),
name=__gather_name(blender_shader_node, export_settings),
- wrap_s=__gather_wrap_s(blender_shader_node, export_settings),
- wrap_t=__gather_wrap_t(blender_shader_node, export_settings)
+ wrap_s=wrap_s,
+ wrap_t=wrap_t,
)
export_user_extensions('gather_sampler_hook', export_settings, sampler, blender_shader_node)
@@ -83,13 +90,83 @@ def __gather_name(blender_shader_node, export_settings):
return None
-def __gather_wrap_s(blender_shader_node, export_settings):
- if blender_shader_node.extension == 'EXTEND':
- return TextureWrap.ClampToEdge
- return None
-
-
-def __gather_wrap_t(blender_shader_node, export_settings):
+def __gather_wrap(blender_shader_node, export_settings):
+ # First gather from the Texture node
if blender_shader_node.extension == 'EXTEND':
- return TextureWrap.ClampToEdge
- return None
+ wrap_s = TextureWrap.ClampToEdge
+ elif blender_shader_node.extension == 'CLIP':
+ # Not possible in glTF, but ClampToEdge is closest
+ wrap_s = TextureWrap.ClampToEdge
+ else:
+ wrap_s = TextureWrap.Repeat
+ wrap_t = wrap_s
+
+ # Take manual wrapping into account
+ result = detect_manual_uv_wrapping(blender_shader_node)
+ if result:
+ if result['wrap_s'] is not None: wrap_s = result['wrap_s']
+ if result['wrap_t'] is not None: wrap_t = result['wrap_t']
+
+ # Omit if both are repeat
+ if (wrap_s, wrap_t) == (TextureWrap.Repeat, TextureWrap.Repeat):
+ wrap_s, wrap_t = None, None
+
+ return wrap_s, wrap_t
+
+
+def detect_manual_uv_wrapping(blender_shader_node):
+ # Detects UV wrapping done using math nodes. This is for emulating wrap
+ # modes Blender doesn't support. It looks like
+ #
+ # next_socket => [Sep XYZ] => [Wrap S] => [Comb XYZ] => blender_shader_node
+ # => [Wrap T] =>
+ #
+ # The [Wrap _] blocks are either math nodes (eg. PINGPONG for mirrored
+ # repeat), or can be omitted.
+ #
+ # Returns None if not detected. Otherwise a dict containing the wrap
+ # mode in each direction (or None), and next_socket.
+ result = {}
+
+ comb = previous_node(blender_shader_node.inputs['Vector'])
+ if comb is None or comb.type != 'COMBXYZ': return None
+
+ for soc in ['X', 'Y']:
+ node = previous_node(comb.inputs[soc])
+ if node is None: return None
+
+ if node.type == 'SEPXYZ':
+ # Passed through without change
+ wrap = None
+ prev_socket = previous_socket(comb.inputs[soc])
+ elif node.type == 'MATH':
+ # Math node applies a manual wrap
+ if (node.operation == 'PINGPONG' and
+ get_const_from_socket(node.inputs[1], kind='VALUE') == 1.0): # scale = 1
+ wrap = TextureWrap.MirroredRepeat
+ elif (node.operation == 'WRAP' and
+ get_const_from_socket(node.inputs[1], kind='VALUE') == 0.0 and # min = 0
+ get_const_from_socket(node.inputs[2], kind='VALUE') == 1.0): # max = 1
+ wrap = TextureWrap.Repeat
+ else:
+ return None
+
+ prev_socket = previous_socket(node.inputs[0])
+ else:
+ return None
+
+ if prev_socket is None: return None
+ prev_node = prev_socket.node
+ if prev_node.type != 'SEPXYZ': return None
+ # Make sure X goes to X, etc.
+ if prev_socket.name != soc: return None
+ # Make sure both attach to the same SeparateXYZ node
+ if soc == 'X':
+ sep = prev_node
+ else:
+ if sep != prev_node: return None
+
+ result['wrap_s' if soc == 'X' else 'wrap_t'] = wrap
+
+ result['next_socket'] = sep.inputs[0]
+ return result