| .. | ||
| export_shader_nodes.py | ||
| README.md | ||
Blender Shader Node Exporter
Exports the active object's material shader node tree to a readable JSON file. Useful for documenting materials, diffing shader changes, or feeding node data into external tools.
Requirements
- Blender 4.0 or later (tested on 4.5)
- No additional Python packages — uses only Blender's built-in
bpy,json, andos
Quick Start
- Open your
.blendfile and select the object whose material you want to export. - In Blender, go to the Text Editor (you can split any panel and switch it to Text Editor).
- Click New to create a new text block, then paste in
export_shader_nodes.py. - Click Run Script (or press
Alt + P). - The JSON file is saved automatically next to your
.blendfile, named<MaterialName>_shader.json.
Check the System Console (Window → Toggle System Console on Windows) for a confirmation message and node/link counts.
Configuration
At the top of the script there are two settings you can change:
EXPORT_PATH = None # Set a custom output path, e.g. r"C:\Users\You\my_shader.json"
MATERIAL_INDEX = 0 # Which material slot to export (0 = first slot)
EXPORT_PATH — leave as None to auto-save next to the .blend file. If the .blend hasn't been saved yet, the file goes to your home directory (~/).
MATERIAL_INDEX — if your object has multiple material slots, set this to the slot number you want (0-indexed). For example, 1 exports the second material.
Output format
The JSON has this structure:
{
"material_name": "MyMaterial",
"blend_method": "OPAQUE",
"shadow_method": "OPAQUE",
"use_backface_culling": false,
"node_tree": {
"name": "MyMaterial",
"type": "SHADER",
"nodes": [ ... ],
"links": [ ... ]
}
}
Nodes
Each entry in nodes looks like:
{
"name": "Principled BSDF",
"label": "",
"type": "BSDF_PRINCIPLED",
"bl_idname": "ShaderNodeBsdfPrincipled",
"location": [-200.0, 300.0],
"width": 240.0,
"height": 100.0,
"hide": false,
"mute": false,
"use_custom_color": false,
"color": [0.6, 0.6, 0.6],
"inputs": [
{
"name": "Base Color",
"identifier": "Base Color",
"type": "RGBA",
"is_linked": true,
"default_value": [0.8, 0.8, 0.8, 1.0]
}
],
"outputs": [ ... ],
"properties": {
"distribution": "MULTI_GGX",
"subsurface_method": "RANDOM_WALK"
}
}
Links
Each entry in links describes one connection between nodes:
{
"from_node": "Image Texture",
"from_socket": "Color",
"to_node": "Principled BSDF",
"to_socket": "Base Color",
"is_muted": false
}
What gets exported per node type
| Node | Extra properties captured |
|---|---|
| Principled BSDF | distribution, subsurface_method |
| Image Texture | interpolation, projection, extension, image_name, image_filepath |
| Noise Texture | noise_dimensions |
| Wave Texture | wave_type, bands_direction, rings_direction, wave_profile |
| Voronoi Texture | voronoi_dimensions, feature, distance |
| Mapping | vector_type |
| Math | operation, use_clamp |
| Vector Math | operation |
| Mix / MixRGB | blend_type, use_clamp / data_type, clamp_factor, clamp_result, factor_mode |
| Bump | invert |
| Normal Map | space, uv_map |
| Displacement | space |
| Value | value (the output number) |
| RGB | color (the output color as RGBA list) |
| Group | node_tree (the name of the node group) |
| Script | mode, script, filepath |
| All others | Sockets + default values only |
Note: Image pixel data is not exported — only the image name and its filepath as stored in Blender.
Troubleshooting
No active object selected — click on your object in the viewport before running the script. Make sure it's highlighted orange, not just in the scene.
Object has no material slots — the selected object has no material assigned. Add one in the Properties panel → Material tab.
Material slot N is out of range — you set MATERIAL_INDEX higher than the number of slots the object has. Slot numbering starts at 0.
Material does not use nodes — the material has node editing disabled. In the Material Properties panel, enable Use Nodes.
Permission error on the output file — Blender doesn't have write access to the target directory. Either set EXPORT_PATH to a folder you own (e.g. your Desktop), or run Blender as an administrator (Windows).
The JSON only has generic socket data for a node type I care about — the script has an explicit allowlist of properties per node type. You can add your node's bl_idname and the property attribute names to the prop_names dict near the top of export_node(). All available attributes are listed in the Blender Python API docs.
Exporting multiple materials
The script exports one material at a time. To batch-export all materials on an object, you can wrap the main() call in a loop:
for i in range(len(bpy.context.active_object.material_slots)):
MATERIAL_INDEX = i
main()
Paste this at the bottom of the script in place of the final main() call.