nbv_rec_blender_render/utils/material_util.py
2024-10-18 20:46:31 +08:00

96 lines
4.1 KiB
Python

import bpy
class MaterialUtil:
''' --------- Basic --------- '''
@staticmethod
def change_object_material(obj, mat):
if obj.data.materials:
obj.data.materials[0] = mat
else:
obj.data.materials.append(mat)
''' ------- Materials ------- '''
@staticmethod
def create_normal_material():
normal_mat = bpy.data.materials.new(name="NormalMaterial")
normal_mat.use_nodes = True
nodes = normal_mat.node_tree.nodes
links = normal_mat.node_tree.links
nodes.clear()
geometry_node = nodes.new(type="ShaderNodeNewGeometry")
vector_transform_node = nodes.new(type="ShaderNodeVectorTransform")
separate_xyz_node = nodes.new(type="ShaderNodeSeparateXYZ")
multiply_node_x = nodes.new(type="ShaderNodeMath")
multiply_node_y = nodes.new(type="ShaderNodeMath")
multiply_node_z = nodes.new(type="ShaderNodeMath")
combine_xyz_node = nodes.new(type="ShaderNodeCombineXYZ")
light_path_node = nodes.new(type="ShaderNodeLightPath")
emission_node_1 = nodes.new(type="ShaderNodeEmission")
emission_node_2 = nodes.new(type="ShaderNodeEmission")
mix_shader_node_1 = nodes.new(type="ShaderNodeMixShader")
mix_shader_node_2 = nodes.new(type="ShaderNodeMixShader")
material_output_node = nodes.new(type="ShaderNodeOutputMaterial")
vector_transform_node.vector_type = 'VECTOR'
vector_transform_node.convert_from = 'WORLD'
vector_transform_node.convert_to = 'CAMERA'
multiply_node_x.operation = 'MULTIPLY'
multiply_node_x.inputs[1].default_value = 1.0
multiply_node_y.operation = 'MULTIPLY'
multiply_node_y.inputs[1].default_value = 1.0
multiply_node_z.operation = 'MULTIPLY'
multiply_node_z.inputs[1].default_value = -1.0
emission_node_1.inputs['Strength'].default_value = 1.0
emission_node_2.inputs['Strength'].default_value = 1.0
mix_shader_node_2.inputs['Fac'].default_value = 0.5
links.new(geometry_node.outputs['Normal'], vector_transform_node.inputs['Vector'])
links.new(vector_transform_node.outputs['Vector'], separate_xyz_node.inputs['Vector'])
links.new(separate_xyz_node.outputs['X'], multiply_node_x.inputs[0])
links.new(separate_xyz_node.outputs['Y'], multiply_node_y.inputs[0])
links.new(separate_xyz_node.outputs['Z'], multiply_node_z.inputs[0])
links.new(multiply_node_x.outputs['Value'], combine_xyz_node.inputs['X'])
links.new(multiply_node_y.outputs['Value'], combine_xyz_node.inputs['Y'])
links.new(multiply_node_z.outputs['Value'], combine_xyz_node.inputs['Z'])
links.new(combine_xyz_node.outputs['Vector'], emission_node_1.inputs['Color'])
links.new(light_path_node.outputs['Is Camera Ray'], mix_shader_node_1.inputs['Fac'])
links.new(emission_node_1.outputs['Emission'], mix_shader_node_1.inputs[2])
links.new(mix_shader_node_1.outputs['Shader'], mix_shader_node_2.inputs[1])
links.new(emission_node_2.outputs['Emission'], mix_shader_node_2.inputs[2])
links.new(mix_shader_node_2.outputs['Shader'], material_output_node.inputs['Surface'])
return normal_mat
@staticmethod
def create_mask_material(color=(1.0, 1.0, 1.0)):
mask_mat = bpy.data.materials.new(name="MaskMaterial")
mask_mat.use_nodes = True
nodes = mask_mat.node_tree.nodes
links = mask_mat.node_tree.links
nodes.clear()
emission_node = nodes.new(type="ShaderNodeEmission")
emission_node.inputs['Color'].default_value = (*color, 1.0)
emission_node.inputs['Strength'].default_value = 1.0
material_output_node = nodes.new(type="ShaderNodeOutputMaterial")
links.new(emission_node.outputs['Emission'], material_output_node.inputs['Surface'])
return mask_mat
# -------- debug --------
if __name__ == "__main__":
cube = bpy.data.objects.get("Cube")
normal_mat = MaterialUtil.create_normal_material()
MaterialUtil.change_object_material(cube, normal_mat)