import bpy
# ============================================================
# GLOWING EDGE - TOP EDGE MATERIAL
# Brightens ONLY upward-facing bevel / top edges
# Blender 4.x / 5.x
# ============================================================
MAT_NAME = "Glowing Edge"
obj = bpy.context.active_object
if obj is None:
raise RuntimeError("choose the object first : @rtxid")
# ------------------------------------------------------------
# MATERIAL
# ------------------------------------------------------------
mat = bpy.data.materials.get(MAT_NAME)
if mat is None:
mat = bpy.data.materials.new(MAT_NAME)
mat.use_nodes = True
nodes = mat.node_tree.nodes
links = mat.node_tree.links
nodes.clear()
# ============================================================
# OUTPUT
# ============================================================
output = nodes.new("ShaderNodeOutputMaterial")
output.location = (900, 0)
bsdf = nodes.new("ShaderNodeBsdfPrincipled")
bsdf.location = (620, 0)
links.new(bsdf.outputs["BSDF"], output.inputs["Surface"])
# Metallic text
bsdf.inputs["Metallic"].default_value = 1.0
bsdf.inputs["Roughness"].default_value = 0.24
# ============================================================
# BASE COLOR
# ============================================================
base_color = nodes.new("ShaderNodeRGB")
base_color.label = "BASE SILVER"
base_color.location = (-100, 180)
base_color.outputs[0].default_value = (
0.72,
0.72,
0.74,
1.0
)
# HOT TOP COLOR
hot_color = nodes.new("ShaderNodeRGB")
hot_color.label = "HOT TOP EDGE"
hot_color.location = (-100, 300)
hot_color.outputs[0].default_value = (
1.0,
0.97,
0.88,
1.0
)
# ============================================================
# DETECT UPWARD-FACING NORMAL
# ============================================================
geometry = nodes.new("ShaderNodeNewGeometry")
geometry.label = "SURFACE NORMAL"
geometry.location = (-900, 400)
transform = nodes.new("ShaderNodeVectorTransform")
transform.label = "WORLD → OBJECT"
transform.location = (-680, 400)
transform.vector_type = 'NORMAL'
transform.convert_from = 'WORLD'
transform.convert_to = 'OBJECT'
separate = nodes.new("ShaderNodeSeparateXYZ")
separate.label = "LOCAL XYZ"
separate.location = (-470, 400)
links.new(
geometry.outputs["Normal"],
transform.inputs["Vector"]
)
links.new(
transform.outputs["Vector"],
separate.inputs["Vector"]
)
# ============================================================
# TOP EDGE MASK
# ============================================================
ramp = nodes.new("ShaderNodeValToRGB")
ramp.label = "TOP EDGE WIDTH"
ramp.location = (-250, 430)
cr = ramp.color_ramp
# Surfaces not facing upward = black
cr.elements[0].position = 0.20
cr.elements[0].color = (0, 0, 0, 1)
# Strong upward-facing surfaces = white
cr.elements[1].position = 0.72
cr.elements[1].color = (1, 1, 1, 1)
cr.interpolation = 'EASE'
# IMPORTANT:
# Default Blender text:
# X = horizontal
# Y = vertical
# Z = extrusion/depth
#
# Therefore LOCAL +Y detects the TOP of letters.
links.new(
separate.outputs["Y"],
ramp.inputs["Fac"]
)
# ============================================================
# MIX BASE + HOT EDGE
# ============================================================
mix = nodes.new("ShaderNodeMixRGB")
mix.label = "TOP EDGE BRIGHTNESS"
mix.blend_type = 'MIX'
mix.location = (180, 220)
links.new(ramp.outputs["Color"], mix.inputs[0])
links.new(base_color.outputs["Color"], mix.inputs[1])
links.new(hot_color.outputs["Color"], mix.inputs[2])
links.new(
mix.outputs["Color"],
bsdf.inputs["Base Color"]
)
# ============================================================
# SMALL EMISSION FOR AE GLOW SOURCE
# ============================================================
if "Emission Color" in bsdf.inputs:
links.new(
mix.outputs["Color"],
bsdf.inputs["Emission Color"]
)
if "Emission Strength" in bsdf.inputs:
bsdf.inputs["Emission Strength"].default_value = 0.25
# ============================================================
# MICRO SURFACE
# ============================================================
texcoord = nodes.new("ShaderNodeTexCoord")
texcoord.location = (-850, -180)
noise = nodes.new("ShaderNodeTexNoise")
noise.location = (-600, -180)
noise.noise_dimensions = '3D'
noise.inputs["Scale"].default_value = 220.0
noise.inputs["Detail"].default_value = 2.0
noise.inputs["Roughness"].default_value = 0.5
bump = nodes.new("ShaderNodeBump")
bump.location = (330, -170)
bump.inputs["Strength"].default_value = 0.020
bump.inputs["Distance"].default_value = 0.006
links.new(texcoord.outputs["Generated"], noise.inputs["Vector"])
links.new(noise.outputs["Fac"], bump.inputs["Height"])
links.new(bump.outputs["Normal"], bsdf.inputs["Normal"])
# ============================================================
# ASSIGN MATERIAL
# ============================================================
if len(obj.data.materials) == 0:
obj.data.materials.append(mat)
else:
obj.data.materials[0] = mat
print(
f"'{MAT_NAME}' has made for object '{obj.name}'. "
"Top-facing bevel now are more glowing."
)

0 Komentar