From a99a62231e040a15c93add9ffa582ec9e1d9c4f1 Mon Sep 17 00:00:00 2001 From: Aras Pranckevicius Date: Tue, 13 Sep 2022 13:28:57 +0300 Subject: obj: implement support for PBR .mtl extensions Implement import & export support for "PBR extensions" in .mtl files (T101029, also fixes T86736). Newly supported parameters: - Roughness (Pr, map_Pr) - Metallic (Pm, map_Pm) - Sheen (Ps, map_Ps) - Clearcoat thickness (Pc) and roughness (Pcr) - Anisotropy (aniso) and rotation (anisor) - Transmittance (Tf / Kt) Exporter has an option to enable these additional PBR parameters export; defaults to off since not all software understands that. Exporter UI tweaked and all material-related options were put into their own separate box. Added/extended test files in Subversion repository for test coverage. --- .../importer/obj_import_file_reader.cc | 33 ++++++++++++++++++++++ .../io/wavefront_obj/importer/obj_import_mtl.cc | 32 +++++++++++++++++++++ 2 files changed, 65 insertions(+) (limited to 'source/blender/io/wavefront_obj/importer') diff --git a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc index cc98dbdbf92..f92f9894f75 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc @@ -617,6 +617,15 @@ static MTLTexMapType mtl_line_start_to_texture_type(const char *&p, const char * parse_keyword(p, end, "map_bump")) { return MTLTexMapType::Normal; } + if (parse_keyword(p, end, "map_Pr")) { + return MTLTexMapType::Roughness; + } + if (parse_keyword(p, end, "map_Pm")) { + return MTLTexMapType::Metallic; + } + if (parse_keyword(p, end, "map_Ps")) { + return MTLTexMapType::Sheen; + } return MTLTexMapType::Count; } @@ -806,6 +815,30 @@ void MTLParser::parse_and_store(Map> &r_mat parse_float(p, end, 1.0f, val); material->illum_mode = val; } + else if (parse_keyword(p, end, "Pr")) { + parse_float(p, end, 0.5f, material->roughness); + } + else if (parse_keyword(p, end, "Pm")) { + parse_float(p, end, 0.0f, material->metallic); + } + else if (parse_keyword(p, end, "Ps")) { + parse_float(p, end, 0.0f, material->sheen); + } + else if (parse_keyword(p, end, "Pc")) { + parse_float(p, end, 0.0f, material->cc_thickness); + } + else if (parse_keyword(p, end, "Pcr")) { + parse_float(p, end, 0.0f, material->cc_roughness); + } + else if (parse_keyword(p, end, "aniso")) { + parse_float(p, end, 0.0f, material->aniso); + } + else if (parse_keyword(p, end, "anisor")) { + parse_float(p, end, 0.0f, material->aniso_rot); + } + else if (parse_keyword(p, end, "Kt") || parse_keyword(p, end, "Tf")) { + parse_floats(p, end, 0.0f, material->transmit_color, 3); + } else { parse_texture_map(p, end, material, mtl_dir_path_); } diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc b/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc index 2819fe9efc8..c471b2002de 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc @@ -284,6 +284,14 @@ static void set_bsdf_socket_values(bNode *bsdf, Material *mat, const MTLMaterial alpha = 1.0f; } + /* PBR values, when present, override the ones calculated above. */ + if (mtl_mat.roughness >= 0) { + roughness = mtl_mat.roughness; + } + if (mtl_mat.metallic >= 0) { + metallic = mtl_mat.metallic; + } + float3 base_color = mtl_mat.color; if (base_color.x >= 0 && base_color.y >= 0 && base_color.z >= 0) { set_property_of_socket(SOCK_RGBA, "Base Color", {base_color, 3}, bsdf); @@ -314,6 +322,30 @@ static void set_bsdf_socket_values(bNode *bsdf, Material *mat, const MTLMaterial if (do_tranparency || (alpha >= 0.0f && alpha < 1.0f)) { mat->blend_method = MA_BM_BLEND; } + + if (mtl_mat.sheen >= 0) { + set_property_of_socket(SOCK_FLOAT, "Sheen", {mtl_mat.sheen}, bsdf); + } + if (mtl_mat.cc_thickness >= 0) { + set_property_of_socket(SOCK_FLOAT, "Clearcoat", {mtl_mat.cc_thickness}, bsdf); + } + if (mtl_mat.cc_roughness >= 0) { + set_property_of_socket(SOCK_FLOAT, "Clearcoat Roughness", {mtl_mat.cc_roughness}, bsdf); + } + if (mtl_mat.aniso >= 0) { + set_property_of_socket(SOCK_FLOAT, "Anisotropic", {mtl_mat.aniso}, bsdf); + } + if (mtl_mat.aniso_rot >= 0) { + set_property_of_socket(SOCK_FLOAT, "Anisotropic Rotation", {mtl_mat.aniso_rot}, bsdf); + } + + /* Transmission: average of transmission color. */ + float transmission = (mtl_mat.transmit_color[0] + mtl_mat.transmit_color[1] + + mtl_mat.transmit_color[2]) / + 3; + if (transmission >= 0) { + set_property_of_socket(SOCK_FLOAT, "Transmission", {transmission}, bsdf); + } } static void add_image_textures(Main *bmain, -- cgit v1.2.3