We’re testing with a very simple model with one linked texture exported from 3ds max as a fbx with prb texture.
If I try to import it into blender I don’t get textures. However If I modify the import_fbx.py to add in the material names coming out of 3ds max it works fine:
if lnk_type in {b'DiffuseColor', b'3dsMax|maps|texmap_diffuse', b'3dsMax|Parameters|base_color_map'}:
ma_wrap.base_color_texture.image = image
texture_mapping_set(fbx_lnk, ma_wrap.base_color_texture)
elif lnk_type in {b'SpecularColor', b'SpecularFactor'}:
# Intensity actually, not color...
ma_wrap.specular_texture.image = image
texture_mapping_set(fbx_lnk, ma_wrap.specular_texture)
elif lnk_type in {b'ReflectionColor', b'ReflectionFactor', b'3dsMax|maps|texmap_reflection', b'3dsMax|Parameters|metalness_map'}:
# Intensity actually, not color...
ma_wrap.metallic_texture.image = image
texture_mapping_set(fbx_lnk, ma_wrap.metallic_texture)
elif lnk_type in {b'TransparentColor', b'TransparentFactor'}:
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 in {b'ShininessExponent', b'3dsMax|Parameters|roughness_map'}:
# That is probably reversed compared to expected results? TODO...
ma_wrap.roughness_texture.image = image
texture_mapping_set(fbx_lnk, ma_wrap.roughness_texture)
# XXX, applications abuse bump!
elif lnk_type in {b'NormalMap', b'Bump', b'3dsMax|maps|texmap_bump', b'3dsMax|Parameters|bump_map'}:
ma_wrap.normalmap_texture.image = image
texture_mapping_set(fbx_lnk, ma_wrap.normalmap_texture)
"""
elif lnk_type == b'Bump':
# TODO displacement...
"""
elif lnk_type in {b'EmissiveColor'}:
ma_wrap.emission_color_texture.image = image
texture_mapping_set(fbx_lnk, ma_wrap.emission_color_texture)
else:
print("WARNING: material link %r ignored" % lnk_type)
Is this something that is known? We are planning on manually applying this patch to our render-farm because it unblocks all of our max-blender rendering but I’d rather not do that if there was a known solution.
update: continuing testing with multiple types exported out of fbx and have a list of possible good matches, I’d be open to making a patch request for this but would want to confirm this is a route Blender would like to go down… is this the place for that discussion or should I move to developer.blender.org?
if fbx_lnk_type.props[0] == b 'OP':
lnk_type = fbx_lnk_type.props[3]
ma_wrap = nodal_material_wrap_map[material]
base_color_matches = [b 'DiffuseColor',
b '3dsMax|maps|texmap_diffuse',
b '3dsMax|Parameters|base_color_map',
b '3dsMax|ai_standard_surface Parameters/Connections|base_color.shader',
b 'base',
b 'diffuse'
]
specular_matches = [b 'SpecularColor', b 'SpecularFactor', b 'specular']
metallic_matches = [b 'ReflectionColor',
b 'ReflectionFactor',
b '3dsMax|maps|texmap_reflection',
b '3dsMax|Parameters|metalness_map',
b '3dsMax|maps|texmap_metalness',
b '3dsMax|ai_standard_surface Parameters/Connections|metalness.shader',
b 'metal',
b 'reflection'
]
alpha_matches = [b 'TransparentColor', b 'TransparentFactor', b 'transparent']
roughness_matches = [b 'ShininessExponent',
b '3dsMax|Parameters|roughness_map',
b '3dsMax|maps|texmap_roughness',
b '3dsMax|ai_standard_surface Parameters/Connections|specular_roughness.shader',
b 'roughness',
b 'shininess'
]
normal_matches = [b 'NormalMap',
b 'Bump',
b '3dsMax|maps|texmap_bump',
b '3dsMax|Parameters|bump_map',
b '3dsMax|ai_standard_surface Parameters/Connections|normal.shader',
b 'normal'
]
emissive_matches = [b 'EmissiveColor', b 'emissive']
if any(s.lower() in lnk_type.lower() for s in base_color_matches):
ma_wrap.base_color_texture.image = image
texture_mapping_set(fbx_lnk, ma_wrap.base_color_texture)
elif any(s.lower() in lnk_type.lower() for s in specular_matches):
# Intensity actually, not color...
ma_wrap.specular_texture.image = image
texture_mapping_set(fbx_lnk, ma_wrap.specular_texture)
elif any(s.lower() in lnk_type.lower() for s in metallic_matches):
# Intensity actually, not color...
ma_wrap.metallic_texture.image = image
texture_mapping_set(fbx_lnk, ma_wrap.metallic_texture)
elif any(s.lower() in lnk_type.lower() for s in alpha_matches):
ma_wrap.alpha_texture.image = image
texture_mapping_set(fbx_lnk, ma_wrap.alpha_texture)
if use_alpha_decals:
material_decals.add(material)
elif any(s.lower() in lnk_type.lower() for s in roughness_matches):
# That is probably reversed compared to expected results ? TODO...
ma_wrap.roughness_texture.image = image
texture_mapping_set(fbx_lnk, ma_wrap.roughness_texture)
# XXX, applications abuse bump!
elif any(s.lower() in lnk_type.lower() for s in normal_matches):
ma_wrap.normalmap_texture.image = image
texture_mapping_set(fbx_lnk, ma_wrap.normalmap_texture)
""
"
elif lnk_type == b 'Bump':
# TODO displacement...
""
"
elif any(s.lower() in lnk_type.lower() for s in emissive_matches):
ma_wrap.emission_color_texture.image = image
texture_mapping_set(fbx_lnk, ma_wrap.emission_color_texture)
else :
print("WARNING: material link %r ignored" % lnk_type)
material_images.setdefault(material, {})[lnk_type] = image
Wait, so you’re telling me max can export fbx with all textures using it’s standard PBR material? In my experience (With Max 2020.0 or .1 iirc) I had to manually change materials standard scanline and connect roughness to glossines and metalness to reflection in order to import directly into blender.
@xdanic So far it seems to be working with our tests – if you want to test it the source is here, just manually copy the file to the appropriate folder overwriting the existing file and then relaunch blender. You should be able to test importing/exporting.
It been a while but I just tested and is almost working right, except for the normal map, which I have to select manually the weird, but good part is kind of there already, since I can select it from the dropdown.
As you can see there are two textures with 0 users and by default the one that is empty is loaded, the metallic map is the same, except the “bad” one isn’t empty so there’s no problem.
EDIT: It also looks like this importer can’t import blender’s own fbx, so I guess it only works for Max’s files and need to be merged with the existing code to import everything?