forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			216 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			216 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 
								 | 
							
								"""
							 | 
						||
| 
								 | 
							
								This module contains a list of all material nodes that Leenkx supports
							 | 
						||
| 
								 | 
							
								(excluding output nodes), as well as Leenkx-related metadata.
							 | 
						||
| 
								 | 
							
								"""
							 | 
						||
| 
								 | 
							
								from enum import IntEnum, unique
							 | 
						||
| 
								 | 
							
								from dataclasses import dataclass
							 | 
						||
| 
								 | 
							
								from typing import Any, Callable, Optional
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import bpy
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import lnx.material.lnx_nodes.shader_data_node as shader_data_node
							 | 
						||
| 
								 | 
							
								import lnx.material.cycles_nodes.nodes_color as nodes_color
							 | 
						||
| 
								 | 
							
								import lnx.material.cycles_nodes.nodes_converter as nodes_converter
							 | 
						||
| 
								 | 
							
								import lnx.material.cycles_nodes.nodes_input as nodes_input
							 | 
						||
| 
								 | 
							
								import lnx.material.cycles_nodes.nodes_shader as nodes_shader
							 | 
						||
| 
								 | 
							
								import lnx.material.cycles_nodes.nodes_texture as nodes_texture
							 | 
						||
| 
								 | 
							
								import lnx.material.cycles_nodes.nodes_vector as nodes_vector
							 | 
						||
| 
								 | 
							
								import lnx.material.parser_state
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if lnx.is_reload(__name__):
							 | 
						||
| 
								 | 
							
								    shader_data_node = lnx.reload_module(shader_data_node)
							 | 
						||
| 
								 | 
							
								    nodes_color = lnx.reload_module(nodes_color)
							 | 
						||
| 
								 | 
							
								    nodes_converter = lnx.reload_module(nodes_converter)
							 | 
						||
| 
								 | 
							
								    nodes_input = lnx.reload_module(nodes_input)
							 | 
						||
| 
								 | 
							
								    nodes_shader = lnx.reload_module(nodes_shader)
							 | 
						||
| 
								 | 
							
								    nodes_texture = lnx.reload_module(nodes_texture)
							 | 
						||
| 
								 | 
							
								    nodes_vector = lnx.reload_module(nodes_vector)
							 | 
						||
| 
								 | 
							
								    lnx.material.parser_state = lnx.reload_module(lnx.material.parser_state)
							 | 
						||
| 
								 | 
							
								else:
							 | 
						||
| 
								 | 
							
								    lnx.enable_reload(__name__)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@unique
							 | 
						||
| 
								 | 
							
								class ComputeDXDYVariant(IntEnum):
							 | 
						||
| 
								 | 
							
								    ALWAYS = 0
							 | 
						||
| 
								 | 
							
								    """Always compute dx/dy variants of the corresponding node.
							 | 
						||
| 
								 | 
							
								    Use this for input nodes that represent leafs of the node graph
							 | 
						||
| 
								 | 
							
								    if some of their output values vary between fragments.
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    NEVER = 1
							 | 
						||
| 
								 | 
							
								    """Never compute dx/dy variants of the corresponding node.
							 | 
						||
| 
								 | 
							
								    Use this for nodes whose output values do not change with respect
							 | 
						||
| 
								 | 
							
								    to fragment positions.
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DYNAMIC = 2
							 | 
						||
| 
								 | 
							
								    """Compute dx/dy variants if any input socket of the corresponding node
							 | 
						||
| 
								 | 
							
								    is connected to a node that requires dx/dy variants.
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@dataclass
							 | 
						||
| 
								 | 
							
								class MaterialNodeMeta:
							 | 
						||
| 
								 | 
							
								    # Use Any here due to contravariance
							 | 
						||
| 
								 | 
							
								    parse_func: Callable[[Any, bpy.types.NodeSocket, lnx.material.parser_state.ParserState], Optional[str]]
							 | 
						||
| 
								 | 
							
								    """The function used to parse this node and to translate it to GLSL output code."""
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    compute_dxdy_variants: ComputeDXDYVariant = ComputeDXDYVariant.DYNAMIC
							 | 
						||
| 
								 | 
							
								    """Specifies when this node should compute dx/dy variants
							 | 
						||
| 
								 | 
							
								    if the ParserState is in the dx/dy offset pass.
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ALL_NODES: dict[str, MaterialNodeMeta] = {
							 | 
						||
| 
								 | 
							
								    # --- nodes_color
							 | 
						||
| 
								 | 
							
								    'BRIGHTCONTRAST': MaterialNodeMeta(parse_func=nodes_color.parse_brightcontrast),
							 | 
						||
| 
								 | 
							
								    'CURVE_RGB': MaterialNodeMeta(parse_func=nodes_color.parse_curvergb),
							 | 
						||
| 
								 | 
							
								    'GAMMA': MaterialNodeMeta(parse_func=nodes_color.parse_gamma),
							 | 
						||
| 
								 | 
							
								    'HUE_SAT': MaterialNodeMeta(parse_func=nodes_color.parse_huesat),
							 | 
						||
| 
								 | 
							
								    'INVERT': MaterialNodeMeta(parse_func=nodes_color.parse_invert),
							 | 
						||
| 
								 | 
							
								    'LIGHT_FALLOFF': MaterialNodeMeta(parse_func=nodes_color.parse_lightfalloff),
							 | 
						||
| 
								 | 
							
								    'MIX': MaterialNodeMeta(parse_func=nodes_color.parse_mix),
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # --- nodes_converter
							 | 
						||
| 
								 | 
							
								    'BLACKBODY': MaterialNodeMeta(parse_func=nodes_converter.parse_blackbody),
							 | 
						||
| 
								 | 
							
								    'CLAMP': MaterialNodeMeta(parse_func=nodes_converter.parse_clamp),
							 | 
						||
| 
								 | 
							
								    'COMBHSV': MaterialNodeMeta(parse_func=nodes_converter.parse_combhsv),
							 | 
						||
| 
								 | 
							
								    'COMBRGB': MaterialNodeMeta(parse_func=nodes_converter.parse_combrgb),
							 | 
						||
| 
								 | 
							
								    'COMBXYZ': MaterialNodeMeta(parse_func=nodes_converter.parse_combxyz),
							 | 
						||
| 
								 | 
							
								    'MAP_RANGE': MaterialNodeMeta(parse_func=nodes_converter.parse_maprange),
							 | 
						||
| 
								 | 
							
								    'MATH': MaterialNodeMeta(parse_func=nodes_converter.parse_math),
							 | 
						||
| 
								 | 
							
								    'RGBTOBW': MaterialNodeMeta(parse_func=nodes_converter.parse_rgbtobw),
							 | 
						||
| 
								 | 
							
								    'SEPHSV': MaterialNodeMeta(parse_func=nodes_converter.parse_sephsv),
							 | 
						||
| 
								 | 
							
								    'SEPRGB': MaterialNodeMeta(parse_func=nodes_converter.parse_seprgb),
							 | 
						||
| 
								 | 
							
								    'SEPXYZ': MaterialNodeMeta(parse_func=nodes_converter.parse_sepxyz),
							 | 
						||
| 
								 | 
							
								    'VALTORGB': MaterialNodeMeta(parse_func=nodes_converter.parse_valtorgb),  # ColorRamp
							 | 
						||
| 
								 | 
							
								    'VECT_MATH': MaterialNodeMeta(parse_func=nodes_converter.parse_vectormath),
							 | 
						||
| 
								 | 
							
								    'WAVELENGTH': MaterialNodeMeta(parse_func=nodes_converter.parse_wavelength),
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # --- nodes_input
							 | 
						||
| 
								 | 
							
								    'ATTRIBUTE': MaterialNodeMeta(
							 | 
						||
| 
								 | 
							
								        parse_func=nodes_input.parse_attribute,
							 | 
						||
| 
								 | 
							
								        compute_dxdy_variants=ComputeDXDYVariant.ALWAYS
							 | 
						||
| 
								 | 
							
								    ),
							 | 
						||
| 
								 | 
							
								    'CAMERA': MaterialNodeMeta(
							 | 
						||
| 
								 | 
							
								        parse_func=nodes_input.parse_camera,
							 | 
						||
| 
								 | 
							
								        compute_dxdy_variants=ComputeDXDYVariant.ALWAYS
							 | 
						||
| 
								 | 
							
								    ),
							 | 
						||
| 
								 | 
							
								    'FRESNEL': MaterialNodeMeta(
							 | 
						||
| 
								 | 
							
								        parse_func=nodes_input.parse_fresnel,
							 | 
						||
| 
								 | 
							
								        compute_dxdy_variants=ComputeDXDYVariant.ALWAYS
							 | 
						||
| 
								 | 
							
								    ),
							 | 
						||
| 
								 | 
							
								    'HAIR_INFO': MaterialNodeMeta(parse_func=nodes_input.parse_hairinfo),
							 | 
						||
| 
								 | 
							
								    'LAYER_WEIGHT': MaterialNodeMeta(
							 | 
						||
| 
								 | 
							
								        parse_func=nodes_input.parse_layerweight,
							 | 
						||
| 
								 | 
							
								        compute_dxdy_variants=ComputeDXDYVariant.ALWAYS
							 | 
						||
| 
								 | 
							
								    ),
							 | 
						||
| 
								 | 
							
								    'LIGHT_PATH': MaterialNodeMeta(
							 | 
						||
| 
								 | 
							
								        parse_func=nodes_input.parse_lightpath,
							 | 
						||
| 
								 | 
							
								        compute_dxdy_variants=ComputeDXDYVariant.NEVER
							 | 
						||
| 
								 | 
							
								    ),
							 | 
						||
| 
								 | 
							
								    'NEW_GEOMETRY': MaterialNodeMeta(
							 | 
						||
| 
								 | 
							
								        parse_func=nodes_input.parse_geometry,
							 | 
						||
| 
								 | 
							
								        compute_dxdy_variants=ComputeDXDYVariant.ALWAYS
							 | 
						||
| 
								 | 
							
								    ),
							 | 
						||
| 
								 | 
							
								    'OBJECT_INFO': MaterialNodeMeta(
							 | 
						||
| 
								 | 
							
								        parse_func=nodes_input.parse_objectinfo,
							 | 
						||
| 
								 | 
							
								        compute_dxdy_variants=ComputeDXDYVariant.NEVER
							 | 
						||
| 
								 | 
							
								    ),
							 | 
						||
| 
								 | 
							
								    'PARTICLE_INFO': MaterialNodeMeta(
							 | 
						||
| 
								 | 
							
								        parse_func=nodes_input.parse_particleinfo,
							 | 
						||
| 
								 | 
							
								        compute_dxdy_variants=ComputeDXDYVariant.NEVER
							 | 
						||
| 
								 | 
							
								    ),
							 | 
						||
| 
								 | 
							
								    'RGB': MaterialNodeMeta(
							 | 
						||
| 
								 | 
							
								        parse_func=nodes_input.parse_rgb,
							 | 
						||
| 
								 | 
							
								        compute_dxdy_variants=ComputeDXDYVariant.NEVER
							 | 
						||
| 
								 | 
							
								    ),
							 | 
						||
| 
								 | 
							
								    'TANGENT': MaterialNodeMeta(
							 | 
						||
| 
								 | 
							
								        parse_func=nodes_input.parse_tangent,
							 | 
						||
| 
								 | 
							
								        compute_dxdy_variants=ComputeDXDYVariant.ALWAYS
							 | 
						||
| 
								 | 
							
								    ),
							 | 
						||
| 
								 | 
							
								    'TEX_COORD': MaterialNodeMeta(
							 | 
						||
| 
								 | 
							
								        parse_func=nodes_input.parse_texcoord,
							 | 
						||
| 
								 | 
							
								        compute_dxdy_variants=ComputeDXDYVariant.ALWAYS
							 | 
						||
| 
								 | 
							
								    ),
							 | 
						||
| 
								 | 
							
								    'UVMAP': MaterialNodeMeta(
							 | 
						||
| 
								 | 
							
								        parse_func=nodes_input.parse_uvmap,
							 | 
						||
| 
								 | 
							
								        compute_dxdy_variants=ComputeDXDYVariant.ALWAYS
							 | 
						||
| 
								 | 
							
								    ),
							 | 
						||
| 
								 | 
							
								    'VALUE': MaterialNodeMeta(
							 | 
						||
| 
								 | 
							
								        parse_func=nodes_input.parse_value,
							 | 
						||
| 
								 | 
							
								        compute_dxdy_variants=ComputeDXDYVariant.NEVER
							 | 
						||
| 
								 | 
							
								    ),
							 | 
						||
| 
								 | 
							
								    'VERTEX_COLOR': MaterialNodeMeta(parse_func=nodes_input.parse_vertex_color),
							 | 
						||
| 
								 | 
							
								    'WIREFRAME': MaterialNodeMeta(
							 | 
						||
| 
								 | 
							
								        parse_func=nodes_input.parse_wireframe,
							 | 
						||
| 
								 | 
							
								        compute_dxdy_variants=ComputeDXDYVariant.NEVER
							 | 
						||
| 
								 | 
							
								    ),
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # --- nodes_shader
							 | 
						||
| 
								 | 
							
								    'ADD_SHADER': MaterialNodeMeta(parse_func=nodes_shader.parse_addshader),
							 | 
						||
| 
								 | 
							
								    'AMBIENT_OCCLUSION': MaterialNodeMeta(parse_func=nodes_shader.parse_ambientocclusion),
							 | 
						||
| 
								 | 
							
								    'BSDF_ANISOTROPIC': MaterialNodeMeta(parse_func=nodes_shader.parse_bsdfanisotropic),
							 | 
						||
| 
								 | 
							
								    'BSDF_DIFFUSE': MaterialNodeMeta(parse_func=nodes_shader.parse_bsdfdiffuse),
							 | 
						||
| 
								 | 
							
								    'BSDF_GLASS': MaterialNodeMeta(parse_func=nodes_shader.parse_bsdfglass),
							 | 
						||
| 
								 | 
							
								    'BSDF_PRINCIPLED': MaterialNodeMeta(parse_func=nodes_shader.parse_bsdfprincipled),
							 | 
						||
| 
								 | 
							
								    'BSDF_TRANSLUCENT': MaterialNodeMeta(parse_func=nodes_shader.parse_bsdftranslucent),
							 | 
						||
| 
								 | 
							
								    'BSDF_TRANSPARENT': MaterialNodeMeta(parse_func=nodes_shader.parse_bsdftransparent),
							 | 
						||
| 
								 | 
							
								    'BSDF_REFRACTION': MaterialNodeMeta(parse_func=nodes_shader.parse_bsdfrefraction),
							 | 
						||
| 
								 | 
							
								    'EMISSION': MaterialNodeMeta(parse_func=nodes_shader.parse_emission),
							 | 
						||
| 
								 | 
							
								    'HOLDOUT': MaterialNodeMeta(
							 | 
						||
| 
								 | 
							
								        parse_func=nodes_shader.parse_holdout,
							 | 
						||
| 
								 | 
							
								        compute_dxdy_variants=ComputeDXDYVariant.NEVER
							 | 
						||
| 
								 | 
							
								    ),
							 | 
						||
| 
								 | 
							
								    'MIX_SHADER': MaterialNodeMeta(parse_func=nodes_shader.parse_mixshader),
							 | 
						||
| 
								 | 
							
								    'SUBSURFACE_SCATTERING': MaterialNodeMeta(parse_func=nodes_shader.parse_subsurfacescattering),
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # --- nodes_texture
							 | 
						||
| 
								 | 
							
								    'TEX_BRICK': MaterialNodeMeta(parse_func=nodes_texture.parse_tex_brick),
							 | 
						||
| 
								 | 
							
								    'TEX_CHECKER': MaterialNodeMeta(parse_func=nodes_texture.parse_tex_checker),
							 | 
						||
| 
								 | 
							
								    'TEX_ENVIRONMENT': MaterialNodeMeta(parse_func=nodes_texture.parse_tex_environment),
							 | 
						||
| 
								 | 
							
								    'TEX_GRADIENT': MaterialNodeMeta(parse_func=nodes_texture.parse_tex_gradient),
							 | 
						||
| 
								 | 
							
								    'TEX_IMAGE': MaterialNodeMeta(parse_func=nodes_texture.parse_tex_image),
							 | 
						||
| 
								 | 
							
								    'TEX_MAGIC': MaterialNodeMeta(parse_func=nodes_texture.parse_tex_magic),
							 | 
						||
| 
								 | 
							
								    'TEX_NOISE': MaterialNodeMeta(parse_func=nodes_texture.parse_tex_noise),
							 | 
						||
| 
								 | 
							
								    'TEX_POINTDENSITY': MaterialNodeMeta(
							 | 
						||
| 
								 | 
							
								        parse_func=nodes_texture.parse_tex_pointdensity,
							 | 
						||
| 
								 | 
							
								        compute_dxdy_variants=ComputeDXDYVariant.NEVER
							 | 
						||
| 
								 | 
							
								    ),
							 | 
						||
| 
								 | 
							
								    'TEX_SKY': MaterialNodeMeta(parse_func=nodes_texture.parse_tex_sky),
							 | 
						||
| 
								 | 
							
								    'TEX_VORONOI': MaterialNodeMeta(parse_func=nodes_texture.parse_tex_voronoi),
							 | 
						||
| 
								 | 
							
								    'TEX_WAVE': MaterialNodeMeta(parse_func=nodes_texture.parse_tex_wave),
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # --- nodes_vector
							 | 
						||
| 
								 | 
							
								    'BUMP': MaterialNodeMeta(parse_func=nodes_vector.parse_bump),
							 | 
						||
| 
								 | 
							
								    'CURVE_VEC': MaterialNodeMeta(parse_func=nodes_vector.parse_curvevec),
							 | 
						||
| 
								 | 
							
								    'DISPLACEMENT': MaterialNodeMeta(parse_func=nodes_vector.parse_displacement),
							 | 
						||
| 
								 | 
							
								    'MAPPING': MaterialNodeMeta(parse_func=nodes_vector.parse_mapping),
							 | 
						||
| 
								 | 
							
								    'NORMAL': MaterialNodeMeta(parse_func=nodes_vector.parse_normal),
							 | 
						||
| 
								 | 
							
								    'NORMAL_MAP': MaterialNodeMeta(parse_func=nodes_vector.parse_normalmap),
							 | 
						||
| 
								 | 
							
								    'VECTOR_ROTATE': MaterialNodeMeta(parse_func=nodes_vector.parse_vectorrotate),
							 | 
						||
| 
								 | 
							
								    'VECT_TRANSFORM': MaterialNodeMeta(parse_func=nodes_vector.parse_vectortransform),
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # --- lnx_nodes
							 | 
						||
| 
								 | 
							
								    'LnxShaderDataNode': MaterialNodeMeta(
							 | 
						||
| 
								 | 
							
								        parse_func=shader_data_node.ShaderDataNode.parse,
							 | 
						||
| 
								 | 
							
								        compute_dxdy_variants=ComputeDXDYVariant.ALWAYS
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if bpy.app.version > (3, 2, 0):
							 | 
						||
| 
								 | 
							
								    ALL_NODES['SEPARATE_COLOR'] = MaterialNodeMeta(parse_func=nodes_converter.parse_separate_color)
							 | 
						||
| 
								 | 
							
								    ALL_NODES['COMBINE_COLOR'] = MaterialNodeMeta(parse_func=nodes_converter.parse_combine_color)
							 | 
						||
| 
								 | 
							
								if bpy.app.version < (4, 1, 0):
							 | 
						||
| 
								 | 
							
								    ALL_NODES['BSDF_VELVET'] = MaterialNodeMeta(parse_func=nodes_shader.parse_bsdfvelvet)
							 | 
						||
| 
								 | 
							
								    ALL_NODES['TEX_MUSGRAVE'] = MaterialNodeMeta(parse_func=nodes_texture.parse_tex_musgrave)
							 | 
						||
| 
								 | 
							
								if bpy.app.version >= (4, 0, 0):
							 | 
						||
| 
								 | 
							
								    ALL_NODES['BSDF_SHEEN'] = MaterialNodeMeta(parse_func=nodes_shader.parse_bsdfsheen)
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								ALL_NODES['BSDF_GLOSSY'] = MaterialNodeMeta(parse_func=nodes_shader.parse_bsdfglossy)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def get_node_meta(node: bpy.types.Node) -> MaterialNodeMeta:
							 | 
						||
| 
								 | 
							
								    type_identifier = node.type if node.type != 'CUSTOM' else node.bl_idname
							 | 
						||
| 
								 | 
							
								    return ALL_NODES[type_identifier]
							 |