# Blender Tools Small tools for moving textured assets between Blender and Substance Painter. ```text blender/ material_id_baker/ Blender 5.x extension source scripts/ Build, install/update, and test helpers tests/ Headless Blender smoke test tools/ combine_substance_textures.py requirements.txt tests/ dist/ Built extension packages (generated) ``` Build every Blender extension in the repository at once with: ```bash ./build-all.sh ``` Set `BLENDER_BIN=/path/to/blender` when Blender is not available as `blender`. ## Material ID Baker extension The Blender extension bakes the active mesh's material-slot assignments to a flat-color texture using its active UV map. It works on a temporary mesh copy, so the source mesh and materials are not modified. Features include 256px–8K output, configurable island margin, optional evaluated modifiers, and three palette modes: deterministic distinct colors, material viewport colors, and exact slot-index encoding. It can write a PNG plus a JSON legend used by the standalone merger. ### Install or update Close Blender, set `BLENDER_BIN` if Blender 5.2 is not available as `blender`, and run: ```bash BLENDER_BIN=/path/to/blender-5.2 ./blender/scripts/install.sh ``` This builds `dist/material_id_baker-.zip` and installs or reinstalls the stable `material_id_baker` extension ID in Blender's `user_default` repository. For a release, bump `version` in `blender/material_id_baker/blender_manifest.toml` first. You can instead run `./blender/scripts/build.sh` and install the resulting ZIP through **Edit > Preferences > Extensions > Install from Disk**. ### Bake an ID map 1. Select one mesh in Object Mode. 2. Ensure it has an active UV map and the intended per-face material assignments. 3. Open the 3D Viewport sidebar and choose the **Material ID** tab. 4. Select the resolution, margin, and color mode. 5. Enable **Save PNG** and **Save JSON Legend**, then click **Bake Material ID**. Overlapping UV islands with different materials are ambiguous. Use a non-overlapping UV layout for recovery/compositing. ## Combine separate Substance Painter texture sets Use [tools/combine_substance_textures.py](tools/combine_substance_textures.py) when an asset was imported into Substance with one texture set per Blender material and now needs one texture per channel. Ordinary alpha compositing is unreliable here because Substance exports may have opaque backgrounds and padding. The merger uses the Material ID PNG and JSON legend as exact masks, so padding in each separate texture set cannot overwrite another material. Install its one dependency in your preferred Python environment: ```bash python3 -m venv .venv .venv/bin/pip install -r tools/requirements.txt ``` Then run: ```bash .venv/bin/python tools/combine_substance_textures.py \ --id-map recovery/Material_ID.png \ --legend recovery/Material_ID.json \ --input-dir substance-export \ --output-dir combined ``` Suppose the legend contains materials named `Body` and `Trim`, and Substance exported: ```text Robot_Body_BaseColor.png Robot_Trim_BaseColor.png Robot_Body_Normal.png Robot_Trim_Normal.png ``` The tool discovers the material token and writes: ```text combined/Robot_BaseColor.png combined/Robot_Normal.png ``` The ID map and exported textures must have the same dimensions. The merger first uses exact ID bytes, with an automatic one-byte fallback only when a material's exact color is absent (this handles Blender's float-to-PNG rounding). `--tolerance 0` forces strict matching; larger explicit tolerances are available for external ID maps, but the tool rejects values that make material masks overlap. If a Substance texture-set token differs from its Blender material name, add aliases: ```bash .venv/bin/python tools/combine_substance_textures.py \ --id-map recovery/Material_ID.png \ --legend recovery/Material_ID.json \ --input-dir substance-export \ --output-dir combined \ --material-alias 'Body Material=Body' \ --material-alias 'Trim Material=Trim' ``` Useful options: - `--dry-run` shows discovered channel groups without writing images. - `--recursive` searches subdirectories and can group layouts such as `Body/BaseColor.png` plus `Trim/BaseColor.png`; shared directory prefixes are preserved. - `--overwrite` replaces existing combined textures. - `--material-alias 'LEGEND NAME=FILENAME NAME'` may be repeated. The merger supports common Pillow-readable image types including PNG, TGA, TIFF, and JPEG. Prefer lossless 8-bit PNG/TGA exports for data maps; JPEG compression can alter texture values. ## Tests Run the extension bake test with Blender: ```bash ./blender/scripts/test.sh ``` Run the standalone merger tests after installing Pillow: ```bash ./tools/test.sh ```