示例#1
0
def is_transluc(material):
    nodes = material.node_tree.nodes
    output_node = cycles.node_by_type(nodes, 'OUTPUT_MATERIAL')
    if output_node == None or output_node.inputs[0].is_linked == False:
        return False

    surface_node = output_node.inputs[0].links[0].from_node
    return is_transluc_traverse(surface_node)
示例#2
0
def get_sorted(mat):
    nodes = mat.node_tree.nodes
    output_node = cycles.node_by_type(nodes, 'OUTPUT_MATERIAL')

    if output_node != None:
        ar = []
        traverse_tree2(output_node, ar)
        return ar
示例#3
0
def parse_objectinfo(node: bpy.types.ShaderNodeObjectInfo,
                     out_socket: bpy.types.NodeSocket,
                     state: ParserState) -> Union[floatstr, vec3str]:
    # Location
    if out_socket == node.outputs[0]:
        if state.context == ParserContext.WORLD:
            return c.to_vec3((0.0, 0.0, 0.0))
        return 'wposition'

    # Color
    elif out_socket == node.outputs[1]:
        if state.context == ParserContext.WORLD:
            # Use world strength like Blender
            background_node = c.node_by_type(state.world.node_tree.nodes,
                                             'BACKGROUND')
            if background_node is None:
                return c.to_vec3((0.0, 0.0, 0.0))
            return c.to_vec3([background_node.inputs[1].default_value] * 3)

        # TODO: Implement object color in Iron
        # state.curshader.add_uniform('vec3 objectInfoColor', link='_objectInfoColor')
        # return 'objectInfoColor'
        return c.to_vec3((1.0, 1.0, 1.0))

    # Object Index
    elif out_socket == node.outputs[2]:
        if state.context == ParserContext.WORLD:
            return '0.0'
        state.curshader.add_uniform('float objectInfoIndex',
                                    link='_objectInfoIndex')
        return 'objectInfoIndex'

    # Material Index
    elif out_socket == node.outputs[3]:
        if state.context == ParserContext.WORLD:
            return '0.0'
        state.curshader.add_uniform('float objectInfoMaterialIndex',
                                    link='_objectInfoMaterialIndex')
        return 'objectInfoMaterialIndex'

    # Random
    elif out_socket == node.outputs[4]:
        if state.context == ParserContext.WORLD:
            return '0.0'

        # Use random value per instance
        if mat_state.uses_instancing:
            state.vert.add_out(f'flat float irand')
            state.frag.add_in(f'flat float irand')
            state.vert.write(
                f'irand = fract(sin(gl_InstanceID) * 43758.5453);')
            return 'irand'

        state.curshader.add_uniform('float objectInfoRandom',
                                    link='_objectInfoRandom')
        return 'objectInfoRandom'
示例#4
0
def get_signature(mat):
    nodes = mat.node_tree.nodes
    output_node = cycles.node_by_type(nodes, 'OUTPUT_MATERIAL')

    if output_node != None:
        sign = traverse_tree(output_node, '')
        # Append flags
        sign += '1' if mat.arm_cast_shadow else '0'
        sign += '1' if mat.arm_overlay else '0'
        sign += '1' if mat.arm_cull_mode == 'Clockwise' else '0'
        return sign
示例#5
0
def build(material, mat_users, mat_armusers):
    mat_state.mat_users = mat_users
    mat_state.mat_armusers = mat_armusers
    mat_state.material = material
    mat_state.nodes = material.node_tree.nodes
    mat_state.data = ShaderData(material)
    mat_state.output_node = cycles.node_by_type(mat_state.nodes, 'OUTPUT_MATERIAL')
    if mat_state.output_node == None:
        # Place empty material output to keep compiler happy..
        mat_state.output_node = mat_state.nodes.new('ShaderNodeOutputMaterial')

    wrd = bpy.data.worlds['Arm']
    rpdat = arm.utils.get_rp()
    rpasses = mat_utils.get_rpasses(material)
    matname = arm.utils.safesrc(arm.utils.asset_name(material))
    rel_path = arm.utils.build_dir() + '/compiled/Shaders/'
    full_path = arm.utils.get_fp() + '/' + rel_path
    if not os.path.exists(full_path):
        os.makedirs(full_path)

    global_elems = []
    if mat_users != None and material in mat_users:
        for bo in mat_users[material]:
            # GPU Skinning
            if arm.utils.export_bone_data(bo):
                global_elems.append({'name': 'bone', 'size': 4})
                global_elems.append({'name': 'weight', 'size': 4})
            # Instancing
            if bo.arm_instanced or material.arm_particle_flag:
                global_elems.append({'name': 'off', 'size': 3})
                
    mat_state.data.global_elems = global_elems

    bind_constants = dict()
    bind_textures = dict()

    for rp in rpasses:

        car = []
        bind_constants[rp] = car
        mat_state.bind_constants = car
        tar = []
        bind_textures[rp] = tar
        mat_state.bind_textures = tar

        con = None

        if rpdat.rp_driver != 'Armory' and arm.api.drivers[rpdat.rp_driver]['make_rpass'] != None:
            con = arm.api.drivers[rpdat.rp_driver]['make_rpass'](rp)

        if con != None:
            pass
            
        elif rp == 'mesh':
            con = make_mesh.make(rp)

        elif rp == 'rect':
            con = make_rect.make(rp)

        elif rp == 'shadowmap':
            con = make_depth.make(rp, rpasses, shadowmap=True)

        elif rp == 'translucent':
            con = make_transluc.make(rp)

        elif rp == 'overlay':
            con = make_overlay.make(rp)

        elif rp == 'decal':
            con = make_decal.make(rp)

        elif rp == 'depth':
            con = make_depth.make(rp, rpasses)

        elif rp == 'voxel':
            con = make_voxel.make(rp)

        elif rpass_hook != None:
            con = rpass_hook(rp)

        write_shaders(rel_path, con, rp, matname)

    arm.utils.write_arm(full_path + '/' + matname + '_data.arm', mat_state.data.get())
    shader_data_name = matname + '_data'
    shader_data_path = arm.utils.get_fp_build() + '/compiled/Shaders/' + shader_data_name + '.arm'
    assets.add_shader_data(shader_data_path)

    return rpasses, mat_state.data, shader_data_name, bind_constants, bind_textures
示例#6
0
def build(material: Material, mat_users: Dict[Material, List[Object]],
          mat_armusers) -> Tuple:
    mat_state.mat_users = mat_users
    mat_state.mat_armusers = mat_armusers
    mat_state.material = material
    mat_state.nodes = material.node_tree.nodes
    mat_state.data = ShaderData(material)
    mat_state.output_node = cycles.node_by_type(mat_state.nodes,
                                                'OUTPUT_MATERIAL')
    if mat_state.output_node is None:
        # Place empty material output to keep compiler happy..
        mat_state.output_node = mat_state.nodes.new('ShaderNodeOutputMaterial')

    wrd = bpy.data.worlds['Arm']
    rpdat = arm.utils.get_rp()
    rpasses = mat_utils.get_rpasses(material)
    is_emissive = mat_utils.is_emmisive(material)
    if is_emissive and '_Emission' not in wrd.world_defs:
        wrd.world_defs += '_Emission'
    matname = arm.utils.safesrc(arm.utils.asset_name(material))
    rel_path = arm.utils.build_dir() + '/compiled/Shaders/'
    full_path = arm.utils.get_fp() + '/' + rel_path
    if not os.path.exists(full_path):
        os.makedirs(full_path)

    make_instancing_and_skinning(material, mat_users)

    bind_constants = dict()
    bind_textures = dict()

    for rp in rpasses:

        car = []
        bind_constants[rp] = car
        mat_state.bind_constants = car
        tar = []
        bind_textures[rp] = tar
        mat_state.bind_textures = tar

        con = None

        if rpdat.rp_driver != 'Armory' and arm.api.drivers[
                rpdat.rp_driver]['make_rpass'] is not None:
            con = arm.api.drivers[rpdat.rp_driver]['make_rpass'](rp)

        if con is not None:
            pass

        elif rp == 'mesh':
            con = make_mesh.make(rp, rpasses)

        elif rp == 'shadowmap':
            con = make_depth.make(rp, rpasses, shadowmap=True)

        elif rp == 'translucent':
            con = make_transluc.make(rp)

        elif rp == 'overlay':
            con = make_overlay.make(rp)

        elif rp == 'decal':
            con = make_decal.make(rp)

        elif rp == 'depth':
            con = make_depth.make(rp, rpasses)

        elif rp == 'voxel':
            con = make_voxel.make(rp)

        elif rpass_hook is not None:
            con = rpass_hook(rp)

        write_shaders(rel_path, con, rp, matname)

    shader_data_name = matname + '_data'

    if wrd.arm_single_data_file:
        if 'shader_datas' not in arm.exporter.current_output:
            arm.exporter.current_output['shader_datas'] = []
        arm.exporter.current_output['shader_datas'].append(
            mat_state.data.get()['shader_datas'][0])
    else:
        arm.utils.write_arm(full_path + '/' + matname + '_data.arm',
                            mat_state.data.get())
        shader_data_path = arm.utils.get_fp_build(
        ) + '/compiled/Shaders/' + shader_data_name + '.arm'
        assets.add_shader_data(shader_data_path)

    return rpasses, mat_state.data, shader_data_name, bind_constants, bind_textures