glTF importer: manage texture wrap modes.
Thanks scurest!
This commit is contained in:
parent
f3683cf7bf
commit
d0dee32d2b
|
@ -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',
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue