コード例 #1
0
def __gather_clearcoat_extension(blender_material, export_settings):
    clearcoat_enabled = False
    has_clearcoat_texture = False
    has_clearcoat_roughness_texture = False

    clearcoat_extension = {}
    clearcoat_roughness_slots = ()

    clearcoat_socket = gltf2_blender_get.get_socket(blender_material, 'Clearcoat')
    clearcoat_roughness_socket = gltf2_blender_get.get_socket(blender_material, 'Clearcoat Roughness')
    clearcoat_normal_socket = gltf2_blender_get.get_socket(blender_material, 'Clearcoat Normal')

    if isinstance(clearcoat_socket, bpy.types.NodeSocket) and not clearcoat_socket.is_linked:
        clearcoat_extension['clearcoatFactor'] = clearcoat_socket.default_value
        clearcoat_enabled = clearcoat_extension['clearcoatFactor'] > 0
    elif __has_image_node_from_socket(clearcoat_socket):
        clearcoat_extension['clearcoatFactor'] = 1
        has_clearcoat_texture = True
        clearcoat_enabled = True

    if not clearcoat_enabled:
        return None

    if isinstance(clearcoat_roughness_socket, bpy.types.NodeSocket) and not clearcoat_roughness_socket.is_linked:
        clearcoat_extension['clearcoatRoughnessFactor'] = clearcoat_roughness_socket.default_value
    elif __has_image_node_from_socket(clearcoat_roughness_socket):
        clearcoat_extension['clearcoatRoughnessFactor'] = 1
        has_clearcoat_roughness_texture = True

    # Pack clearcoat (R) and clearcoatRoughness (G) channels.
    if has_clearcoat_texture and has_clearcoat_roughness_texture:
        clearcoat_roughness_slots = (clearcoat_socket, clearcoat_roughness_socket,)
    elif has_clearcoat_texture:
        clearcoat_roughness_slots = (clearcoat_socket,)
    elif has_clearcoat_roughness_texture:
        clearcoat_roughness_slots = (clearcoat_roughness_socket,)

    if len(clearcoat_roughness_slots) > 0:
        if has_clearcoat_texture:
            clearcoat_extension['clearcoatTexture'] = gltf2_blender_gather_texture_info.gather_texture_info(
                clearcoat_socket,
                clearcoat_roughness_slots,
                export_settings,
            )
        if has_clearcoat_roughness_texture:
            clearcoat_extension['clearcoatRoughnessTexture'] = gltf2_blender_gather_texture_info.gather_texture_info(
                clearcoat_roughness_socket,
                clearcoat_roughness_slots,
                export_settings,
            )

    if __has_image_node_from_socket(clearcoat_normal_socket):
        clearcoat_extension['clearcoatNormalTexture'] = gltf2_blender_gather_texture_info.gather_material_normal_texture_info_class(
            clearcoat_normal_socket,
            (clearcoat_normal_socket,),
            export_settings
        )

    return Extension('KHR_materials_clearcoat', clearcoat_extension, False)
コード例 #2
0
def __gather_transmission_extension(blender_material, export_settings):
    transmission_enabled = False
    has_transmission_texture = False

    transmission_extension = {}
    transmission_slots = ()

    transmission_socket = gltf2_blender_get.get_socket(blender_material, 'Transmission')

    if isinstance(transmission_socket, bpy.types.NodeSocket) and not transmission_socket.is_linked:
        transmission_extension['transmissionFactor'] = transmission_socket.default_value
        transmission_enabled = transmission_extension['transmissionFactor'] > 0
    elif __has_image_node_from_socket(transmission_socket):
        transmission_extension['transmissionFactor'] = 1
        has_transmission_texture = True
        transmission_enabled = True

    if not transmission_enabled:
        return None

    # Pack transmission channel (R).
    if has_transmission_texture:
        transmission_slots = (transmission_socket,)

    if len(transmission_slots) > 0:
        combined_texture = gltf2_blender_gather_texture_info.gather_texture_info(transmission_slots, export_settings)
        if has_transmission_texture:
            transmission_extension['transmissionTexture'] = combined_texture

    return Extension('KHR_materials_transmission', transmission_extension, False)
コード例 #3
0
def __gather_metallic_roughness_texture(blender_material, orm_texture,
                                        export_settings):
    if orm_texture is not None:
        texture_input = orm_texture
    else:
        metallic_socket = gltf2_blender_get.get_socket_or_texture_slot(
            blender_material, "Metallic")
        roughness_socket = gltf2_blender_get.get_socket_or_texture_slot(
            blender_material, "Roughness")

        hasMetal = metallic_socket is not None and __has_image_node_from_socket(
            metallic_socket)
        hasRough = roughness_socket is not None and __has_image_node_from_socket(
            roughness_socket)

        if not hasMetal and not hasRough:
            metallic_roughness = gltf2_blender_get.get_socket_or_texture_slot_old(
                blender_material, "MetallicRoughness")
            if metallic_roughness is None or not __has_image_node_from_socket(
                    metallic_roughness):
                return None
            texture_input = (metallic_roughness, )
        elif not hasMetal:
            texture_input = (roughness_socket, )
        elif not hasRough:
            texture_input = (metallic_socket, )
        else:
            texture_input = (metallic_socket, roughness_socket)

    return gltf2_blender_gather_texture_info.gather_texture_info(
        texture_input, export_settings)
def __gather_emissive_texture(blender_material, export_settings):
    emissive = gltf2_blender_get.get_socket(blender_material, "Emissive")
    if emissive is None:
        emissive = gltf2_blender_get.get_socket_old(blender_material,
                                                    "Emissive")
    return gltf2_blender_gather_texture_info.gather_texture_info(
        emissive, (emissive, ), export_settings)
コード例 #5
0
def __gather_base_color_texture(blender_material, export_settings):
    base_color_socket = gltf2_blender_get.get_socket_or_texture_slot(
        blender_material, "Base Color")
    if base_color_socket is None:
        base_color_socket = gltf2_blender_get.get_socket_or_texture_slot(
            blender_material, "BaseColor")
    if base_color_socket is None:
        base_color_socket = gltf2_blender_get.get_socket_or_texture_slot_old(
            blender_material, "BaseColor")
    if base_color_socket is None:
        base_color_socket = gltf2_blender_get.get_socket_or_texture_slot(
            blender_material, "Background")

    alpha_socket = gltf2_blender_get.get_socket_or_texture_slot(
        blender_material, "Alpha")
    if alpha_socket is not None and alpha_socket.is_linked:
        inputs = (
            base_color_socket,
            alpha_socket,
        )
    else:
        inputs = (base_color_socket, )

    return gltf2_blender_gather_texture_info.gather_texture_info(
        inputs, export_settings)
コード例 #6
0
def __gather_orm_texture(blender_material, export_settings):
    # Check for the presence of Occlusion, Roughness, Metallic sharing a single image.
    # If not fully shared, return None, so the images will be cached and processed separately.

    occlusion = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Occlusion")
    if occlusion is None or not __has_image_node_from_socket(occlusion):
        occlusion = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "Occlusion")
        if occlusion is None or not __has_image_node_from_socket(occlusion):
            return None

    metallic_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Metallic")
    roughness_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Roughness")

    hasMetal = metallic_socket is not None and __has_image_node_from_socket(metallic_socket)
    hasRough = roughness_socket is not None and __has_image_node_from_socket(roughness_socket)

    if not hasMetal and not hasRough:
        metallic_roughness = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "MetallicRoughness")
        if metallic_roughness is None or not __has_image_node_from_socket(metallic_roughness):
            return None
        result = (occlusion, metallic_roughness)
    elif not hasMetal:
        result = (occlusion, roughness_socket)
    elif not hasRough:
        result = (occlusion, metallic_socket)
    else:
        result = (occlusion, roughness_socket, metallic_socket)

    # Double-check this will past the filter in texture_info (otherwise there are different resolutions or other problems).
    info = gltf2_blender_gather_texture_info.gather_texture_info(result, export_settings)
    if info is None:
        return None

    return result
コード例 #7
0
def __gather_base_color_texture(blender_material, export_settings):
    base_color_socket = gltf2_blender_get.get_socket_or_texture_slot(
        blender_material, "Base Color")
    if base_color_socket is None:
        base_color_socket = gltf2_blender_get.get_socket_or_texture_slot(
            blender_material, "BaseColor")
    return gltf2_blender_gather_texture_info.gather_texture_info(
        (base_color_socket, ), export_settings)
def __gather_base_color_texture(blender_material, export_settings):
    base_color_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Base Color")
    if base_color_socket is None:
        base_color_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "BaseColor")
    if base_color_socket is None:
        base_color_socket = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "BaseColor")
    if base_color_socket is None:
        base_color_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Background")
    return gltf2_blender_gather_texture_info.gather_texture_info((base_color_socket,), export_settings)
コード例 #9
0
def __gather_emissive_texture(blender_material, export_settings):
    emissive = gltf2_blender_get.get_socket(blender_material, "Emissive")
    if emissive is None:
        emissive = gltf2_blender_get.get_socket_old(blender_material,
                                                    "Emissive")
    emissive_texture, use_actives_uvmap_emissive = gltf2_blender_gather_texture_info.gather_texture_info(
        emissive, (emissive, ), export_settings)
    return emissive_texture, ["emissiveTexture"
                              ] if use_actives_uvmap_emissive else None
def __gather_metallic_roughness_texture(blender_material, export_settings):
    metallic_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Metallic")
    roughness_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Roughness")

    if metallic_socket is None and roughness_socket is None:
        metallic_roughness = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "MetallicRoughness")
        texture_input = (metallic_roughness,)
    else:
        texture_input = (metallic_socket, roughness_socket)

    return gltf2_blender_gather_texture_info.gather_texture_info(texture_input, export_settings)
コード例 #11
0
def gather_base_color_texture(info, export_settings):
    sockets = (info.get('rgb_socket'), info.get('alpha_socket'))
    sockets = tuple(s for s in sockets if s is not None)
    if sockets:
        # NOTE: separate RGB and Alpha textures will not get combined
        # because gather_image determines how to pack images based on the
        # names of sockets, and the names are hard-coded to a Principled
        # style graph.
        return gltf2_blender_gather_texture_info.gather_texture_info(
            sockets[0],
            sockets,
            export_settings,
        )
    return None
def __gather_orm_texture(blender_material, export_settings):
    # Check for the presence of Occlusion, Roughness, Metallic sharing a single image.
    # If not fully shared, return None, so the images will be cached and processed separately.

    occlusion = gltf2_blender_get.get_socket(blender_material, "Occlusion")
    if occlusion is None or not __has_image_node_from_socket(occlusion):
        occlusion = gltf2_blender_get.get_socket_old(blender_material,
                                                     "Occlusion")
        if occlusion is None or not __has_image_node_from_socket(occlusion):
            return None

    metallic_socket = gltf2_blender_get.get_socket(blender_material,
                                                   "Metallic")
    roughness_socket = gltf2_blender_get.get_socket(blender_material,
                                                    "Roughness")

    hasMetal = metallic_socket is not None and __has_image_node_from_socket(
        metallic_socket)
    hasRough = roughness_socket is not None and __has_image_node_from_socket(
        roughness_socket)

    if not hasMetal and not hasRough:
        metallic_roughness = gltf2_blender_get.get_socket_old(
            blender_material, "MetallicRoughness")
        if metallic_roughness is None or not __has_image_node_from_socket(
                metallic_roughness):
            return None
        result = (occlusion, metallic_roughness)
    elif not hasMetal:
        result = (occlusion, roughness_socket)
    elif not hasRough:
        result = (occlusion, metallic_socket)
    else:
        result = (occlusion, roughness_socket, metallic_socket)

    if not gltf2_blender_gather_texture_info.check_same_size_images(result):
        print_console(
            "INFO",
            "Occlusion and metal-roughness texture will be exported separately "
            "(use same-sized images if you want them combined)")
        return None

    # Double-check this will past the filter in texture_info
    info = gltf2_blender_gather_texture_info.gather_texture_info(
        result[0], result, export_settings)
    if info is None:
        return None

    return result
def __gather_metallic_roughness_texture(blender_material, orm_texture, export_settings):
    if orm_texture is not None:
        texture_input = orm_texture
    else:
        metallic_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Metallic")
        roughness_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Roughness")

        if metallic_socket is None and roughness_socket is None:
            metallic_roughness = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "MetallicRoughness")
            if metallic_roughness is None:
                metallic_roughness = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "MetallicRoughness")
            texture_input = (metallic_roughness,)
        else:
            texture_input = (metallic_socket, roughness_socket)

    return gltf2_blender_gather_texture_info.gather_texture_info(texture_input, export_settings)
def __gather_base_color_texture(blender_material, export_settings):
    base_color_socket = gltf2_blender_get.get_socket(blender_material, "Base Color")
    if base_color_socket is None:
        base_color_socket = gltf2_blender_get.get_socket(blender_material, "BaseColor")
    if base_color_socket is None:
        base_color_socket = gltf2_blender_get.get_socket_old(blender_material, "BaseColor")

    alpha_socket = gltf2_blender_get.get_socket(blender_material, "Alpha")

    # keep sockets that have some texture : color and/or alpha
    inputs = tuple(
        socket for socket in [base_color_socket, alpha_socket]
        if socket is not None and __has_image_node_from_socket(socket)
    )
    if not inputs:
        return None, None

    return gltf2_blender_gather_texture_info.gather_texture_info(inputs[0], inputs, export_settings)
コード例 #15
0
def gather_lightmap_texture_info(blender_material, export_settings):
    nodes = blender_material.node_tree.nodes
    lightmap_node = next((n for n in nodes if isinstance(n, MozLightmapNode)), None)

    if not lightmap_node: return

    texture_socket = lightmap_node.inputs.get("Lightmap")
    intensity = lightmap_node.intensity

    texture_info = gather_texture_info(texture_socket, (texture_socket,), export_settings)
    if not texture_info: return

    return {
        "intensity": intensity,
        'extensions': texture_info.extensions,
        'extras': texture_info.extras,
        "index": texture_info.index,
        "texCoord": texture_info.tex_coord
    }
コード例 #16
0
def __gather_extensions(blender_material, export_settings):
    extensions = {}

    if blender_material.msfs_material_type == "msfs_anisotropic":
        extensions["ASOBO_material_anisotropic"] = {}
    elif blender_material.msfs_material_type == "msfs_sss" or blender_material.msfs_material_type == "msfs_hair": # sss and hair are basically the same
        extensions["ASOBO_material_SSS"] = {
            "SSSColor": [blender_material.msfs_color_sss[0],blender_material.msfs_color_sss[1],blender_material.msfs_color_sss[2],blender_material.msfs_color_sss[3]]
        }
    elif blender_material.msfs_material_type == "msfs_glass":
        if blender_material.msfs_glass_reflection_mask_factor != 0.0 or blender_material.msfs_glass_deformation_factor != 0.0:
            extensions["ASOBO_material_kitty_glass"] = {
                "glassReflectionMaskFactor": blender_material.msfs_glass_reflection_mask_factor,
                "glassDeformationFactor": blender_material.msfs_glass_deformation_factor
            }
        else:
            extensions["ASOBO_material_glass"] = {}
    elif blender_material.msfs_material_type == "msfs_clearcoat":
        extensions["ASOBO_material_clear_coat"] = {"dirtTexture" : blender_material.msfs_clearcoat_texture}
    elif blender_material.msfs_material_type == "msfs_env_occluder":
        extensions["ASOBO_material_environment_occluder"] = {}
    elif blender_material.msfs_material_type == "msfs_fake_terrain":
        extensions["ASOBO_material_fake_terrain"] = {}
    elif blender_material.msfs_material_type == "msfs_fresnel":
        extensions["ASOBO_material_fresnel_fade"] = {
            "fresnelFactor": blender_material.msfs_fresnel_factor,
            "fresnelOpacityOffset": blender_material.msfs_fresnel_opacity_bias
            }
    elif blender_material.msfs_material_type == "msfs_parallax":
        extension = {
            "parallaxScale": blender_material.msfs_parallax_scale,
            "roomSizeXScale": blender_material.msfs_parallax_room_size_x,
            "roomSizeYScale": blender_material.msfs_parallax_room_size_y,
            "roomNumberXY": blender_material.msfs_parallax_room_number,
            "corridor": blender_material.msfs_parallax_corridor
        }

        if blender_material.msfs_behind_glass_texture != None:
            node = nodes.get("albedo_detail_mix")
            if node != None:
                inputs = (node.inputs["Color2"],)
            behind_glass_texture = gather_texture_info(inputs, export_settings)
            if behind_glass_texture != None:
                extension["behindWindowMapTexture"] = behind_glass_texture
        extensions["ASOBO_material_parallax_window"] = extension
    elif blender_material.msfs_material_type == "msfs_invisible":
        extensions["ASOBO_material_invisible"] = {}

    # other extensions
    if blender_material.msfs_show_blend_mode == True:
        if blender_material.msfs_blend_mode == 'DITHER':
            extensions["ASOBO_material_alphamode_dither"] = {}

    if (blender_material.msfs_show_road_material == True or blender_material.msfs_show_collision_material == True):
        if (blender_material.msfs_road_material == True or blender_material.msfs_collision_material == True):
            tags = []
            if blender_material.msfs_road_material == True:
                tags.append("Road")
            if blender_material.msfs_collision_material == True:
                tags.append("Collision")

            extensions["ASOBO_tags"] = {"tags" : tags}
    
    if blender_material.msfs_show_day_night_cycle == True:
        if blender_material.msfs_day_night_cycle == True:
            extensions["ASOBO_material_day_night_switch"] = {}

    if blender_material.msfs_show_draworder == True:
        if blender_material.msfs_draw_order > 0:
            extensions["ASOBO_material_draw_order"] = {"drawOrderOffset": blender_material.msfs_draw_order}

    if blender_material.msfs_show_no_cast_shadow == True:
        if blender_material.msfs_no_cast_shadow == True:
            extensions["ASOBO_material_shadow_options"] = {"noCastShadow": blender_material.msfs_no_cast_shadow}

    if (blender_material.msfs_show_ao_use_uv2 == True or blender_material.msfs_show_uv_clamp == True):
        if (blender_material.msfs_ao_use_uv2 == True or blender_material.msfs_uv_clamp_x == True or blender_material.msfs_uv_clamp_y == True):
            extensions["ASOBO_material_UV_options"] = {
                "AOUseUV2": blender_material.msfs_ao_use_uv2,
                "clampUVX": blender_material.msfs_uv_clamp_x,
                "clampUVY": blender_material.msfs_uv_clamp_y
            }

    if (blender_material.msfs_show_detail_albedo == True or blender_material.msfs_show_detail_metallic == True or blender_material.msfs_show_detail_normal == True):

        nodes = blender_material.node_tree.nodes

        detail_extension = {}
        if blender_material.msfs_detail_albedo_texture != None:
            node = nodes.get("albedo_detail_mix")
            if node != None:
                inputs = (node.inputs["Color2"],)
            albedo_detail_texture = gather_texture_info(inputs, export_settings)
            if albedo_detail_texture != None:
                detail_extension["detailColorTexture"] = albedo_detail_texture
        if blender_material.msfs_detail_metallic_texture != None:
            node = nodes.get("metallic_detail_mix")
            if node != None:
                inputs = (node.inputs["Color2"],)
            metallic_detail_texture = gather_texture_info(inputs, export_settings)
            if metallic_detail_texture != None:
                detail_extension["detailMetalRoughAOTexture"] = metallic_detail_texture
        if blender_material.msfs_detail_normal_texture != None:
            node = nodes.get("normal_detail_mix")
            if node != None:
                inputs = (node.inputs["Color2"],)
            normal_detail_texture = gather_texture_info(inputs, export_settings)
            if normal_detail_texture != None:
                detail_extension["detailNormalTexture"] = normal_detail_texture
        if len(detail_extension) > 0:
            detail_extension["UVScale"] = blender_material.msfs_detail_uv_scale
            detail_extension["UVOffset"] = (blender_material.msfs_detail_uv_offset_x,blender_material.msfs_detail_uv_offset_y)
            detail_extension["blendTreshold"] = blender_material.msfs_blend_threshold

            extensions["ASOBO_material_detail_map"] = detail_extension

    if blender_material.msfs_material_type == "msfs_decal":
        extensions["ASOBO_material_blend_gbuffer"] = {
            "baseColorBlendFactor": blender_material.msfs_decal_blend_factor_color,
            "metallicBlendFactor": blender_material.msfs_decal_blend_factor_metal,
            "roughnessBlendFactor": blender_material.msfs_decal_blend_factor_roughness,
            "normalBlendFactor": blender_material.msfs_decal_blend_factor_normal,
            "emissiveBlendFactor": blender_material.msfs_decal_blend_factor_emissive,
            "occlusionBlendFactor": blender_material.msfs_decal_blend_factor_occlusion
        }

    if blender_material.msfs_material_type == "msfs_geo_decal":
        extensions["ASOBO_material_blend_gbuffer"] = {
            "baseColorBlendFactor": blender_material.msfs_decal_blend_factor_color,
            "metallicBlendFactor": blender_material.msfs_decal_blend_factor_metal,
            "roughnessBlendFactor": blender_material.msfs_decal_blend_factor_roughness,
            "normalBlendFactor": blender_material.msfs_decal_blend_factor_normal,
            "emissiveBlendFactor": blender_material.msfs_decal_blend_factor_emissive,
            "occlusionBlendFactor": blender_material.msfs_decal_blend_factor_occlusion
        }

    return extensions
コード例 #17
0
def __gather_emissive_texture(blender_material, export_settings):
    emissive = gltf2_blender_get.get_socket_or_texture_slot(
        blender_material, "Emissive")
    return gltf2_blender_gather_texture_info.gather_texture_info(
        (emissive, ), export_settings)
コード例 #18
0
def __gather_emissive_texture(blender_material, export_settings):
    emissive = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Emissive")
    if emissive is None:
        emissive = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "Emissive")
    return gltf2_blender_gather_texture_info.gather_texture_info((emissive,), export_settings)
コード例 #19
0
def __gather_clearcoat_extension(blender_material, export_settings):
    clearcoat_enabled = False
    has_clearcoat_texture = False
    has_clearcoat_roughness_texture = False

    clearcoat_extension = {}
    clearcoat_roughness_slots = ()

    clearcoat_socket = gltf2_blender_get.get_socket(blender_material,
                                                    'Clearcoat')
    clearcoat_roughness_socket = gltf2_blender_get.get_socket(
        blender_material, 'Clearcoat Roughness')
    clearcoat_normal_socket = gltf2_blender_get.get_socket(
        blender_material, 'Clearcoat Normal')

    if isinstance(clearcoat_socket,
                  bpy.types.NodeSocket) and not clearcoat_socket.is_linked:
        clearcoat_extension['clearcoatFactor'] = clearcoat_socket.default_value
        clearcoat_enabled = clearcoat_extension['clearcoatFactor'] > 0
    elif __has_image_node_from_socket(clearcoat_socket):
        fac = gltf2_blender_get.get_factor_from_socket(clearcoat_socket,
                                                       kind='VALUE')
        # default value in glTF is 0.0, but if there is a texture without factor, use 1
        clearcoat_extension['clearcoatFactor'] = fac if fac != None else 1.0
        has_clearcoat_texture = True
        clearcoat_enabled = True

    if not clearcoat_enabled:
        return None, None

    if isinstance(
            clearcoat_roughness_socket,
            bpy.types.NodeSocket) and not clearcoat_roughness_socket.is_linked:
        clearcoat_extension[
            'clearcoatRoughnessFactor'] = clearcoat_roughness_socket.default_value
    elif __has_image_node_from_socket(clearcoat_roughness_socket):
        fac = gltf2_blender_get.get_factor_from_socket(
            clearcoat_roughness_socket, kind='VALUE')
        # default value in glTF is 0.0, but if there is a texture without factor, use 1
        clearcoat_extension[
            'clearcoatRoughnessFactor'] = fac if fac != None else 1.0
        has_clearcoat_roughness_texture = True

    # Pack clearcoat (R) and clearcoatRoughness (G) channels.
    if has_clearcoat_texture and has_clearcoat_roughness_texture:
        clearcoat_roughness_slots = (
            clearcoat_socket,
            clearcoat_roughness_socket,
        )
    elif has_clearcoat_texture:
        clearcoat_roughness_slots = (clearcoat_socket, )
    elif has_clearcoat_roughness_texture:
        clearcoat_roughness_slots = (clearcoat_roughness_socket, )

    use_actives_uvmaps = []

    if len(clearcoat_roughness_slots) > 0:
        if has_clearcoat_texture:
            clearcoat_texture, clearcoat_texture_use_active_uvmap = gltf2_blender_gather_texture_info.gather_texture_info(
                clearcoat_socket,
                clearcoat_roughness_slots,
                export_settings,
            )
            clearcoat_extension['clearcoatTexture'] = clearcoat_texture
            if clearcoat_texture_use_active_uvmap:
                use_actives_uvmaps.append("clearcoatTexture")
        if has_clearcoat_roughness_texture:
            clearcoat_roughness_texture, clearcoat_roughness_texture_use_active_uvmap = gltf2_blender_gather_texture_info.gather_texture_info(
                clearcoat_roughness_socket,
                clearcoat_roughness_slots,
                export_settings,
            )
            clearcoat_extension[
                'clearcoatRoughnessTexture'] = clearcoat_roughness_texture
            if clearcoat_roughness_texture_use_active_uvmap:
                use_actives_uvmaps.append("clearcoatRoughnessTexture")
    if __has_image_node_from_socket(clearcoat_normal_socket):
        clearcoat_normal_texture, clearcoat_normal_texture_use_active_uvmap = gltf2_blender_gather_texture_info.gather_material_normal_texture_info_class(
            clearcoat_normal_socket, (clearcoat_normal_socket, ),
            export_settings)
        clearcoat_extension[
            'clearcoatNormalTexture'] = clearcoat_normal_texture
        if clearcoat_normal_texture_use_active_uvmap:
            use_actives_uvmaps.append("clearcoatNormalTexture")

    return Extension('KHR_materials_clearcoat', clearcoat_extension,
                     False), use_actives_uvmaps