[Bf-extensions-cvs] [b3257c11] blender2.8: FBX IO: add support for exporting nodal shaders.

Bastien Montagne noreply at git.blender.org
Tue Oct 16 20:01:18 CEST 2018


Commit: b3257c11365e38436a86a73cf42a300a305c33aa
Author: Bastien Montagne
Date:   Tue Oct 16 16:35:49 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBAb3257c11365e38436a86a73cf42a300a305c33aa

FBX IO: add support for exporting nodal shaders.

Getting textures to work was a bit tricky, since we basically have no
more texture IDs in modern shaders (they are mere nodes).

Modified specular conversion to be quadratic (between FBX Phong exponent
to Pricipled specular factor).

Also fixed several issues in both importers and exporters.

And cleaned up ugly usage of 'mat' short name for materials in exporter
(mat is reserved for matrix in Blneder code in general, 'ma' is short
for material).

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

M	io_scene_fbx/__init__.py
M	io_scene_fbx/export_fbx_bin.py
M	io_scene_fbx/fbx_utils.py
M	io_scene_fbx/import_fbx.py

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

diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py
index d9d70441..07d8a3b2 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, 11, 0),
+    "version": (4, 12, 0),
     "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 006a343b..165befae 100644
--- a/io_scene_fbx/export_fbx_bin.py
+++ b/io_scene_fbx/export_fbx_bin.py
@@ -41,6 +41,7 @@ if "bpy" in locals():
 
 import bpy
 import bpy_extras
+from bpy_extras import node_shader_utils
 from mathutils import Vector, Matrix
 
 from . import encode_bin, data_types, fbx_utils
@@ -75,6 +76,7 @@ from .fbx_utils import (
     get_blender_bindpose_key, get_blender_armature_skin_key, get_blender_bone_cluster_key,
     get_blender_anim_id_base, get_blender_anim_stack_key, get_blender_anim_layer_key,
     get_blender_anim_curve_node_key, get_blender_anim_curve_key,
+    get_blender_nodetexture_key,
     # FBX element data.
     elem_empty,
     elem_data_single_bool, elem_data_single_int16, elem_data_single_int32, elem_data_single_int64,
@@ -1111,38 +1113,39 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
         del _uvtuples_gen
 
     # Face's materials.
-    me_fbxmats_idx = scene_data.mesh_mat_indices.get(me)
-    if me_fbxmats_idx is not None:
-        me_blmats = me.materials
-        if me_fbxmats_idx and me_blmats:
-            lay_mat = elem_data_single_int32(geom, b"LayerElementMaterial", 0)
-            elem_data_single_int32(lay_mat, b"Version", FBX_GEOMETRY_MATERIAL_VERSION)
-            elem_data_single_string(lay_mat, b"Name", b"")
-            nbr_mats = len(me_fbxmats_idx)
+    me_fbxmaterials_idx = scene_data.mesh_material_indices.get(me)
+    if me_fbxmaterials_idx is not None:
+        me_blmaterials = me.materials
+        if me_fbxmaterials_idx and me_blmaterials:
+            lay_ma = elem_data_single_int32(geom, b"LayerElementMaterial", 0)
+            elem_data_single_int32(lay_ma, b"Version", FBX_GEOMETRY_MATERIAL_VERSION)
+            elem_data_single_string(lay_ma, b"Name", b"")
+            nbr_mats = len(me_fbxmaterials_idx)
             if nbr_mats > 1:
                 t_pm = array.array(data_types.ARRAY_INT32, (0,)) * len(me.polygons)
                 me.polygons.foreach_get("material_index", t_pm)
 
                 # We have to validate mat indices, and map them to FBX indices.
                 # Note a mat might not be in me_fbxmats_idx (e.g. node mats are ignored).
-                blmats_to_fbxmats_idxs = [me_fbxmats_idx[m] for m in me_blmats if m in me_fbxmats_idx]
-                mat_idx_limit = len(blmats_to_fbxmats_idxs)
-                def_mat = blmats_to_fbxmats_idxs[0]
-                _gen = (blmats_to_fbxmats_idxs[m] if m < mat_idx_limit else def_mat for m in t_pm)
+                blmaterials_to_fbxmaterials_idxs = [me_fbxmaterials_idx[m]
+                                                    for m in me_blmaterials if m in me_fbxmaterials_idx]
+                ma_idx_limit = len(blmaterials_to_fbxmaterials_idxs)
+                def_ma = blmaterials_to_fbxmaterials_idxs[0]
+                _gen = (blmaterials_to_fbxmaterials_idxs[m] if m < ma_idx_limit else def_ma for m in t_pm)
                 t_pm = array.array(data_types.ARRAY_INT32, _gen)
 
-                elem_data_single_string(lay_mat, b"MappingInformationType", b"ByPolygon")
+                elem_data_single_string(lay_ma, b"MappingInformationType", b"ByPolygon")
                 # XXX Logically, should be "Direct" reference type, since we do not have any index array, and have one
                 #     value per polygon...
                 #     But looks like FBX expects it to be IndexToDirect here (maybe because materials are already
                 #     indices??? *sigh*).
-                elem_data_single_string(lay_mat, b"ReferenceInformationType", b"IndexToDirect")
-                elem_data_single_int32_array(lay_mat, b"Materials", t_pm)
+                elem_data_single_string(lay_ma, b"ReferenceInformationType", b"IndexToDirect")
+                elem_data_single_int32_array(lay_ma, b"Materials", t_pm)
                 del t_pm
             else:
-                elem_data_single_string(lay_mat, b"MappingInformationType", b"AllSame")
-                elem_data_single_string(lay_mat, b"ReferenceInformationType", b"IndexToDirect")
-                elem_data_single_int32_array(lay_mat, b"Materials", [0])
+                elem_data_single_string(lay_ma, b"MappingInformationType", b"AllSame")
+                elem_data_single_string(lay_ma, b"ReferenceInformationType", b"IndexToDirect")
+                elem_data_single_int32_array(lay_ma, b"Materials", [0])
 
     # And the "layer TOC"...
 
@@ -1171,10 +1174,10 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
         lay_uv = elem_empty(layer, b"LayerElement")
         elem_data_single_string(lay_uv, b"Type", b"LayerElementUV")
         elem_data_single_int32(lay_uv, b"TypedIndex", 0)
-    if me_fbxmats_idx is not None:
-        lay_mat = elem_empty(layer, b"LayerElement")
-        elem_data_single_string(lay_mat, b"Type", b"LayerElementMaterial")
-        elem_data_single_int32(lay_mat, b"TypedIndex", 0)
+    if me_fbxmaterials_idx is not None:
+        lay_ma = elem_empty(layer, b"LayerElement")
+        elem_data_single_string(lay_ma, b"Type", b"LayerElementMaterial")
+        elem_data_single_int32(lay_ma, b"TypedIndex", 0)
 
     # Add other uv and/or vcol layers...
     for vcolidx, uvidx, tspaceidx in zip_longest(range(1, vcolnumber), range(1, uvnumber), range(1, tspacenumber),
@@ -1204,77 +1207,70 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
     done_meshes.add(me_key)
 
 
-def check_skip_material(mat):
-    """Simple helper to check whether we actually support exporting that material or not"""
-    ### TODO Fix node-to-simpleshader issue...
-    return True or mat.type not in {'SURFACE'}
-
-
-def fbx_data_material_elements(root, mat, scene_data):
+def fbx_data_material_elements(root, ma, scene_data):
     """
     Write the Material data block.
     """
+
     ambient_color = (0.0, 0.0, 0.0)
     if scene_data.data_world:
         ambient_color = next(iter(scene_data.data_world.keys())).color
 
-    mat_key, _objs = scene_data.data_materials[mat]
-    skip_mat = check_skip_material(mat)
-    node_mat = mat.use_nodes
-    mat_type = b"Phong"
-    # Approximation...
-    if not skip_mat and not node_mat and mat.specular_shader not in {'COOKTORR', 'PHONG', 'BLINN'}:
-        mat_type = b"Lambert"
+    ma_wrap = node_shader_utils.PrincipledBSDFWrapper(ma, is_readonly=True)
+    ma_key, _objs = scene_data.data_materials[ma]
+    ma_type = b"Phong"
 
-    fbx_mat = elem_data_single_int64(root, b"Material", get_fbx_uuid_from_key(mat_key))
-    fbx_mat.add_string(fbx_name_class(mat.name.encode(), b"Material"))
-    fbx_mat.add_string(b"")
+    fbx_ma = elem_data_single_int64(root, b"Material", get_fbx_uuid_from_key(ma_key))
+    fbx_ma.add_string(fbx_name_class(ma.name.encode(), b"Material"))
+    fbx_ma.add_string(b"")
 
-    elem_data_single_int32(fbx_mat, b"Version", FBX_MATERIAL_VERSION)
+    elem_data_single_int32(fbx_ma, b"Version", FBX_MATERIAL_VERSION)
     # those are not yet properties, it seems...
-    elem_data_single_string(fbx_mat, b"ShadingModel", mat_type)
-    elem_data_single_int32(fbx_mat, b"MultiLayer", 0)  # Should be bool...
+    elem_data_single_string(fbx_ma, b"ShadingModel", ma_type)
+    elem_data_single_int32(fbx_ma, b"MultiLayer", 0)  # Should be bool...
 
     tmpl = elem_props_template_init(scene_data.templates, b"Material")
-    props = elem_properties(fbx_mat)
-
-    if not skip_mat:
-        elem_props_template_set(tmpl, props, "p_string", b"ShadingModel", mat_type.decode())
-        elem_props_template_set(tmpl, props, "p_color", b"DiffuseColor", mat.diffuse_color)
-        elem_props_template_set(tmpl, props, "p_number", b"DiffuseFactor", mat.diffuse_intensity)
-        if not node_mat:
-            elem_props_template_set(tmpl, props, "p_color", b"EmissiveColor", mat.diffuse_color)
-            elem_props_template_set(tmpl, props, "p_number", b"EmissiveFactor", mat.emit)
-            elem_props_template_set(tmpl, props, "p_color", b"AmbientColor", ambient_color)
-            elem_props_template_set(tmpl, props, "p_number", b"AmbientFactor", mat.ambient)
-            elem_props_template_set(tmpl, props, "p_color", b"TransparentColor",
-                                    mat.diffuse_color if mat.use_transparency else (1.0, 1.0, 1.0))
-            elem_props_template_set(tmpl, props, "p_number", b"TransparencyFactor",
-                                    1.0 - mat.alpha if mat.use_transparency else 0.0)
-            elem_props_template_set(tmpl, props, "p_number", b"Opacity", mat.alpha if mat.use_transparency else 1.0)
-            elem_props_template_set(tmpl, props, "p_vector_3d", b"NormalMap", (0.0, 0.0, 0.0))
-            # Not sure about those...
-            """
-            b"Bump": ((0.0, 0.0, 0.0), "p_vector_3d"),
-            b"BumpFactor": (1.0, "p_double"),
-            b"DisplacementColor": ((0.0, 0.0, 0.0), "p_color_rgb"),
-            b"DisplacementFactor": (0.0, "p_double"),
-            """
-            if mat_type == b"Phong":
-                elem_props_template_set(tmpl, props, "p_color", b"SpecularColor", mat.specular_color)
-                elem_props_template_set(tmpl, props, "p_number", b"SpecularFactor", mat.specular_intensity / 2.0)
-                # See Material template about those two!
-                elem_props_template_set(tmpl, props, "p_number", b"Shininess", (mat.specular_hardness - 1.0) / 5.10)
-                elem_props_template_set(tmpl, props, "p_number", b"ShininessExponent", (mat.specular_hardness - 1.0) / 5.10)
-                elem_props_template_set(tmpl, props, "p_color", b"ReflectionColor", mat.mirror_color)
-        

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list