diff options
Diffstat (limited to 'source/blender/io/wavefront_obj/exporter')
5 files changed, 111 insertions, 15 deletions
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc index 27526734624..f2547e6fc14 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc @@ -493,11 +493,14 @@ void OBJWriter::write_nurbs_curve(FormatHandler &fh, const OBJCurve &obj_nurbs_d static const char *tex_map_type_to_string[] = { "map_Kd", + "map_Pm", "map_Ks", "map_Ns", - "map_d", + "map_Pr", + "map_Ps", "map_refl", "map_Ke", + "map_d", "map_Bump", }; BLI_STATIC_ASSERT(ARRAY_SIZE(tex_map_type_to_string) == (int)MTLTexMapType::Count, @@ -553,16 +556,20 @@ StringRefNull MTLWriter::mtl_file_path() const return mtl_filepath_; } -void MTLWriter::write_bsdf_properties(const MTLMaterial &mtl) +void MTLWriter::write_bsdf_properties(const MTLMaterial &mtl, bool write_pbr) { /* For various material properties, we only capture information * coming from the texture, or the default value of the socket. * When the texture is present, do not emit the default value. */ - if (!mtl.tex_map_of_type(MTLTexMapType::SpecularExponent).is_valid()) { - fmt_handler_.write_mtl_float("Ns", mtl.spec_exponent); + + /* Do not write Ns & Ka when writing in PBR mode. */ + if (!write_pbr) { + if (!mtl.tex_map_of_type(MTLTexMapType::SpecularExponent).is_valid()) { + fmt_handler_.write_mtl_float("Ns", mtl.spec_exponent); + } + fmt_handler_.write_mtl_float3( + "Ka", mtl.ambient_color.x, mtl.ambient_color.y, mtl.ambient_color.z); } - fmt_handler_.write_mtl_float3( - "Ka", mtl.ambient_color.x, mtl.ambient_color.y, mtl.ambient_color.z); if (!mtl.tex_map_of_type(MTLTexMapType::Color).is_valid()) { fmt_handler_.write_mtl_float3("Kd", mtl.color.x, mtl.color.y, mtl.color.z); } @@ -578,6 +585,35 @@ void MTLWriter::write_bsdf_properties(const MTLMaterial &mtl) fmt_handler_.write_mtl_float("d", mtl.alpha); } fmt_handler_.write_mtl_illum(mtl.illum_mode); + + if (write_pbr) { + if (!mtl.tex_map_of_type(MTLTexMapType::Roughness).is_valid() && mtl.roughness >= 0.0f) { + fmt_handler_.write_mtl_float("Pr", mtl.roughness); + } + if (!mtl.tex_map_of_type(MTLTexMapType::Metallic).is_valid() && mtl.metallic >= 0.0f) { + fmt_handler_.write_mtl_float("Pm", mtl.metallic); + } + if (!mtl.tex_map_of_type(MTLTexMapType::Sheen).is_valid() && mtl.sheen >= 0.0f) { + fmt_handler_.write_mtl_float("Ps", mtl.sheen); + } + if (mtl.cc_thickness >= 0.0f) { + fmt_handler_.write_mtl_float("Pc", mtl.cc_thickness); + } + if (mtl.cc_roughness >= 0.0f) { + fmt_handler_.write_mtl_float("Pcr", mtl.cc_roughness); + } + if (mtl.aniso >= 0.0f) { + fmt_handler_.write_mtl_float("aniso", mtl.aniso); + } + if (mtl.aniso_rot >= 0.0f) { + fmt_handler_.write_mtl_float("anisor", mtl.aniso_rot); + } + if (mtl.transmit_color.x > 0.0f || mtl.transmit_color.y > 0.0f || + mtl.transmit_color.z > 0.0f) { + fmt_handler_.write_mtl_float3( + "Tf", mtl.transmit_color.x, mtl.transmit_color.y, mtl.transmit_color.z); + } + } } void MTLWriter::write_texture_map(const MTLMaterial &mtl_material, @@ -608,9 +644,21 @@ void MTLWriter::write_texture_map(const MTLMaterial &mtl_material, fmt_handler_.write_mtl_map(tex_map_type_to_string[(int)texture_key], options, path); } +static bool is_pbr_map(MTLTexMapType type) +{ + return type == MTLTexMapType::Metallic || type == MTLTexMapType::Roughness || + type == MTLTexMapType::Sheen; +} + +static bool is_non_pbr_map(MTLTexMapType type) +{ + return type == MTLTexMapType::SpecularExponent || type == MTLTexMapType::Reflection; +} + void MTLWriter::write_materials(const char *blen_filepath, ePathReferenceMode path_mode, - const char *dest_dir) + const char *dest_dir, + bool write_pbr) { if (mtlmaterials_.size() == 0) { return; @@ -628,12 +676,18 @@ void MTLWriter::write_materials(const char *blen_filepath, for (const MTLMaterial &mtlmat : mtlmaterials_) { fmt_handler_.write_string(""); fmt_handler_.write_mtl_newmtl(mtlmat.name); - write_bsdf_properties(mtlmat); + write_bsdf_properties(mtlmat, write_pbr); for (int key = 0; key < (int)MTLTexMapType::Count; key++) { const MTLTexMap &tex = mtlmat.texture_maps[key]; if (!tex.is_valid()) { continue; } + if (!write_pbr && is_pbr_map((MTLTexMapType)key)) { + continue; + } + if (write_pbr && is_non_pbr_map((MTLTexMapType)key)) { + continue; + } write_texture_map( mtlmat, (MTLTexMapType)key, tex, blen_filedir, dest_dir, path_mode, copy_set); } diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh index 4544037fbc1..eda4576297b 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh @@ -186,7 +186,8 @@ class MTLWriter : NonMovable, NonCopyable { */ void write_materials(const char *blen_filepath, ePathReferenceMode path_mode, - const char *dest_dir); + const char *dest_dir, + bool write_pbr); StringRefNull mtl_file_path() const; /** * Add the materials of the given object to #MTLWriter, de-duplicating @@ -203,7 +204,7 @@ class MTLWriter : NonMovable, NonCopyable { /** * Write properties sourced from p-BSDF node or #Object.Material. */ - void write_bsdf_properties(const MTLMaterial &mtl_material); + void write_bsdf_properties(const MTLMaterial &mtl_material, bool write_pbr); /** * Write a texture map in the form "map_XX -s 1. 1. 1. -o 0. 0. 0. [-bm 1.] path/to/image". */ diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc index 77cad18a040..f8c7da75a70 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc @@ -23,11 +23,14 @@ namespace blender::io::obj { const char *tex_map_type_to_socket_id[] = { "Base Color", + "Metallic", "Specular", + "Roughness", /* Map specular exponent to roughness. */ "Roughness", - "Alpha", - "Metallic", + "Sheen", + "Metallic", /* Map reflection to metallic. */ "Emission", + "Alpha", "Normal", }; BLI_STATIC_ASSERT(ARRAY_SIZE(tex_map_type_to_socket_id) == (int)MTLTexMapType::Count, @@ -188,7 +191,6 @@ static void store_bsdf_properties(const bNode *bsdf_node, const Material *material, MTLMaterial &r_mtl_mat) { - /* If p-BSDF is not present, fallback to #Object.Material. */ float roughness = material->roughness; if (bsdf_node) { copy_property_from_node(SOCK_FLOAT, bsdf_node, "Roughness", {&roughness, 1}); @@ -231,6 +233,22 @@ static void store_bsdf_properties(const bNode *bsdf_node, } mul_v3_fl(emission_col, emission_strength); + float sheen = -1.0f; + float clearcoat = -1.0f; + float clearcoat_roughness = -1.0f; + float aniso = -1.0f; + float aniso_rot = -1.0f; + float transmission = -1.0f; + if (bsdf_node) { + copy_property_from_node(SOCK_FLOAT, bsdf_node, "Sheen", {&sheen, 1}); + copy_property_from_node(SOCK_FLOAT, bsdf_node, "Clearcoat", {&clearcoat, 1}); + copy_property_from_node( + SOCK_FLOAT, bsdf_node, "Clearcoat Roughness", {&clearcoat_roughness, 1}); + copy_property_from_node(SOCK_FLOAT, bsdf_node, "Anisotropic", {&aniso, 1}); + copy_property_from_node(SOCK_FLOAT, bsdf_node, "Anisotropic Rotation", {&aniso_rot, 1}); + copy_property_from_node(SOCK_FLOAT, bsdf_node, "Transmission", {&transmission, 1}); + } + /* See https://wikipedia.org/wiki/Wavefront_.obj_file for all possible values of `illum`. */ /* Highlight on. */ int illum = 2; @@ -266,6 +284,14 @@ static void store_bsdf_properties(const bNode *bsdf_node, r_mtl_mat.ior = refraction_index; r_mtl_mat.alpha = alpha; r_mtl_mat.illum_mode = illum; + r_mtl_mat.roughness = roughness; + r_mtl_mat.metallic = metallic; + r_mtl_mat.sheen = sheen; + r_mtl_mat.cc_thickness = clearcoat; + r_mtl_mat.cc_roughness = clearcoat_roughness; + r_mtl_mat.aniso = aniso; + r_mtl_mat.aniso_rot = aniso_rot; + r_mtl_mat.transmit_color = {transmission, transmission, transmission}; } /** diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh index 32933a16c4d..9c1bc2f0f8f 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh @@ -15,11 +15,14 @@ namespace blender::io::obj { enum class MTLTexMapType { Color = 0, + Metallic, Specular, SpecularExponent, - Alpha, + Roughness, + Sheen, Reflection, Emission, + Alpha, Normal, Count }; @@ -63,6 +66,15 @@ struct MTLMaterial { float3 emission_color{-1.0f}; /* `Ke` */ float ior{-1.0f}; /* `Ni` */ float alpha{-1.0f}; /* `d` */ + float3 transmit_color{-1.0f}; /* `Kt` / `Tf` */ + float roughness{-1.0f}; /* `Pr` */ + float metallic{-1.0f}; /* `Pm` */ + float sheen{-1.0f}; /* `Ps` */ + float cc_thickness{-1.0f}; /* `Pc` */ + float cc_roughness{-1.0f}; /* `Pcr` */ + float aniso{-1.0f}; /* `aniso` */ + float aniso_rot{-1.0f}; /* `anisor` */ + int illum_mode{-1}; MTLTexMap texture_maps[(int)MTLTexMapType::Count]; /* Only used for Normal Map node: `map_Bump`. */ diff --git a/source/blender/io/wavefront_obj/exporter/obj_exporter.cc b/source/blender/io/wavefront_obj/exporter/obj_exporter.cc index 294ea81fd58..a51c017f81d 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_exporter.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_exporter.cc @@ -293,7 +293,10 @@ void export_frame(Depsgraph *depsgraph, const OBJExportParams &export_params, co } BLI_path_slash_native(dest_dir); BLI_path_normalize(nullptr, dest_dir); - mtl_writer->write_materials(export_params.blen_filepath, export_params.path_mode, dest_dir); + mtl_writer->write_materials(export_params.blen_filepath, + export_params.path_mode, + dest_dir, + export_params.export_pbr_extensions); } write_nurbs_curve_objects(std::move(exportable_as_nurbs), *frame_writer); } |