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_image.py')
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_image.py95
1 files changed, 84 insertions, 11 deletions
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py
index 0dfce9f9..81e79a50 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py
@@ -11,7 +11,7 @@ from io_scene_gltf2.blender.exp import gltf2_blender_search_node_tree
from io_scene_gltf2.io.exp import gltf2_io_binary_data
from io_scene_gltf2.io.exp import gltf2_io_image_data
from io_scene_gltf2.io.com import gltf2_io_debug
-from io_scene_gltf2.blender.exp.gltf2_blender_image import Channel, ExportImage, FillImage
+from io_scene_gltf2.blender.exp.gltf2_blender_image import Channel, ExportImage, FillImage, StoreImage, StoreData
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
@@ -21,26 +21,31 @@ def gather_image(
blender_shader_sockets: typing.Tuple[bpy.types.NodeSocket],
export_settings):
if not __filter_image(blender_shader_sockets, export_settings):
- return None
+ return None, None
image_data = __get_image_data(blender_shader_sockets, export_settings)
if image_data.empty():
# The export image has no data
- return None
+ return None, None
mime_type = __gather_mime_type(blender_shader_sockets, image_data, export_settings)
name = __gather_name(image_data, export_settings)
+ factor = None
+
if image_data.original is None:
- uri = __gather_uri(image_data, mime_type, name, export_settings)
+ uri, factor_uri = __gather_uri(image_data, mime_type, name, export_settings)
else:
# Retrieve URI relative to exported glTF files
uri = __gather_original_uri(image_data.original.filepath, export_settings)
# In case we can't retrieve image (for example packed images, with original moved)
# We don't create invalid image without uri
+ factor_uri = None
if uri is None: return None
- buffer_view = __gather_buffer_view(image_data, mime_type, name, export_settings)
+ buffer_view, factor_buffer_view = __gather_buffer_view(image_data, mime_type, name, export_settings)
+
+ factor = factor_uri if uri is not None else factor_buffer_view
image = __make_image(
buffer_view,
@@ -54,7 +59,7 @@ def gather_image(
export_user_extensions('gather_image_hook', export_settings, image, blender_shader_sockets)
- return image
+ return image, factor
def __gather_original_uri(original_uri, export_settings):
@@ -98,8 +103,9 @@ def __filter_image(sockets, export_settings):
@cached
def __gather_buffer_view(image_data, mime_type, name, export_settings):
if export_settings[gltf2_blender_export_keys.FORMAT] != 'GLTF_SEPARATE':
- return gltf2_io_binary_data.BinaryData(data=image_data.encode(mime_type))
- return None
+ data, factor = image_data.encode(mime_type)
+ return gltf2_io_binary_data.BinaryData(data=data), factor
+ return None, None
def __gather_extensions(sockets, export_settings):
@@ -165,13 +171,14 @@ def __gather_name(export_image, export_settings):
def __gather_uri(image_data, mime_type, name, export_settings):
if export_settings[gltf2_blender_export_keys.FORMAT] == 'GLTF_SEPARATE':
# as usual we just store the data in place instead of already resolving the references
+ data, factor = image_data.encode(mime_type=mime_type)
return gltf2_io_image_data.ImageData(
- data=image_data.encode(mime_type=mime_type),
+ data=data,
mime_type=mime_type,
name=name
- )
+ ), factor
- return None
+ return None, None
def __get_image_data(sockets, export_settings) -> ExportImage:
@@ -179,6 +186,18 @@ def __get_image_data(sockets, export_settings) -> ExportImage:
# in a helper class. During generation of the glTF in the exporter these will then be combined to actual binary
# resources.
results = [__get_tex_from_socket(socket, export_settings) for socket in sockets]
+
+ # Check if we need a simple mapping or more complex calculation
+ if any([socket.name == "Specular" and socket.node.type == "BSDF_PRINCIPLED" for socket in sockets]):
+ return __get_image_data_specular(sockets, results, export_settings)
+ else:
+ return __get_image_data_mapping(sockets, results, export_settings)
+
+def __get_image_data_mapping(sockets, results, export_settings) -> ExportImage:
+ """
+ Simple mapping
+ Will fit for most of exported textures : RoughnessMetallic, Basecolor, normal, ...
+ """
composed_image = ExportImage()
for result, socket in zip(results, sockets):
# Assume that user know what he does, and that channels/images are already combined correctly for pbr
@@ -217,6 +236,12 @@ def __get_image_data(sockets, export_settings) -> ExportImage:
dst_chan = Channel.R
elif socket.name == 'Clearcoat Roughness':
dst_chan = Channel.G
+ elif socket.name == 'Thickness': # For KHR_materials_volume
+ dst_chan = Channel.G
+ elif socket.name == "Specular": # For original KHR_material_specular
+ dst_chan = Channel.A
+ elif socket.name == "Sigma": # For KHR_materials_sheen
+ dst_chan = Channel.A
if dst_chan is not None:
composed_image.fill_image(result.shader_node.image, dst_chan, src_chan)
@@ -243,6 +268,54 @@ def __get_image_data(sockets, export_settings) -> ExportImage:
return composed_image
+def __get_image_data_specular(sockets, results, export_settings) -> ExportImage:
+ """
+ calculating Specular Texture, settings needed data
+ """
+ from io_scene_gltf2.blender.exp.gltf2_blender_texture_specular import specular_calculation
+ composed_image = ExportImage()
+ composed_image.set_calc(specular_calculation)
+
+ composed_image.store_data("ior", sockets[4].default_value, type="Data")
+
+ results = [__get_tex_from_socket(socket, export_settings) for socket in sockets[:-1]] #Do not retrieve IOR --> No texture allowed
+
+ mapping = {
+ 0: "specular",
+ 1: "specular_tint",
+ 2: "base_color",
+ 3: "transmission"
+ }
+
+ for idx, result in enumerate(results):
+ if __get_tex_from_socket(sockets[idx], export_settings):
+
+ composed_image.store_data(mapping[idx], result.shader_node.image, type="Image")
+
+ # rudimentarily try follow the node tree to find the correct image data.
+ src_chan = None if idx == 2 else Channel.R
+ for elem in result.path:
+ if isinstance(elem.from_node, bpy.types.ShaderNodeSeparateColor):
+ src_chan = {
+ 'Red': Channel.R,
+ 'Green': Channel.G,
+ 'Blue': Channel.B,
+ }[elem.from_socket.name]
+ if elem.from_socket.name == 'Alpha':
+ src_chan = Channel.A
+ # For base_color, keep all channels, as this is a Vec, not scalar
+ if idx != 2:
+ composed_image.store_data(mapping[idx] + "_channel", src_chan, type="Data")
+ else:
+ if src_chan is not None:
+ composed_image.store_data(mapping[idx] + "_channel", src_chan, type="Data")
+
+ else:
+ composed_image.store_data(mapping[idx], sockets[idx].default_value, type="Data")
+
+ return composed_image
+
+# TODOExt deduplicate
@cached
def __get_tex_from_socket(blender_shader_socket: bpy.types.NodeSocket, export_settings):
result = gltf2_blender_search_node_tree.from_socket(