def build_matcap_nodes(node_tree: bpy.types.NodeTree, image_path: str) -> None: tex_coord_node = node_tree.nodes.new(type='ShaderNodeTexCoord') vector_transform_node = node_tree.nodes.new(type='ShaderNodeVectorTransform') mapping_node = node_tree.nodes.new(type='ShaderNodeMapping') texture_image_node = create_texture_node(node_tree, image_path, True) emmission_node = node_tree.nodes.new(type='ShaderNodeEmission') output_node = node_tree.nodes.new(type='ShaderNodeOutputMaterial') create_frame_node(node_tree, (tex_coord_node, vector_transform_node, mapping_node), name="MatCap UV", label="MatCap UV") vector_transform_node.vector_type = "VECTOR" vector_transform_node.convert_from = "OBJECT" vector_transform_node.convert_to = "CAMERA" mapping_node.vector_type = "TEXTURE" if bpy.app.version >= (2, 81, 0): mapping_node.inputs["Location"].default_value = (1.0, 1.0, 0.0) mapping_node.inputs["Scale"].default_value = (2.0, 2.0, 1.0) else: mapping_node.translation = (1.0, 1.0, 0.0) mapping_node.scale = (2.0, 2.0, 1.0) node_tree.links.new(tex_coord_node.outputs['Normal'], vector_transform_node.inputs['Vector']) node_tree.links.new(vector_transform_node.outputs['Vector'], mapping_node.inputs['Vector']) node_tree.links.new(mapping_node.outputs['Vector'], texture_image_node.inputs['Vector']) node_tree.links.new(texture_image_node.outputs['Color'], emmission_node.inputs['Color']) node_tree.links.new(emmission_node.outputs['Emission'], output_node.inputs['Surface']) arrange_nodes(node_tree)
def add_peeling_paint_metal_node_group() -> bpy.types.NodeGroup: group = bpy.data.node_groups.new(type="ShaderNodeTree", name="Peeling Paint Metal") input_node = group.nodes.new(type="NodeGroupInput") group.inputs.new("NodeSocketColor", "Paint Color") group.inputs.new("NodeSocketFloatFactor", "Paint Roughness") group.inputs.new("NodeSocketColor", "Metal Color") group.inputs.new("NodeSocketFloatFactor", "Metal Roughness") group.inputs.new("NodeSocketFloat", "Scale") group.inputs.new("NodeSocketFloat", "Detail") group.inputs.new("NodeSocketFloat", "Distortion") group.inputs.new("NodeSocketFloatFactor", "Threshold") group.inputs.new("NodeSocketFloat", "Peel Intense") group.inputs["Paint Color"].default_value = (0.152, 0.524, 0.067, 1.000) group.inputs["Metal Color"].default_value = (0.062, 0.015, 0.011, 1.000) set_socket_value_range(group.inputs["Paint Roughness"], default_value=0.05) set_socket_value_range(group.inputs["Metal Roughness"], default_value=0.50) set_socket_value_range(group.inputs["Scale"], default_value=4.5, min_value=0.0, max_value=1000.0) set_socket_value_range(group.inputs["Detail"], default_value=8.0, min_value=0.0, max_value=16.0) set_socket_value_range(group.inputs["Distortion"], default_value=0.5, min_value=0.0, max_value=1000.0) set_socket_value_range(group.inputs["Threshold"], default_value=0.42) set_socket_value_range(group.inputs["Peel Intense"], default_value=0.2, min_value=0.0, max_value=1.0) tex_coord_node = group.nodes.new(type="ShaderNodeTexCoord") mapping_node = group.nodes.new(type="ShaderNodeMapping") group.links.new(tex_coord_node.outputs["Object"], mapping_node.inputs["Vector"]) # Peeling region segmentation peeling_noise_node = group.nodes.new(type="ShaderNodeTexNoise") group.links.new(mapping_node.outputs["Vector"], peeling_noise_node.inputs["Vector"]) group.links.new(input_node.outputs["Scale"], peeling_noise_node.inputs["Scale"]) group.links.new(input_node.outputs["Detail"], peeling_noise_node.inputs["Detail"]) group.links.new(input_node.outputs["Distortion"], peeling_noise_node.inputs["Distortion"]) peeling_threshold_node = create_parametric_color_ramp_node(group) peeling_threshold_node.inputs["Color1"].default_value = (0.0, 0.0, 0.0, 1.0) peeling_threshold_node.inputs["Color2"].default_value = (1.0, 1.0, 1.0, 1.0) # Base color epsilon_subtract_node = group.nodes.new(type="ShaderNodeMath") epsilon_subtract_node.operation = "SUBTRACT" epsilon_subtract_node.inputs[1].default_value = 0.001 group.links.new(input_node.outputs["Threshold"], epsilon_subtract_node.inputs[0]) group.links.new(peeling_noise_node.outputs["Fac"], peeling_threshold_node.inputs["Fac"]) group.links.new(epsilon_subtract_node.outputs["Value"], peeling_threshold_node.inputs["Pos1"]) group.links.new(input_node.outputs["Threshold"], peeling_threshold_node.inputs["Pos2"]) color_mix_node = group.nodes.new(type="ShaderNodeMixRGB") group.links.new(peeling_threshold_node.outputs["Color"], color_mix_node.inputs["Fac"]) group.links.new(input_node.outputs["Metal Color"], color_mix_node.inputs[1]) group.links.new(input_node.outputs["Paint Color"], color_mix_node.inputs[2]) # Ambient occulusion epsilon_add_node = group.nodes.new(type="ShaderNodeMath") epsilon_add_node.operation = "ADD" epsilon_add_node.inputs[1].default_value = 0.010 group.links.new(input_node.outputs["Threshold"], epsilon_add_node.inputs[0]) fallout_subtract_node = group.nodes.new(type="ShaderNodeMath") fallout_subtract_node.operation = "SUBTRACT" fallout_subtract_node.inputs[1].default_value = 0.060 group.links.new(input_node.outputs["Threshold"], fallout_subtract_node.inputs[0]) ao_node = create_tri_parametric_color_ramp_node(group) ao_node.inputs["Color1"].default_value = (1.0, 1.0, 1.0, 1.0) ao_node.inputs["Color2"].default_value = (0.0, 0.0, 0.0, 1.0) ao_node.inputs["Color3"].default_value = (1.0, 1.0, 1.0, 1.0) group.links.new(peeling_noise_node.outputs["Fac"], ao_node.inputs["Fac"]) group.links.new(fallout_subtract_node.outputs["Value"], ao_node.inputs["Pos1"]) group.links.new(input_node.outputs["Threshold"], ao_node.inputs["Pos2"]) group.links.new(epsilon_add_node.outputs["Value"], ao_node.inputs["Pos3"]) ao_mix_node = group.nodes.new(type="ShaderNodeMixRGB") ao_mix_node.blend_type = "MULTIPLY" ao_mix_node.inputs["Fac"].default_value = 1.0 group.links.new(color_mix_node.outputs["Color"], ao_mix_node.inputs[1]) group.links.new(ao_node.outputs["Color"], ao_mix_node.inputs[2]) create_frame_node(group, nodes=(epsilon_add_node, fallout_subtract_node, ao_node), name="AO", label="AO") # Metallic metallic_node = group.nodes.new(type="ShaderNodeMixRGB") metallic_node.inputs["Color1"].default_value = (1.0, 1.0, 1.0, 1.0) metallic_node.inputs["Color2"].default_value = (0.0, 0.0, 0.0, 1.0) group.links.new(peeling_threshold_node.outputs["Color"], metallic_node.inputs["Fac"]) # Roughness roughness_node = group.nodes.new(type="ShaderNodeMixRGB") group.links.new(input_node.outputs["Metal Roughness"], roughness_node.inputs["Color1"]) group.links.new(input_node.outputs["Paint Roughness"], roughness_node.inputs["Color2"]) group.links.new(peeling_threshold_node.outputs["Color"], roughness_node.inputs["Fac"]) # Bump height_node = create_tri_parametric_color_ramp_node(group) height_node.inputs["Color1"].default_value = (0.0, 0.0, 0.0, 1.0) height_node.inputs["Color2"].default_value = (1.0, 1.0, 1.0, 1.0) height_node.inputs["Color3"].default_value = (0.5, 0.5, 0.5, 1.0) height_peak_add_node = group.nodes.new(type="ShaderNodeMath") height_peak_add_node.operation = "MULTIPLY_ADD" height_peak_add_node.inputs[1].default_value = 0.025 height_peak_add_node.label = "Height Peak Add" height_tail_add_node = group.nodes.new(type="ShaderNodeMath") height_tail_add_node.operation = "MULTIPLY_ADD" height_tail_add_node.inputs[1].default_value = 0.100 height_tail_add_node.label = "Height Tail Add" group.links.new(input_node.outputs["Threshold"], height_peak_add_node.inputs[2]) group.links.new(input_node.outputs["Peel Intense"], height_peak_add_node.inputs[0]) group.links.new(height_peak_add_node.outputs["Value"], height_tail_add_node.inputs[2]) group.links.new(input_node.outputs["Peel Intense"], height_tail_add_node.inputs[0]) group.links.new(peeling_noise_node.outputs["Fac"], height_node.inputs["Fac"]) group.links.new(input_node.outputs["Threshold"], height_node.inputs["Pos1"]) group.links.new(height_peak_add_node.outputs["Value"], height_node.inputs["Pos2"]) group.links.new(height_tail_add_node.outputs["Value"], height_node.inputs["Pos3"]) bump_node = group.nodes.new(type="ShaderNodeBump") group.links.new(height_node.outputs["Color"], bump_node.inputs["Height"]) create_frame_node(group, nodes=(height_node, height_peak_add_node, height_tail_add_node, bump_node), name="Bump", label="Bump") # Output output_node = group.nodes.new("NodeGroupOutput") group.outputs.new("NodeSocketColor", "Color") group.outputs.new("NodeSocketFloatFactor", "Metallic") group.outputs.new("NodeSocketFloatFactor", "Roughness") group.outputs.new("NodeSocketVectorDirection", "Bump") group.links.new(ao_mix_node.outputs["Color"], output_node.inputs["Color"]) group.links.new(metallic_node.outputs["Color"], output_node.inputs["Metallic"]) group.links.new(roughness_node.outputs["Color"], output_node.inputs["Roughness"]) group.links.new(bump_node.outputs["Normal"], output_node.inputs["Bump"]) arrange_nodes(group) return group