import bpy from bpy.types import NodeSocket import lnx import lnx.material.cycles as c import lnx.material.mat_state as mat_state import lnx.material.mat_utils as mat_utils from lnx.material.parser_state import ParserState if lnx.is_reload(__name__): c = lnx.reload_module(c) mat_state = lnx.reload_module(mat_state) mat_utils = lnx.reload_module(mat_utils) lnx.material.parser_state = lnx.reload_module(lnx.material.parser_state) from lnx.material.parser_state import ParserState else: lnx.enable_reload(__name__) # Principled BSDF socket names that differ between Blender versions if bpy.app.version < (4, 0, 0): EMISSION_COLOR = 'Emission' SUBSURFACE = 'Subsurface' SUBSURFACE_RADIUS = 'Subsurface Radius' SUBSURFACE_COLOR = 'Subsurface Color' SPECULAR = 'Specular' SPECULAR_TINT = 'Specular Tint' ANISOTROPIC = 'Anisotropic' ANISOTROPIC_ROT = 'Anisotropic Rotation' SHEEN = 'Sheen' SHEEN_TINT = 'Sheen Tint' CLEARCOAT = 'Clearcoat' CLEARCOAT_ROUGHNESS = 'Clearcoat Roughness' CLEARCOAT_NORMAL = 'Clearcoat Normal' TRANSMISSION = 'Transmission' TRANSMISSION_ROUGHNESS = 'Transmission Roughness' TANGENT = 'Tangent' else: EMISSION_COLOR = 'Emission Color' SUBSURFACE = 'Subsurface Weight' SUBSURFACE_RADIUS = 'Subsurface Radius' SUBSURFACE_COLOR = 'Subsurface Color' SPECULAR = 'Specular IOR Level' SPECULAR_TINT = 'Specular Tint' ANISOTROPIC = 'Anisotropic' ANISOTROPIC_ROT = 'Anisotropic Rotation' SHEEN = 'Sheen Weight' SHEEN_TINT = 'Sheen Tint' SHEEN_ROUGHNESS = 'Sheen Roughness' CLEARCOAT = 'Coat Weight' CLEARCOAT_ROUGHNESS = 'Coat Roughness' CLEARCOAT_NORMAL = 'Coat Normal' COAT_IOR = 'Coat IOR' COAT_TINT = 'Coat Tint' TRANSMISSION = 'Transmission Weight' TRANSMISSION_ROUGHNESS = 'Transmission Roughness' TANGENT = 'Tangent' THIN_WALL = 'Thin Wall' SUBSURFACE_SCALE = 'Subsurface Scale' SUBSURFACE_ANISOTROPY = 'Subsurface Anisotropy' def parse_mixshader(node: bpy.types.ShaderNodeMixShader, out_socket: NodeSocket, state: ParserState) -> None: # Skip mixing if only one input is effectively used if not node.inputs['Fac'].is_linked: if node.inputs['Fac'].default_value <= 0.0: c.parse_shader_input(node.inputs[1]) return elif node.inputs['Fac'].default_value >= 1.0: c.parse_shader_input(node.inputs[2]) return prefix = '' if node.inputs['Fac'].is_linked else 'const ' fac = c.parse_value_input(node.inputs['Fac']) fac_var = c.node_name(node.name) + '_fac' + state.get_parser_pass_suffix() fac_inv_var = c.node_name(node.name) + '_fac_inv' state.curshader.write('{0}float {1} = clamp({2}, 0.0, 1.0);'.format(prefix, fac_var, fac)) state.curshader.write('{0}float {1} = 1.0 - {2};'.format(prefix, fac_inv_var, fac_var)) mat_state.emission_type = mat_state.EmissionType.NO_EMISSION o1 = c.parse_shader_input(node.inputs[1]) ek1 = mat_state.emission_type mat_state.emission_type = mat_state.EmissionType.NO_EMISSION o2 = c.parse_shader_input(node.inputs[2]) ek2 = mat_state.emission_type if state.parse_surface: fm = '{0} * {3} + {1} * {2}' # fac mix template: a*fac_inv + b*fac fv = (fac_var, fac_inv_var) state.out_basecol = fm.format(o1[0], o2[0], fv[0], fv[1]) state.out_roughness = fm.format(o1[1], o2[1], fv[0], fv[1]) state.out_metallic = fm.format(o1[2], o2[2], fv[0], fv[1]) state.out_occlusion = fm.format(o1[3], o2[3], fv[0], fv[1]) state.out_specular = fm.format(o1[4], o2[4], fv[0], fv[1]) state.out_emission_col = fm.format(o1[7], o2[7], fv[0], fv[1]) state.out_subsurface = fm.format(o1[8], o2[8], fv[0], fv[1]) state.out_subsurface_radius = fm.format(o1[9], o2[9], fv[0], fv[1]) state.out_subsurface_color = fm.format(o1[10], o2[10], fv[0], fv[1]) state.out_specular_tint = fm.format(o1[11], o2[11], fv[0], fv[1]) state.out_anisotropy = fm.format(o1[12], o2[12], fv[0], fv[1]) state.out_aniso_rot = fm.format(o1[13], o2[13], fv[0], fv[1]) state.out_sheen = fm.format(o1[14], o2[14], fv[0], fv[1]) state.out_sheen_rough = fm.format(o1[15], o2[15], fv[0], fv[1]) state.out_sheen_tint = fm.format(o1[16], o2[16], fv[0], fv[1]) state.out_clearcoat = fm.format(o1[17], o2[17], fv[0], fv[1]) state.out_clearcoat_rough = fm.format(o1[18], o2[18], fv[0], fv[1]) state.out_transmission = fm.format(o1[19], o2[19], fv[0], fv[1]) state.out_transmission_rough = fm.format(o1[20], o2[20], fv[0], fv[1]) state.out_thin_wall = fm.format(o1[21], o2[21], fv[0], fv[1]) state.out_tangent = fm.format(o1[22], o2[22], fv[0], fv[1]) state.out_subsurface_scale = fm.format(o1[23], o2[23], fv[0], fv[1]) state.out_subsurface_anisotropy = fm.format(o1[24], o2[24], fv[0], fv[1]) state.out_coat_ior = fm.format(o1[25], o2[25], fv[0], fv[1]) state.out_coat_tint = fm.format(o1[26], o2[26], fv[0], fv[1]) mat_state.emission_type = mat_state.EmissionType.get_effective_combination(ek1, ek2) if state.parse_opacity: fm = '{0} * {3} + {1} * {2}' fv = (fac_var, fac_inv_var) state.out_opacity = fm.format(o1[5], o2[5], fv[0], fv[1]) state.out_ior = fm.format(o1[6], o2[6], fv[0], fv[1]) def parse_addshader(node: bpy.types.ShaderNodeAddShader, out_socket: NodeSocket, state: ParserState) -> None: mat_state.emission_type = mat_state.EmissionType.NO_EMISSION o1 = c.parse_shader_input(node.inputs[0]) ek1 = mat_state.emission_type mat_state.emission_type = mat_state.EmissionType.NO_EMISSION o2 = c.parse_shader_input(node.inputs[1]) ek2 = mat_state.emission_type if state.parse_surface: am = '{0} * 0.5 + {1} * 0.5' # add mix template (average) state.out_basecol = '({0} + {1})'.format(o1[0], o2[0]) state.out_roughness = am.format(o1[1], o2[1]) state.out_metallic = am.format(o1[2], o2[2]) state.out_occlusion = am.format(o1[3], o2[3]) state.out_specular = am.format(o1[4], o2[4]) state.out_emission_col = '({0} + {1})'.format(o1[7], o2[7]) state.out_subsurface = am.format(o1[8], o2[8]) state.out_subsurface_radius = am.format(o1[9], o2[9]) state.out_subsurface_color = am.format(o1[10], o2[10]) state.out_specular_tint = am.format(o1[11], o2[11]) state.out_anisotropy = am.format(o1[12], o2[12]) state.out_aniso_rot = am.format(o1[13], o2[13]) state.out_sheen = am.format(o1[14], o2[14]) state.out_sheen_rough = am.format(o1[15], o2[15]) state.out_sheen_tint = am.format(o1[16], o2[16]) state.out_clearcoat = am.format(o1[17], o2[17]) state.out_clearcoat_rough = am.format(o1[18], o2[18]) state.out_transmission = am.format(o1[19], o2[19]) state.out_transmission_rough = am.format(o1[20], o2[20]) state.out_thin_wall = am.format(o1[21], o2[21]) state.out_tangent = am.format(o1[22], o2[22]) state.out_subsurface_scale = am.format(o1[23], o2[23]) state.out_subsurface_anisotropy = am.format(o1[24], o2[24]) state.out_coat_ior = am.format(o1[25], o2[25]) state.out_coat_tint = am.format(o1[26], o2[26]) mat_state.emission_type = mat_state.EmissionType.get_effective_combination(ek1, ek2) if state.parse_opacity: am = '{0} * 0.5 + {1} * 0.5' state.out_opacity = am.format(o1[5], o2[5]) state.out_ior = am.format(o1[6], o2[6]) # TODO: Refactor using c.get_*_input() if bpy.app.version < (2, 91, 0): def parse_bsdfprincipled(node: bpy.types.ShaderNodeBsdfPrincipled, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: c.write_normal(node.inputs['Normal']) state.out_basecol = c.parse_vector_input(node.inputs['Base Color']) state.out_subsurface = c.parse_value_input(node.inputs[SUBSURFACE]) state.out_subsurface_radius = c.parse_vector_input(node.inputs[SUBSURFACE_RADIUS]) state.out_subsurface_color = c.parse_vector_input(node.inputs[SUBSURFACE_COLOR]) state.out_metallic = c.parse_value_input(node.inputs['Metallic']) state.out_specular = c.parse_value_input(node.inputs[SPECULAR]) state.out_specular_tint = 'vec3({})'.format(c.parse_value_input(node.inputs[SPECULAR_TINT])) state.out_roughness = c.parse_value_input(node.inputs['Roughness']) state.out_anisotropy = c.parse_value_input(node.inputs[ANISOTROPIC]) state.out_aniso_rot = c.parse_value_input(node.inputs[ANISOTROPIC_ROT]) state.out_sheen = c.parse_value_input(node.inputs[SHEEN]) state.out_sheen_tint = 'vec3({})'.format(c.parse_value_input(node.inputs[SHEEN_TINT])) state.out_clearcoat = c.parse_value_input(node.inputs[CLEARCOAT]) state.out_clearcoat_rough = c.parse_value_input(node.inputs[CLEARCOAT_ROUGHNESS]) coat_normal_socket = node.inputs.get(CLEARCOAT_NORMAL) if coat_normal_socket is not None: c.write_normal(coat_normal_socket, target_var='nCoat') state.out_transmission = c.parse_value_input(node.inputs[TRANSMISSION]) trans_rough_socket = node.inputs.get(TRANSMISSION_ROUGHNESS) if trans_rough_socket is not None: state.out_transmission_rough = c.parse_value_input(trans_rough_socket) state.out_tangent = c.parse_vector_input(node.inputs[TANGENT]) if node.inputs[EMISSION_COLOR].is_linked or not mat_utils.equals_color_socket(node.inputs[EMISSION_COLOR], (0.0, 0.0, 0.0), comp_alpha=False): emission_col = c.parse_vector_input(node.inputs[EMISSION_COLOR]) state.out_emission_col = emission_col mat_state.emission_type = mat_state.EmissionType.SHADED else: mat_state.emission_type = mat_state.EmissionType.NO_EMISSION if state.parse_opacity: state.out_ior = c.parse_value_input(node.inputs['IOR']) if 'Alpha' in node.inputs: state.out_opacity = c.parse_value_input(node.inputs['Alpha']) else: state.out_opacity = '1.0' if bpy.app.version >= (2, 91, 0) and bpy.app.version < (4, 0, 0): def parse_bsdfprincipled(node: bpy.types.ShaderNodeBsdfPrincipled, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: c.write_normal(node.inputs['Normal']) state.out_basecol = c.parse_vector_input(node.inputs['Base Color']) state.out_subsurface = c.parse_value_input(node.inputs[SUBSURFACE]) state.out_subsurface_radius = c.parse_vector_input(node.inputs[SUBSURFACE_RADIUS]) state.out_subsurface_color = c.parse_vector_input(node.inputs[SUBSURFACE_COLOR]) state.out_metallic = c.parse_value_input(node.inputs['Metallic']) state.out_specular = c.parse_value_input(node.inputs[SPECULAR]) state.out_specular_tint = 'vec3({})'.format(c.parse_value_input(node.inputs[SPECULAR_TINT])) state.out_roughness = c.parse_value_input(node.inputs['Roughness']) state.out_anisotropy = c.parse_value_input(node.inputs[ANISOTROPIC]) state.out_aniso_rot = c.parse_value_input(node.inputs[ANISOTROPIC_ROT]) state.out_sheen = c.parse_value_input(node.inputs[SHEEN]) state.out_sheen_tint = 'vec3({})'.format(c.parse_value_input(node.inputs[SHEEN_TINT])) state.out_clearcoat = c.parse_value_input(node.inputs[CLEARCOAT]) state.out_clearcoat_rough = c.parse_value_input(node.inputs[CLEARCOAT_ROUGHNESS]) coat_normal_socket = node.inputs.get(CLEARCOAT_NORMAL) if coat_normal_socket is not None: c.write_normal(coat_normal_socket, target_var='nCoat') state.out_transmission = c.parse_value_input(node.inputs[TRANSMISSION]) state.out_transmission_rough = c.parse_value_input(node.inputs[TRANSMISSION_ROUGHNESS]) state.out_tangent = c.parse_vector_input(node.inputs[TANGENT]) if (node.inputs['Emission Strength'].is_linked or node.inputs['Emission Strength'].default_value != 0.0)\ and (node.inputs[EMISSION_COLOR].is_linked or not mat_utils.equals_color_socket(node.inputs[EMISSION_COLOR], (0.0, 0.0, 0.0), comp_alpha=False)): emission_col = c.parse_vector_input(node.inputs[EMISSION_COLOR]) emission_strength = c.parse_value_input(node.inputs['Emission Strength']) state.out_emission_col = '({0} * {1})'.format(emission_col, emission_strength) mat_state.emission_type = mat_state.EmissionType.SHADED else: mat_state.emission_type = mat_state.EmissionType.NO_EMISSION if state.parse_opacity: state.out_ior = c.parse_value_input(node.inputs['IOR']) if 'Alpha' in node.inputs: state.out_opacity = c.parse_value_input(node.inputs['Alpha']) else: state.out_opacity = '1.0' if bpy.app.version >= (4, 0, 0): def parse_bsdfprincipled(node: bpy.types.ShaderNodeBsdfPrincipled, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: c.write_normal(node.inputs['Normal']) state.out_basecol = c.parse_vector_input(node.inputs['Base Color']) sss_input = node.inputs.get(SUBSURFACE) if sss_input is not None: state.out_subsurface = c.parse_value_input(sss_input) sss_radius_input = node.inputs.get(SUBSURFACE_RADIUS) if sss_radius_input is not None: state.out_subsurface_radius = c.parse_vector_input(sss_radius_input) sss_scale_input = node.inputs.get(SUBSURFACE_SCALE) if sss_scale_input is not None: state.out_subsurface_scale = c.parse_value_input(sss_scale_input) sss_aniso_input = node.inputs.get(SUBSURFACE_ANISOTROPY) if sss_aniso_input is not None: state.out_subsurface_anisotropy = c.parse_value_input(sss_aniso_input) sss_color_input = node.inputs.get(SUBSURFACE_COLOR) if sss_color_input is not None: state.out_subsurface_color = c.parse_vector_input(sss_color_input) else: state.out_subsurface_color = c.parse_vector_input(node.inputs['Base Color']) state.out_metallic = c.parse_value_input(node.inputs['Metallic']) specular_socket = node.inputs.get(SPECULAR) if specular_socket is not None: state.out_specular = f'({c.parse_value_input(specular_socket)} * 2.0)' else: specular_socket = node.inputs.get('Specular') if specular_socket is not None: state.out_specular = c.parse_value_input(specular_socket) else: state.out_specular = '1.0' spec_tint_socket = node.inputs.get(SPECULAR_TINT) if spec_tint_socket is not None: state.out_specular_tint = c.parse_vector_input(spec_tint_socket) state.out_roughness = c.parse_value_input(node.inputs['Roughness']) # Prevent black material when metal = 1.0 and roughness = 0.0 try: if float(state.out_roughness) < 0.00101: state.out_roughness = '0.001' except ValueError: pass aniso_socket = node.inputs.get(ANISOTROPIC) if aniso_socket is not None: state.out_anisotropy = c.parse_value_input(aniso_socket) aniso_rot_socket = node.inputs.get(ANISOTROPIC_ROT) if aniso_rot_socket is not None: state.out_aniso_rot = c.parse_value_input(aniso_rot_socket) sheen_socket = node.inputs.get(SHEEN) if sheen_socket is not None: state.out_sheen = c.parse_value_input(sheen_socket) sheen_rough_socket = node.inputs.get(SHEEN_ROUGHNESS) if sheen_rough_socket is not None: state.out_sheen_rough = c.parse_value_input(sheen_rough_socket) sheen_tint_socket = node.inputs.get(SHEEN_TINT) if sheen_tint_socket is not None: state.out_sheen_tint = c.parse_vector_input(sheen_tint_socket) coat_socket = node.inputs.get(CLEARCOAT) if coat_socket is not None: state.out_clearcoat = c.parse_value_input(coat_socket) coat_rough_socket = node.inputs.get(CLEARCOAT_ROUGHNESS) if coat_rough_socket is not None: state.out_clearcoat_rough = c.parse_value_input(coat_rough_socket) coat_ior_socket = node.inputs.get(COAT_IOR) if coat_ior_socket is not None: state.out_coat_ior = c.parse_value_input(coat_ior_socket) coat_tint_socket = node.inputs.get(COAT_TINT) if coat_tint_socket is not None: state.out_coat_tint = c.parse_vector_input(coat_tint_socket) coat_normal_socket = node.inputs.get(CLEARCOAT_NORMAL) if coat_normal_socket is not None: c.write_normal(coat_normal_socket, target_var='nCoat') trans_socket = node.inputs.get(TRANSMISSION) if trans_socket is not None: state.out_transmission = c.parse_value_input(trans_socket) trans_rough_socket = node.inputs.get(TRANSMISSION_ROUGHNESS) if trans_rough_socket is not None: state.out_transmission_rough = c.parse_value_input(trans_rough_socket) thin_wall_socket = node.inputs.get(THIN_WALL) if thin_wall_socket is not None: state.out_thin_wall = c.parse_value_input(thin_wall_socket) tangent_socket = node.inputs.get(TANGENT) if tangent_socket is not None: state.out_tangent = c.parse_vector_input(tangent_socket) if (node.inputs['Emission Strength'].is_linked or node.inputs['Emission Strength'].default_value != 0.0)\ and (node.inputs[EMISSION_COLOR].is_linked or not mat_utils.equals_color_socket(node.inputs[EMISSION_COLOR], (0.0, 0.0, 0.0), comp_alpha=False)): emission_col = c.parse_vector_input(node.inputs[EMISSION_COLOR]) emission_strength = c.parse_value_input(node.inputs['Emission Strength']) state.out_emission_col = '({0} * {1})'.format(emission_col, emission_strength) mat_state.emission_type = mat_state.EmissionType.SHADED else: mat_state.emission_type = mat_state.EmissionType.NO_EMISSION if state.parse_opacity: state.out_ior = c.parse_value_input(node.inputs['IOR']) state.out_opacity = c.parse_value_input(node.inputs['Alpha']) def parse_bsdfdiffuse(node: bpy.types.ShaderNodeBsdfDiffuse, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: c.write_normal(node.inputs['Normal']) state.out_basecol = c.parse_vector_input(node.inputs['Color']) state.out_roughness = c.parse_value_input(node.inputs['Roughness']) state.out_specular = '0.0' if bpy.app.version >= (4, 0, 0): def parse_bsdfsheen(node: bpy.types.ShaderNodeBsdfSheen, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: c.write_normal(node.inputs['Normal']) state.out_basecol = c.parse_vector_input(node.inputs['Color']) state.out_roughness = c.parse_value_input(node.inputs['Roughness']) if bpy.app.version < (4, 0, 0): def parse_bsdfglossy(node: bpy.types.ShaderNodeBsdfGlossy, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: c.write_normal(node.inputs['Normal']) state.out_basecol = c.parse_vector_input(node.inputs['Color']) state.out_roughness = c.parse_value_input(node.inputs['Roughness']) state.out_metallic = '1.0' else: def parse_bsdfglossy(node: bpy.types.ShaderNodeBsdfAnisotropic, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: c.write_normal(node.inputs['Normal']) state.out_basecol = c.parse_vector_input(node.inputs['Color']) state.out_roughness = c.parse_value_input(node.inputs['Roughness']) state.out_metallic = '1.0' def parse_ambientocclusion(node: bpy.types.ShaderNodeAmbientOcclusion, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: # Single channel state.out_occlusion = c.parse_vector_input(node.inputs['Distance']) + '.r' def parse_bsdfanisotropic(node: bpy.types.ShaderNodeBsdfAnisotropic, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: c.write_normal(node.inputs['Normal']) # Revert to glossy state.out_basecol = c.parse_vector_input(node.inputs['Color']) state.out_roughness = c.parse_value_input(node.inputs['Roughness']) state.out_metallic = '1.0' def parse_emission(node: bpy.types.ShaderNodeEmission, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: emission_col = c.parse_vector_input(node.inputs['Color']) emission_strength = c.parse_value_input(node.inputs['Strength']) state.out_emission_col = '({0} * {1})'.format(emission_col, emission_strength) state.out_basecol = 'vec3(0.0)' state.out_specular = '0.0' state.out_metallic = '0.0' mat_state.emission_type = mat_state.EmissionType.SHADELESS def parse_bsdfglass(node: bpy.types.ShaderNodeBsdfGlass, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: state.out_basecol = c.parse_vector_input(node.inputs['Color']) c.write_normal(node.inputs['Normal']) state.out_roughness = c.parse_value_input(node.inputs['Roughness']) if state.parse_opacity: state.out_opacity = '1.0' state.out_ior = c.parse_value_input(node.inputs['IOR']) def parse_bsdfhair(node: bpy.types.ShaderNodeBsdfHair, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: state.out_basecol = c.parse_vector_input(node.inputs['Color']) state.out_roughness = c.parse_value_input(node.inputs['RoughnessU']) state.out_specular = '0.0' rough_v_socket = node.inputs.get('RoughnessV') if rough_v_socket is not None: state.out_aniso_rot = c.parse_value_input(rough_v_socket) tangent_socket = node.inputs.get('Tangent') if tangent_socket is not None: state.out_tangent = c.parse_vector_input(tangent_socket) if bpy.app.version >= (2, 83, 0): def parse_bsdfhairprincipled(node: 'bpy.types.ShaderNodeBsdfHairPrincipled', out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: c.write_normal(node.inputs['Normal']) parametrization = getattr(node, 'parametrization', 'COLOR') if parametrization == 'COLOR': color_socket = node.inputs.get('Color') if color_socket is not None: state.out_basecol = c.parse_vector_input(color_socket) elif parametrization == 'MELANIN': melanin_socket = node.inputs.get('Melanin') if melanin_socket is not None: state.out_subsurface = c.parse_value_input(melanin_socket) melanin_red_socket = node.inputs.get('Melanin Redness') if melanin_red_socket is not None: state.out_specular_tint = 'vec3({})'.format(c.parse_value_input(melanin_red_socket)) elif parametrization == 'ABSORPTION': absorption_socket = node.inputs.get('Absorption Coefficient') if absorption_socket is not None: state.out_specular_tint = c.parse_vector_input(absorption_socket) tint_socket = node.inputs.get('Tint') if tint_socket is not None: state.out_subsurface_color = c.parse_vector_input(tint_socket) rough_socket = node.inputs.get('Roughness') if rough_socket is not None: state.out_roughness = c.parse_value_input(rough_socket) model = getattr(node, 'model', 'CHIANG') if model == 'CHIANG': radial_rough_socket = node.inputs.get('Radial Roughness') if radial_rough_socket is not None: state.out_aniso_rot = c.parse_value_input(radial_rough_socket) coat_socket = node.inputs.get('Coat') if coat_socket is not None: state.out_clearcoat = c.parse_value_input(coat_socket) random_color_socket = node.inputs.get('Random Color') if random_color_socket is not None: state.out_sheen = c.parse_value_input(random_color_socket) random_rough_socket = node.inputs.get('Random Roughness') if random_rough_socket is not None: state.out_sheen_rough = c.parse_value_input(random_rough_socket) offset_socket = node.inputs.get('Offset') if offset_socket is not None: state.out_anisotropy = c.parse_value_input(offset_socket) state.out_specular = '0.0' state.out_metallic = '0.0' if state.parse_opacity: ior_socket = node.inputs.get('IOR') if ior_socket is not None: state.out_ior = c.parse_value_input(ior_socket) state.out_opacity = '1.0' def parse_holdout(node: bpy.types.ShaderNodeHoldout, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: # Occlude state.out_occlusion = '0.0' def parse_bsdfrefraction(node: bpy.types.ShaderNodeBsdfRefraction, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: state.out_basecol = c.parse_vector_input(node.inputs['Color']) c.write_normal(node.inputs['Normal']) state.out_roughness = c.parse_value_input(node.inputs['Roughness']) if state.parse_opacity: state.out_opacity = '1.0' state.out_ior = c.parse_value_input(node.inputs['IOR']) def parse_subsurfacescattering(node: bpy.types.ShaderNodeSubsurfaceScattering, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: c.write_normal(node.inputs['Normal']) state.out_basecol = c.parse_vector_input(node.inputs['Color']) state.out_subsurface = c.parse_value_input(node.inputs['Scale']) state.out_subsurface_radius = c.parse_vector_input(node.inputs['Radius']) state.out_subsurface_color = c.parse_vector_input(node.inputs['Color']) state.out_specular = '0.0' def parse_bsdftoon(node: bpy.types.ShaderNodeBsdfToon, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: c.write_normal(node.inputs['Normal']) state.out_basecol = c.parse_vector_input(node.inputs['Color']) state.out_roughness = c.parse_value_input(node.inputs['Size']) state.out_specular = '0.0' def parse_bsdftranslucent(node: bpy.types.ShaderNodeBsdfTranslucent, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: c.write_normal(node.inputs['Normal']) if state.parse_opacity: state.out_opacity = '(1.0 - {0}.r)'.format(c.parse_vector_input(node.inputs['Color'])) state.out_ior = '1.0' def parse_bsdftransparent(node: bpy.types.ShaderNodeBsdfTransparent, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_opacity: state.out_opacity = '(1.0 - {0}.r)'.format(c.parse_vector_input(node.inputs['Color'])) state.out_ior = '1.0' if bpy.app.version < (4, 0, 0): def parse_bsdfvelvet(node: bpy.types.ShaderNodeBsdfVelvet, out_socket: NodeSocket, state: ParserState) -> None: if state.parse_surface: c.write_normal(node.inputs['Normal']) state.out_basecol = c.parse_vector_input(node.inputs['Color']) state.out_roughness = '1.0' state.out_metallic = '1.0'