def shaderfunc_to_material(shader_func, *args, name=None, **kwargs):
    """
    Convert a shader_func(nw) directly to a bpy.data.material

    Used in add_material and transpiler's Nodes.SetMaterial handler
    """

    if name is None:
        name = shader_func.__name__

    material = bpy.data.materials.new(name=name)
    material.use_nodes = True
    material.node_tree.nodes.remove(
        material.node_tree.nodes["Principled BSDF"]
    )  # remove the default BSDF

    nw = NodeWrangler(material.node_tree)

    new_node_tree = shader_func(nw, *args, **kwargs)

    if new_node_tree is not None:
        if isinstance(new_node_tree, tuple) and isnode(new_node_tree[1]):
            new_node_tree, volume = new_node_tree
            nw.new_node(Nodes.MaterialOutput, input_kwargs={"Volume": volume})
        nw.new_node(Nodes.MaterialOutput, input_kwargs={"Surface": new_node_tree})

    return material

    Convert a shader_func(nw) directly to a bpy.data.material

    Used in add_material and transpiler's Nodes.SetMaterial handler
    
infinigen/core/surface.py