Export pbr fbx from 3ds max works with small change to import_fbx

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)

b’3dsMax|Parameters|base_color_map’
b’3dsMax|Parameters|metalness_map’
b’3dsMax|Parameters|roughness_map’
b’3dsMax|Parameters|bump_map’

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

Such a patch would be welcome. We are already testing for a few 3dsmax specific names, should be no problem to add a few more.

4 Likes

Agree with @brecht of course, please add me (@mont29) as reviewer when you submit the patch. :wink:

1 Like

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.

1 Like

Ok will do thanks!

@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.

image

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?

how do you handle importing FBX from MAX if your scene in Blender already have that object with the same material names?