Wildenhaus / Index

A tool for browsing and extracting assets from Halo 2 Anniversary.
16 stars 1 forks source link

Investigate ways to prevent Blender's FBX import from setting the alpha channel / blend mode #7

Closed Wildenhaus closed 2 years ago

Wildenhaus commented 2 years ago

Blender's FBX Importer automatically connects the Diffuse Texture's alpha to the default PBR shader's alpha input. When it does this, it also automatically sets the material's blend mode to Alpha Blend.

I've tried a number of things to prevent this from happening, but to no avail. It seems that as of right now, the user would need a modified FBX import script to stop this from happening.

One potential workaround is to just remove the texture slots from the shader when exporting from Index. That might have to be the route we go down.

It seems Blender might already be aware of potential issues with this. In their import_fbx.py:

    # Sweetness... Looks like we are not the only ones to not know exactly how FBX is supposed to work (see T59850).
    # According to one of its developers, Unity uses that formula to extract alpha value:
    #
    #   alpha = 1 - TransparencyFactor
    #   if (alpha == 1 or alpha == 0):
    #       alpha = 1 - TransparentColor.r
    #
    # Until further info, let's assume this is correct way to do, hence the following code for TransparentColor.
    # However, there are some cases (from 3DSMax, see T65065), where we do have TransparencyFactor only defined
    # in the template to 0.0, and then materials defining TransparentColor to pure white (1.0, 1.0, 1.0),
    # and setting alpha value in Opacity... try to cope with that too. :((((
    alpha = 1.0 - elem_props_get_number(fbx_props, b'TransparencyFactor', 0.0)
    if (alpha == 1.0 or alpha == 0.0):
        alpha = elem_props_get_number(fbx_props_no_template, b'Opacity', None)
        if alpha is None:
            alpha = 1.0 - elem_props_get_color_rgb(fbx_props, b'TransparentColor', const_color_black)[0]
    ma_wrap.alpha = alpha
    ma_wrap.metallic = elem_props_get_number(fbx_props, b'ReflectionFactor', 0.0)
    # We have no metallic (a.k.a. reflection) color...
    # elem_props_get_color_rgb(fbx_props, b'ReflectionColor', const_color_white)
    ma_wrap.normalmap_strength = elem_props_get_number(fbx_props, b'BumpFactor', 1.0)
    # Emission strength and color
    ma_wrap.emission_strength = elem_props_get_number(fbx_props, b'EmissiveFactor', 1.0)
    ma_wrap.emission_color = elem_props_get_color_rgb(fbx_props, b'EmissiveColor', const_color_black)

    nodal_material_wrap_map[ma] = ma_wrap

    if settings.use_custom_props:
        blen_read_custom_properties(fbx_obj, ma, settings)

    return ma
# Check if the diffuse image has an alpha channel,
        # if so, use the alpha channel.

        # Note: this could be made optional since images may have alpha but be entirely opaque
        for fbx_uuid, fbx_item in fbx_table_nodes.items():
            fbx_obj, blen_data = fbx_item
            if fbx_obj.id != b'Material':
                continue
            material = fbx_table_nodes.get(fbx_uuid, (None, None))[1]
            image = material_images.get(material, {}).get(b'DiffuseColor', None)
            # do we have alpha?
            if image and image.depth == 32:
                if use_alpha_decals:
                    material_decals.add(material)

                ma_wrap = nodal_material_wrap_map[material]
                ma_wrap.alpha_texture.use_alpha = True
                ma_wrap.alpha_texture.copy_from(ma_wrap.base_color_texture)
Wildenhaus commented 2 years ago

Closing this, as it's an issue with blender, and there seems to be no way to override it within the material's settings.

To fix:

Open this file in a text editor: (Blender Install Path)\(Your Blender Version)\scripts\addons\io_scene_fbx\import_fbx.py Comment these lines out with a # (as seen in the screenshot) Requires restarting blender or disabling/re-enabling the FBX importer in addons unknown