From 44dd3564bb3517efa1aa290a74a7683b1a814457 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 15 May 2019 21:00:32 +0200 Subject: FBX IO: use new Principled BSDF Alpha option for transparency. Much better option than using Principled's Transmission setting. Related to T64609. --- io_scene_fbx/__init__.py | 2 +- io_scene_fbx/export_fbx_bin.py | 10 +++++----- io_scene_fbx/import_fbx.py | 23 +++++++++++++++++------ 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py index 693cfe7d..dfe55f17 100644 --- a/io_scene_fbx/__init__.py +++ b/io_scene_fbx/__init__.py @@ -21,7 +21,7 @@ bl_info = { "name": "FBX format", "author": "Campbell Barton, Bastien Montagne, Jens Restemeier", - "version": (4, 14, 7), + "version": (4, 14, 8), "blender": (2, 80, 0), "location": "File > Import-Export", "description": "FBX IO meshes, UV's, vertex colors, materials, textures, cameras, lamps and actions", diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py index 48dabc25..af3bc005 100644 --- a/io_scene_fbx/export_fbx_bin.py +++ b/io_scene_fbx/export_fbx_bin.py @@ -1265,12 +1265,12 @@ def fbx_data_material_elements(root, ma, scene_data): # alpha = 1 - TransparentColor.r # # Until further info, let's assume this is correct way to do, hence the following code for TransparentColor. - if ma_wrap.transmission < 1.0e-5 or ma_wrap.transmission > (1.0 - 1.0e-5): - elem_props_template_set(tmpl, props, "p_color", b"TransparentColor", (ma_wrap.transmission,) * 3) + if ma_wrap.alpha < 1.0e-5 or ma_wrap.alpha > (1.0 - 1.0e-5): + elem_props_template_set(tmpl, props, "p_color", b"TransparentColor", (1.0 - ma_wrap.alpha,) * 3) else: elem_props_template_set(tmpl, props, "p_color", b"TransparentColor", ma_wrap.base_color) - elem_props_template_set(tmpl, props, "p_number", b"TransparencyFactor", ma_wrap.transmission) - elem_props_template_set(tmpl, props, "p_number", b"Opacity", 1.0 - ma_wrap.transmission) + elem_props_template_set(tmpl, props, "p_number", b"TransparencyFactor", 1.0 - ma_wrap.alpha) + elem_props_template_set(tmpl, props, "p_number", b"Opacity", ma_wrap.alpha) elem_props_template_set(tmpl, props, "p_vector_3d", b"NormalMap", (0.0, 0.0, 0.0)) # Not sure about those... """ @@ -1748,7 +1748,7 @@ def fbx_data_animation_elements(root, scene_data): PRINCIPLED_TEXTURE_SOCKETS_TO_FBX = ( # ("diffuse", "diffuse", b"DiffuseFactor"), ("base_color_texture", b"DiffuseColor"), - ("transmission_texture", b"TransparencyFactor"), + ("alpha_texture", b"TransparencyFactor"), # Will be inverted in fact, not much we can do really... # ("base_color_texture", b"TransparentColor"), # Uses diffuse color in Blender! # ("emit", "emit", b"EmissiveFactor"), # ("diffuse", "diffuse", b"EmissiveColor"), # Uses diffuse color in Blender! diff --git a/io_scene_fbx/import_fbx.py b/io_scene_fbx/import_fbx.py index 10ac8aed..c24c2ae3 100644 --- a/io_scene_fbx/import_fbx.py +++ b/io_scene_fbx/import_fbx.py @@ -1332,6 +1332,7 @@ def blen_read_material(fbx_tmpl, fbx_obj, settings): ma = bpy.data.materials.new(name=elem_name_utf8) const_color_white = 1.0, 1.0, 1.0 + const_color_black = 0.0, 0.0, 0.0 fbx_props = (elem_find_first(fbx_obj, b'Properties70'), elem_find_first(fbx_tmpl, b'Properties70', fbx_elem_nil)) @@ -1345,7 +1346,18 @@ def blen_read_material(fbx_tmpl, fbx_obj, settings): # (from 1.0 - 0.0 Principled BSDF range to 0.0 - 100.0 FBX shininess range)... fbx_shininess = elem_props_get_number(fbx_props, b'Shininess', 20.0) ma_wrap.roughness = 1.0 - (sqrt(fbx_shininess) / 10.0) - ma_wrap.transmission = 1.0 - elem_props_get_number(fbx_props, b'Opacity', 1.0) + # Sweetness... Looks like we are not the only ones to not know exactly how FBX is supposed to work (see T59850). + # According to one of its developers, Unity uses that formula to extract alpha value: + # + # alpha = 1 - TransparencyFactor + # if (alpha == 1 or alpha == 0): + # alpha = 1 - TransparentColor.r + # + # Until further info, let's assume this is correct way to do, hence the following code for TransparentColor. + alpha = 1.0 - elem_props_get_number(fbx_props, b'TransparencyFactor', 0.0) + if (alpha == 1.0 or alpha == 0.0): + alpha = 1.0 - elem_props_get_color_rgb(fbx_props, b'TransparentColor', const_color_black)[0] + ma_wrap.alpha = alpha ma_wrap.metallic = elem_props_get_number(fbx_props, b'ReflectionFactor', 0.0) # We have no metallic (a.k.a. reflection) color... # elem_props_get_color_rgb(fbx_props, b'ReflectionColor', const_color_white) @@ -2989,9 +3001,8 @@ def load(operator, context, filepath="", ma_wrap.metallic_texture.image = image texture_mapping_set(fbx_lnk, ma_wrap.metallic_texture) elif lnk_type in {b'TransparentColor', b'TransparentFactor'}: - # Transparency... sort of... - ma_wrap.transmission_texture.image = image - texture_mapping_set(fbx_lnk, ma_wrap.transmission_texture) + ma_wrap.alpha_texture.image = image + texture_mapping_set(fbx_lnk, ma_wrap.alpha_texture) if use_alpha_decals: material_decals.add(material) elif lnk_type == b'ShininessExponent': @@ -3027,8 +3038,8 @@ def load(operator, context, filepath="", material_decals.add(material) ma_wrap = nodal_material_wrap_map[material] - ma_wrap.transmission_texture.use_alpha = True - ma_wrap.transmission_texture.copy_from(ma_wrap.base_color_texture) + ma_wrap.alpha_texture.use_alpha = True + ma_wrap.alpha_texture.copy_from(ma_wrap.base_color_texture) # Propagate mapping from diffuse to all other channels which have none defined. # XXX Commenting for now, I do not really understand the logic here, why should diffuse mapping -- cgit v1.2.3