Created
May 22, 2026 02:41
-
-
Save yunho-c/18e1324c4be9ef0f3c23190a2fb38b3c to your computer and use it in GitHub Desktop.
Blender: create toon shader
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import bpy | |
| def create_toon_shader(): | |
| mat_name = "Toon_3_Tone" | |
| # Create a new material and enable use of nodes | |
| mat = bpy.data.materials.new(name=mat_name) | |
| mat.use_nodes = True | |
| # Get the node tree | |
| nodes = mat.node_tree.nodes | |
| links = mat.node_tree.links | |
| # Clear out the default Principled BSDF node setup | |
| nodes.clear() | |
| # --- Create Nodes --- | |
| # 1. Diffuse BSDF | |
| node_diffuse = nodes.new(type='ShaderNodeBsdfDiffuse') | |
| node_diffuse.location = (-400, 0) | |
| # 2. Shader to RGB | |
| # Note: This node only functions in Eevee | |
| node_shader2rgb = nodes.new(type='ShaderNodeShaderToRGB') | |
| node_shader2rgb.location = (-200, 0) | |
| # 3. ColorRamp | |
| node_ramp = nodes.new(type='ShaderNodeValToRGB') | |
| node_ramp.location = (0, 0) | |
| # Set interpolation to 'CONSTANT' to crush the gradients into flat colors | |
| node_ramp.color_ramp.interpolation = 'CONSTANT' | |
| # 4. Material Output | |
| node_output = nodes.new(type='ShaderNodeOutputMaterial') | |
| node_output.location = (300, 0) | |
| # --- Configure ColorRamp (3 Tones) --- | |
| ramp = node_ramp.color_ramp | |
| # A ColorRamp comes with 2 elements by default. Add a 3rd for the mid-tone. | |
| ramp.elements.new(position=0.5) | |
| # Set the threshold positions for where the light cuts off | |
| ramp.elements[0].position = 0.00 # Shadow | |
| ramp.elements[1].position = 0.25 # Mid-tone | |
| ramp.elements[2].position = 0.65 # Highlight | |
| # Set the colors (RGBA format). Currently set to a technical blue/grey. | |
| ramp.elements[0].color = (0.2, 0.25, 0.3, 1.0) # Dark Shadow | |
| ramp.elements[1].color = (0.4, 0.5, 0.6, 1.0) # Mid-tone | |
| ramp.elements[2].color = (0.7, 0.8, 0.9, 1.0) # Bright Highlight | |
| # --- Link the Nodes --- | |
| links.new(node_diffuse.outputs['BSDF'], node_shader2rgb.inputs['Shader']) | |
| links.new(node_shader2rgb.outputs['Color'], node_ramp.inputs['Fac']) | |
| links.new(node_ramp.outputs['Color'], node_output.inputs['Surface']) | |
| # --- Assign to Active Object --- | |
| obj = bpy.context.active_object | |
| if obj and obj.type == 'MESH': | |
| # If the object already has materials, replace the first one, otherwise append | |
| if len(obj.data.materials) > 0: | |
| obj.data.materials[0] = mat | |
| else: | |
| obj.data.materials.append(mat) | |
| print(f"Success: Assigned '{mat_name}' to {obj.name}") | |
| else: | |
| print(f"Notice: Created material '{mat_name}', but no valid active mesh object was selected.") | |
| # Execute the function | |
| create_toon_shader() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment