About blender-texture-baking
A Blender Cycles texture-baking skill for artists creating texture maps from high- and low-poly assets or procedural materials. Its script handles map setup, image color spaces, temporary nodes, and GPU selection with CPU fallback.
Key features
- 01Bake maps from high- and low-poly meshes
- 02Bake procedural materials into textures
- 03Generate normal, AO, curvature, and ID maps
- 04Configure ray extrusion or a cage
- 05Select GPU with CPU fallback
Use cases
- 01Bake game-ready maps for low-poly meshes
- 02Create ORM texture packs
- 03Generate lightmaps on a second UV layer
- 04Diagnose projection artifacts and seams
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ el4cteo/ blender-skills --skill blender-texture-bakingAfter installing, type/blender-texture-bakingin Claude Code to confirm it loaded.
Bundled filesscripts/_bpyx.pyscripts/bake_maps.py
Details
From the project READMETexture Baking (Cycles)
The execution model is in blender-core. UVs come from blender-retopology-uv and materials from blender-pbr-materials.
One call
scripts/bake_maps.py -- --low SM_Crate --high Crate_high Crate_bolts --maps normal ao curvature id \
--res 2048 --samples 64 --margin-px 16 --pack-orm --out //textures
Self-bake (procedural → textures, no --high): --low SM_Crate --maps basecolor roughness metallic normal --pack-orm.
The script picks the GPU (OptiX/CUDA/HIP/Metal/oneAPI) and falls back to CPU, creates the target images with correct color spaces, cleans up its temporary nodes, and saves T_<name>_<N|AO|CURV|BC|R|M|ORM...>.png.
Preparation checklist (most bake bugs come from this list)
- Low poly: UVs unwrapped, no overlaps (stacked/mirrored islands moved +1 U), padding ≥ 8 px at the bake resolution, scale applied.
- Hard edges = UV seams on the low poly. Use either smooth shading with the bake handling gradients, or hard edges split at seams. Never put a hard edge inside a UV island.
- Triangulate the low poly the same way the engine will, or export the triangulated mesh. Mismatched triangulation shows as shading seams.
- High poly covers the low completely and pokes out of it only a little. Floaters (bolts, panel details) can hover just above the surface, but must stay within the extrusion distance.
- Names:
X_low/X_highpairs. Bake per part, or explode the parts apart (move each pair along an axis) so neighbouring parts don't project onto each other, then put them back. - Apply modifiers on the high poly as needed (multires and subd are evaluated automatically).
Rays: extrusion vs cage
--extrusion(meters) pushes the ray origin outward from the low surface. It must be greater than the farthest distance the high poly sticks out of the low. The default is 2% of the low's diagonal;max_ray_distanceis 2 × extrusion.- Cage (
--cage Crate_cage): a copy of the low with the same topology, inflated (Displace/"Push"). Use it when uniform extrusion fails (sharp concave corners, thin parts). Edit the cage locally where rays miss. - Too small: holes or missing details. Too large: other parts of the mesh project in (intersections, "ghosting").
Map guide
| Map | Space | Notes |
|---|---|---|
| normal | Non-Color, tangent, OpenGL (--directx for Unreal) | 16-sample AA is plenty; 8-bit PNG is fine for games |
| ao | Non-Color | 64–256 samples; bake with the high only (no ground) unless contact AO is wanted |
| curvature | Non-Color, 0.5 = flat | derived from the baked normal (convex white / concave dark); drives edge wear |
| id | sRGB | one flat color per high-poly material; use materials as masks |
| thickness | Non-Color | AO with inside rays; dark = thin; for SSS/translucency masks |
| basecolor/metallic/opacity | via emission override | reads the Principled inputs of the source materials (also procedural chains) |
| roughness, emit, combined | native Cycles passes | combined = lit result (lightmaps, stylized) |
| position | float | gradient masks |
ORM = R:AO G:Roughness B:Metallic, the glTF/Unreal standard. Unity uses a different packing (blender-pbr-materials). |
Fixing common artifacts
| Symptom | Cause | Fix |
|---|---|---|
| Wavy lines on cylinders | low poly too low, smoothing gradients | add segments, use a cage, or more support on the low |
| Skewed details (bolts lean) | ray direction follows the averaged low normals | hard edges + seams, a cage, or bake the floater separately |
| Black/garbage areas | rays miss or hit the back faces | raise extrusion, fix flipped normals (blender-asset-qa), check high coverage |
| Seams visible in engine | margin too small, hard edge without a seam, different tangents | margin ≥ 16 px @2k, seams at hard edges, export tangents (MikkTSpace) |
| Details from a neighbouring part | parts too close | explode the bake, or bake per object pair |
| Inverted green look in engine | OpenGL/DirectX mismatch | --directx for Unreal, or flip G in the texture importer |
| Stepping/banding | 8-bit with large flat gradients | bake to 16-bit (float_buffer) and dither on export |
Baking non-PBR data
- Vertex colors:
bake.target = "VERTEX_COLORS"with an active color attribute (useful for mobile and Roblox-free shading). - Lightmaps: bake
combinedonto UV2 (--uv-layer UVMap_Lightmap) with the scene lights. - Multires (no separate high object):
bake.use_multires=True,bake.type="NORMALS"|"DISPLACEMENT"|"VECTOR_DISPLACEMENT",bake.use_lores_mesh=True, thenbpy.ops.object.bake_image(). The viewport level is the low, the sculpt level is the high.
Gotchas
- The target image must be the active Image Texture node in every material of the low object (the script handles this).
- Baking in Cycles uses the active UV map (
--uv-layerto pick). - Images aren't saved automatically:
img.save()orsave_render. Packed or internal images disappear on reload. - 5.2: the Cycles texture cache (
.tx) is for render memory and doesn't affect bake results. - Run
blender-asset-qaon low + high first, because flipped normals and floating chunks produce most bake garbage.