58 const char *from_node_id,
60 const char *to_node_id)
98 const ufbx_material_map &umap,
103 float multiplier = 1.0f)
105 if (!umap.has_value) {
106 return def * multiplier;
108 float value = umap.value_real * multiplier;
115 const ufbx_material_map &umap,
121 if (!umap.has_value || umap.value_components < 3) {
124 float3 value =
float3(umap.value_vec3.x, umap.value_vec3.y, umap.value_vec3.z);
133 mat->
r = base_color.x;
134 mat->
g = base_color.y;
135 mat->
b = base_color.z;
153 if (fmat.features.specular.enabled) {
155 bsdf, fmat.pbr.specular_factor,
"Specular IOR Level", 0.25f, 0.0f, 1.0f, 2.0f);
162 if (
ELEM(fmat.shader_type,
163 UFBX_SHADER_OSL_STANDARD_SURFACE,
164 UFBX_SHADER_ARNOLD_STANDARD_SURFACE,
165 UFBX_SHADER_3DS_MAX_PHYSICAL_MATERIAL,
166 UFBX_SHADER_3DS_MAX_PBR_METAL_ROUGH,
167 UFBX_SHADER_3DS_MAX_PBR_SPEC_GLOSS,
168 UFBX_SHADER_GLTF_MATERIAL,
169 UFBX_SHADER_BLENDER_PHONG) &&
170 fmat.features.transmission.enabled)
175 if (fmat.features.coat.enabled) {
182 if (fmat.features.sheen.enabled) {
189 bsdf, fmat.pbr.emission_factor,
"Emission Strength", 0.0f, 0.0f, 1000000.0f);
191 fmat.pbr.emission_color,
198 bsdf, fmat.pbr.thin_film_thickness,
"Thin Film Thickness", 0.0f, 0.0f, 100000.0f);
204 const float color[4] = {0, 0, 0, 1};
207 bmain, 32, 32,
name, 24,
false,
IMA_GENTYPE_BLANK,
color,
false,
false,
false);
218 if (image ==
nullptr) {
219 std::string path = file_dir +
"/" + tex.filename.data;
223 if (image ==
nullptr) {
229 if (image ==
nullptr) {
230 size_t pos = tex.absolute_filename.length;
233 if (parent_path ==
nullptr) {
237 BLI_path_join(path,
sizeof(path), file_dir.c_str(), parent_path);
240 pos = parent_path - tex.absolute_filename.data;
241 }
while (image ==
nullptr);
245 if (image ==
nullptr) {
253 memcpy(data_dup, tex.content.data, tex.content.size);
269 {UFBX_MATERIAL_PBR_BASE_COLOR,
"Base Color"},
270 {UFBX_MATERIAL_PBR_ROUGHNESS,
"Roughness"},
271 {UFBX_MATERIAL_PBR_METALNESS,
"Metallic"},
272 {UFBX_MATERIAL_PBR_DIFFUSE_ROUGHNESS,
"Diffuse Roughness"},
273 {UFBX_MATERIAL_PBR_SPECULAR_FACTOR,
"Specular IOR Level"},
274 {UFBX_MATERIAL_PBR_SPECULAR_COLOR,
"Specular Tint"},
275 {UFBX_MATERIAL_PBR_SPECULAR_IOR,
"IOR"},
276 {UFBX_MATERIAL_PBR_SPECULAR_ANISOTROPY,
"Anisotropic"},
277 {UFBX_MATERIAL_PBR_SPECULAR_ROTATION,
"Anisotropic Rotation"},
278 {UFBX_MATERIAL_PBR_TRANSMISSION_FACTOR,
"Transmission Weight"},
279 {UFBX_MATERIAL_PBR_SUBSURFACE_FACTOR,
"Subsurface Weight"},
280 {UFBX_MATERIAL_PBR_SUBSURFACE_SCALE,
"Subsurface Scale"},
281 {UFBX_MATERIAL_PBR_SUBSURFACE_ANISOTROPY,
"Subsurface Anisotropy"},
282 {UFBX_MATERIAL_PBR_SHEEN_FACTOR,
"Sheen Weight"},
283 {UFBX_MATERIAL_PBR_SHEEN_COLOR,
"Sheen Tint"},
284 {UFBX_MATERIAL_PBR_SHEEN_ROUGHNESS,
"Sheen Roughness"},
285 {UFBX_MATERIAL_PBR_COAT_FACTOR,
"Coat Weight"},
286 {UFBX_MATERIAL_PBR_COAT_COLOR,
"Coat Tint"},
287 {UFBX_MATERIAL_PBR_COAT_ROUGHNESS,
"Coat Roughness"},
288 {UFBX_MATERIAL_PBR_COAT_IOR,
"Coat IOR"},
289 {UFBX_MATERIAL_PBR_COAT_NORMAL,
"Coat Normal"},
290 {UFBX_MATERIAL_PBR_THIN_FILM_THICKNESS,
"Thin Film Thickness"},
291 {UFBX_MATERIAL_PBR_THIN_FILM_IOR,
"Thin Film IOR"},
292 {UFBX_MATERIAL_PBR_EMISSION_FACTOR,
"Emission Strength"},
293 {UFBX_MATERIAL_PBR_EMISSION_COLOR,
"Emission Color"},
294 {UFBX_MATERIAL_PBR_OPACITY,
"Alpha"},
295 {UFBX_MATERIAL_PBR_NORMAL_MAP,
"Normal"},
296 {UFBX_MATERIAL_PBR_TANGENT_MAP,
"Tangent"},
304 {UFBX_MATERIAL_FBX_TRANSPARENCY_FACTOR,
"Alpha"},
305 {UFBX_MATERIAL_FBX_TRANSPARENCY_COLOR,
"Alpha"},
306 {UFBX_MATERIAL_FBX_BUMP,
"Normal"},
310 const std::string &file_dir,
313 const ufbx_material &fmat,
314 const ufbx_texture *ftex,
315 const char *socket_name,
324 socket_name,
"Base Color",
"Specular Tint",
"Sheen Tint",
"Coat Tint",
"Emission Color"))
333 image_node->
id = &image->
id;
338 if (ftex->wrap_u == UFBX_WRAP_CLAMP || ftex->wrap_v == UFBX_WRAP_CLAMP) {
343 if (ftex->has_uv_transform) {
349 ftex->uv_transform.translation.x,
350 ftex->uv_transform.translation.y,
351 ftex->uv_transform.translation.z,
353 ufbx_vec3
rot = ufbx_quat_to_euler(ftex->uv_transform.rotation, UFBX_ROTATION_ORDER_XYZ);
356 1.0f / ftex->uv_transform.scale.x,
357 1.0f / ftex->uv_transform.scale.y,
358 1.0f / ftex->uv_transform.scale.z,
362 link_sockets(ntree, mapping,
"Vector", image_node,
"Vector");
365 done_bsdf_inputs.
add(socket_name);
366 if (
STREQ(socket_name,
"Normal")) {
368 link_sockets(ntree, image_node,
"Color", normal_node,
"Color");
369 link_sockets(ntree, normal_node,
"Normal", bsdf,
"Normal");
372 float normal_strength = 1.0f;
373 if (fmat.fbx.bump_factor.has_value) {
374 normal_strength = fmat.fbx.bump_factor.value_real;
379 link_sockets(ntree, image_node,
"Color", bsdf, socket_name);
381 if (
STREQ(socket_name,
"Base Color") && !done_bsdf_inputs.
contains(
"Alpha")) {
389 link_sockets(ntree, image_node,
"Alpha", bsdf,
"Alpha");
390 done_bsdf_inputs.
add(
"Alpha");
397 const std::string &file_dir,
400 const ufbx_material &fmat)
408 if (done_bsdf_inputs.
contains(entry.socket)) {
412 const ufbx_texture *ftex = fmat.pbr.maps[entry.slot].texture;
413 if (ftex ==
nullptr || !fmat.pbr.maps[entry.slot].texture_enabled) {
419 bmain, file_dir, ntree, bsdf, fmat, ftex, entry.socket, node_locy, done_bsdf_inputs);
427 if (done_bsdf_inputs.
contains(entry.socket)) {
431 const ufbx_texture *ftex = fmat.fbx.maps[entry.slot].texture;
432 if (ftex ==
nullptr || !fmat.fbx.maps[entry.slot].texture_enabled) {
438 bmain, file_dir, ntree, bsdf, fmat, ftex, entry.socket, node_locy, done_bsdf_inputs);
ImBuf * BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
Image * BKE_image_load_exists(Main *bmain, const char *filepath, bool *r_exists=nullptr)
bool BKE_image_has_packedfile(const Image *image)
void BKE_image_packfiles_from_mem(ReportList *reports, Image *ima, char *data, size_t data_len)
Image * BKE_image_add_generated(Main *bmain, unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, const float color[4], bool stereo3d, bool is_data, bool tiled)
General operations, lookup, etc. for materials.
Material * BKE_material_add(Main *bmain, const char *name)
#define SH_NODE_TEX_IMAGE
#define SH_NODE_BSDF_PRINCIPLED
#define SH_NODE_NORMAL_MAP
#define SH_NODE_OUTPUT_MATERIAL
void BKE_ntree_update_after_single_tree_change(Main &bmain, bNodeTree &modified_tree, const NodeTreeUpdateExtraParams ¶ms={})
void void void const char * BLI_path_basename(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
int BLI_path_normalize(char *path) ATTR_NONNULL(1)
#define BLI_path_join(...)
const char * BLI_path_parent_dir_end(const char *path, size_t path_len) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
char * STRNCPY(char(&dst)[N], const char *src)
#define STRNCPY_UTF8(dst, src)
@ SHD_IMAGE_EXTENSION_REPEAT
@ SHD_IMAGE_EXTENSION_EXTEND
const char * IMB_colormanagement_role_colorspace_name_get(int role)
struct blender::bke::bNodeTreeType * ntreeType_Shader
bool contains(const Key &key) const
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
bNodeTree * node_tree_add_tree_embedded(Main *bmain, ID *owner_id, StringRefNull name, StringRefNull idname)
bNodeSocket * node_find_socket(bNode &node, eNodeSocketInOut in_out, StringRef identifier)
bNode * node_add_static_node(const bContext *C, bNodeTree &ntree, int type)
bNodeLink & node_add_link(bNodeTree &ntree, bNode &fromnode, bNodeSocket &fromsock, bNode &tonode, bNodeSocket &tosock)
void node_set_active(bNodeTree &ntree, bNode &node)
static void add_image_texture(Main *bmain, const std::string &file_dir, bNodeTree *ntree, bNode *bsdf, const ufbx_material &fmat, const ufbx_texture *ftex, const char *socket_name, float node_locy, Set< StringRefNull > &done_bsdf_inputs)
static constexpr float node_locx_bsdf
Material * import_material(Main *bmain, const std::string &base_dir, const ufbx_material &fmat)
static constexpr float node_locy_top
static float set_bsdf_float_param(bNode *bsdf, const ufbx_material_map &umap, const char *socket, float def, float min=0.0f, float max=1.0f, float multiplier=1.0f)
static void link_sockets(bNodeTree *ntree, bNode *from_node, const char *from_node_id, bNode *to_node, const char *to_node_id)
static constexpr float node_locx_image
static bNode * add_node(bNodeTree *ntree, int type, float x, float y)
static const FbxPbrTextureToSocket fbx_pbr_to_socket[]
static const FbxStdTextureToSocket fbx_std_to_socket[]
static void set_bsdf_socket_values(bNode *bsdf, Material *mat, const ufbx_material &fmat)
static Image * create_placeholder_image(Main *bmain, const std::string &path)
static float3 set_bsdf_color_param(bNode *bsdf, const ufbx_material_map &umap, const char *socket, float3 def, float3 min=float3(0.0f), float3 max=float3(1.0f))
static constexpr float node_locx_mapping
static void set_socket_rgb(const char *socket_id, float vr, float vg, float vb, bNode *node)
static void add_image_textures(Main *bmain, const std::string &file_dir, bNodeTree *ntree, bNode *bsdf, const ufbx_material &fmat)
static constexpr float node_locx_output
static void set_socket_vector(const char *socket_id, float vx, float vy, float vz, bNode *node)
static Image * load_texture_image(Main *bmain, const std::string &file_dir, const ufbx_texture &tex)
static void set_socket_float(const char *socket_id, const float value, bNode *node)
static constexpr float node_locy_step
static constexpr float node_locx_texcoord
static constexpr float node_locx_normalmap
T clamp(const T &a, const T &min, const T &max)
VecBase< float, 3 > float3
ColorManagedColorspaceSettings colorspace_settings
struct bNodeTree * nodetree
ufbx_material_pbr_map slot
ufbx_material_fbx_map slot
void * BKE_image_free_buffers