Utility_Apps/Blender/simple scripts/Export Shader Nodes/README.md
2026-04-01 15:39:57 -05:00

162 lines
5.2 KiB
Markdown

# 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`, and `os`
---
## Quick Start
1. Open your `.blend` file and select the object whose material you want to export.
2. In Blender, go to the **Text Editor** (you can split any panel and switch it to Text Editor).
3. Click **New** to create a new text block, then paste in `export_shader_nodes.py`.
4. Click **Run Script** (or press `Alt + P`).
5. The JSON file is saved automatically next to your `.blend` file, 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:
```python
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:
```json
{
"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:
```json
{
"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:
```json
{
"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](https://docs.blender.org/api/current/).
---
## 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:
```python
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.