关于 scenario-blender-uv-baking
面向 Blender 美术创作者,涵盖 UV 展开与贴图烘焙,并通过脚本测量各阶段的质量。工作流强调按纹理方法规划缝线、控制纹素密度和像素级留边。
主要功能
- 01按纹理方式规划缝线
- 02测量并规范纹素密度
- 03展开、整理与打包 UV
- 04测量投射距离并自适应烘焙
- 05检查 UV 与烘焙结果
适用场景
- 01为游戏模型制作 UV 与烘焙贴图
- 02检查 UV 岛的重叠和留边
- 03为高模到低模烘焙法线与 AO
- 04定位烘焙中的反转像素问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-blender-uv-baking安装后在 Claude Code 中输入/scenario-blender-uv-baking确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/critique.mdexpert-notes.mdprocedures.mdsources.mdscripts/bx_uvbake.py详细介绍
UV 展开与烘焙
专家级 UV 会根据纹理绘制方法选择可容忍接缝的位置,在确定纹理尺寸之前先设定纹素密度,并按像素精确设置填充。专家级烘焙会测量投射距离,而不是凭猜测,并以像素和斜射光下的效果进行评判,绝不只凭肉眼看一眼。下文每个阶段都有可测量的门槛,由 scripts/bx_uvbake.py 计算。如果此处提到的同伴技能不在你可用的技能中,请让用户安装它(npx skills add scenario-labs/skills --skill <name>);在无人值守的情况下,根据工具架构继续操作并标明这一缺口。
必备背景: scenario-blender-expert(执行渠道、审查循环、5.2 API 变更)。
立场(专家之道)
- 接缝要配合纹理绘制方法。 Kaspar(2021,2D 绘制):接缝越少越好,并藏在头发、衣物和四肢内侧。Blender Studio 指南(2024,同一作者):在 3D 中绘制或进行烘焙时,接缝宁多勿少,因为拉伸的代价更大。游戏烘焙还有一条硬性规则:每条硬边都必须是接缝,否则法线贴图会开裂(Lampel、Gambrell、On Mars 3D、Polycount)。
- 只有封闭壳体和长管状物需要额外切缝。 Morren:任何首尾相连闭合的物体都需要一道切缝。Gambrell:每个胶带纸环都要切开一次,并藏起来。但带孔的岛(有眼洞的面、垫圈)可以很好地展平。
cut_to_disks会先测试展开,仅在发生拉伸时才切缝[新增;全部切开会使羊的大岛发生折叠]。 - 展开方法是一种测量方式,且 5.2 默认采用 CONFORMAL。 务必传入
method=。在 Suzanne 上,Minimum Stretch 的密度最均匀(离散度 1.38),Angle Based 的角度最佳,而 Conformal 的面积表现不佳(5.89)。在平坦的硬表面岛上,三种方法的结果都会趋同。unwrap(method="BEST")会按岛选择方法,并拒绝发生自身折叠的岛。 - 先确定密度,再确定纹理尺寸(Huge Menace)。目标值:FPS 10.24 px/cm,武器 20.48,第三人称 5.12,俯视视角 2.56。优先级由镜头决定:提高脸部、手部和正面的密度;降低鞋底、口腔内侧和背面的密度(SpeedChar、Kaspar)。通过缩小密度较高的纹理集来匹配纹理集,绝不要放大另一个纹理集(Gambrell)。
- 先拉直,再均衡,最后不旋转地打包(Lampel):从真正呈矩形的四边面开始使用 Follow Active Quads,固定该面,重新展开其余部分,再用 CARDINAL 打包。填充以像素数表示,为 res/128(2K 时为 16 px),作为 FRACTION 边距传入,margin = gap/(2*res)。
- 测量投射距离,绝不猜测挤出值,也不要依赖单一全局值。 Ryan King 的 0.01 和后来的 0.02 是针对特定场景的。SpeedChar 手动测试了六个值,而修好脸部的值却破坏了腋窝(“我们在某处修好问题时,其他地方就会出现一些问题”,E6QMhGuhyoc [00:26:23])。射线从低模表面发出,
max_ray_distance从挤出后的起点开始计算。自适应烘焙会为每个纹素保留能命中正面的最小挤出值。在羊模型上,它将反转纹素从 7.5% 降至 1.2%[已验证]。 - 烘焙光照有差异的地方都要使用独立 UV(SpeedChar:AO 残影意味着纹素被共享)。烘焙前,将堆叠或镜像的副本恰好移出 0-1 一个图块(Polycount),因为在 0-1 范围内,最后烘焙的岛会覆盖之前的结果。
- 烘焙要以像素和光照下的效果来评判。 蓝色 < 0.5 表示射线命中了远侧。完全平坦表示射线未命中。AO 全白表示距离太短。改变挤出值后位置不变的反转像素,说明问题出在几何体,而非设置[已在羊模型上验证]。Multires 烘焙不会投射射线:在相同表面上,反转纹素占比为 0.09%。
首先确定
| 输入 | 影响 | 简述未说明时的默认值 |
|---|---|---|
| 目标 | 接缝、对称性、UDIM 与贴图集的取舍、三角化 | 游戏引擎,每种材质使用一个 0-1 贴图集 |
| 纹理绘制方法 | 接缝数量和可见性 | 3D 绘制/Substance:接缝可以位于背面 |
| 摄像机 | 密度和优先级 | 第三人称,512 px/m,以最近视角决定纹理图块 |
| 纹理预算 | 分辨率、贴图集数量、UDIM 数量 | 每个贴图集 2048;由 texture_size_for 决定 |
| 变形 | 接缝避开关节、切线空间法线 | 角色:切线空间、唯一 UV |
| 高模源文件 | Selected to Active 与 Multires 的选择 | 独立雕刻模型:Selected to Active |
| 引擎约定 | 法线绿色通道 | OpenGL(Blender、Unity、glTF);Unreal 使用 directx=True |
工作流
- 飞行前检查。 应用缩放(On Mars 3D 表示,这能“解决绝大多数”问题)。清理非流形几何体、重叠顶点和背面(SpeedChar)。决定是否使用 Mirror 和 Solidify 修改器。如果已有 UV,请将
island_topology与uv_qa的岛屿进行比较:文件中的缝线标记往往是重拓扑时遗留的标记,因此在重新展开 UV 之前,先运行seams_from_uv_islands(Lampel)。 GATE:缩放为 1,bx_audit检查通过,并已查看拓扑表。 - 缝线。 硬表面:
seams_from_sharp(obj, 30, mark_sharp=True)。有机模型:构建部位标签(头部、耳朵、四肢、躯干正面和背面、脚底、口腔内侧和眼睑;参见references/expert-notes.md中 Kaspar 和 Morren 的缝线图),然后运行seams_from_groups(obj, labels)。特定切口:seam_path(obj, v_a, v_b, view_dirs)。然后运行cut_to_disks(obj, view_dirs=[camera])。 GATE:must_cut为空;检查器渲染结果显示重点区域没有无法接受的缝线。 - 展开 UV。 运行
unwrap(obj, method="BEST"),或根据岛屿类型选择合适的方法。 GATE:unsolved_faces为 0(即使操作失败,操作器也会返回 FINISHED),folding_islands为空(否则运行seams_from_groups(..., faces=folding_faces)后再次展开),角度 p95 不超过 15 到 20 度。 - 拉直网格状岛屿(硬表面、服装、发束):在进行任何缩放之前运行
straighten(obj)。 GATE:检查器中的条纹保持笔直。 - 纹素密度。 运行
normalize_texel_density(obj, target, res, weights),然后运行texture_size_for(obj, target)。 GATE:岛屿间的差异在 10-20% 以内,或符合预期的优先级比例。 - 打包。 运行
pack(obj, tex_res=res);严格保持密度时使用scale=False,有机岛屿使用allow_any=True。UDIM:逐个区域打包,然后运行move_to_tile。 GATE:uv_qa检查结果为重叠数 0、间距至少为 res/128、边距至少为间距的一半、覆盖率至少为 0.70;如有例外,须说明原因。 - 查看效果。 使用
uv_layout_image、checker_review、distortion_review(metric="angle")。根据references/critique.md进行评估。 - 烘焙准备。 运行
prepare_low(low, triangulate=game, sharp_from_uv_islands=hard_surface)。将低模与高模的轮廓进行比较(bx_audit.audit(low, high=...))。将互相穿插或会移动的部件分离(explode,沿一个轴)。运行measure_projection:miss_pct低于 2,wrong_part_pct低于 1;否则使用笼子、分离部件,或按部件对进行烘焙。 - 烘焙。 先运行
bake_high_to_low(low, highs, out, res=512),然后再使用最终分辨率。默认采用自适应挤出,并隐藏其他所有对象的渲染。多重分辨率:bake_multires。附加贴图:bake_id、curvature_from_normal。 GATE:sanity[...]["problems"]为空(反转纹素低于 2%;从 0.2% 起记录提示),输出 16-bit PNG。如果仍有反转纹素,运行map_problem_review查看位置。如果sweep_projection显示这些问题不会随挤出而移动,应修复几何体(贴合度、孔洞、薄部件),而不是调整数值。 - 检查并连接贴图。 运行
bake_review(low, highs, paths, out):在掠射光下,带贴图的低模应呈现出与高模相似的效果。然后运行hookup_maps。报告测量结果,并说明哪些内容未经验证。
数值
| 数值 | 相对于 | 来源 |
|---|---|---|
| 10.24 / 20.48 / 5.12 / 2.56 px/cm | FPS 世界 / FPS 武器 / 第三人称 / 俯视 | Huge Menace [00:12:28] |
| 密度差异为 10-20% 时不可见 | 岛屿或集合之间 | Gambrell [01:36:16] |
| 覆盖率高于 70%,工作室最低要求为 75% | 一个 0-1 贴图块 | Gambrell [01:31:56], Huge Menace [00:16:27] |
| 岛屿间距为分辨率/128(1K/2K/4K 时分别为 8/16/32 px) | 纹理分辨率 | Lampel [00:38:01], On Mars 3D [00:11:18] |
| FRACTION 边距 m:间距为 2m,边框为 m | Blender 打包 | 已验证 |
| 烘焙边距为分辨率/128,2K 时为 16 px | 纹理分辨率 | On Mars 3D,摘要 |
| 圆柱侧面数:最低 6,推荐 8 | 低多边形轮廓 | On Mars 3D [00:03:48] |
| 采样数:法线为 16,AO 为 128,仅在迭代时为 1 | 抗锯齿与噪点 | Gambrell/Marmoset 16,SpeedChar 4x4,已验证 |
| 测试烘焙 512,最终 2048 | 迭代流程 | SpeedChar [00:59:09] |
| AO 距离约为包围盒对角线的 0.2 倍(默认 10 个单位) | 资源尺寸 | [已添加],效果已验证 |
| 每个角的角度误差 p95 不超过有机模型 15 度、平面 3 度 | 每个角 | 根据 5.2.1 的测量结果[已添加] |
| Blender 打包器处理有机角色:55-62% | 2K 时间距为 16 px | 在绵羊模型上测量(多次运行) |
| 反转纹素:单次处理为 7.3-7.8%,自适应处理为 2.2%(雕刻模型)/ 1.2%(一致的高质量模型) | 选中到活动对象,绵羊 | 已测量 |
| 2048 烘焙,186k 面高模:一次法线 + AO 耗时 4.4 s,自适应处理耗时 25 s | Metal GPU,无头模式 | 已测量 |
质量门槛
代码:q = uv_qa(obj, res),然后执行 uv_verdict(q, "game" or "film", priorities=...)。
unwrap()["unsolved_faces"] 和 ["folding_islands"]。measure_projection()。
bake_high_to_low()["sanity"](反转、精确平面、非单位值、AO 黑白检查)。如有疑问,使用
bpy.ops.uv.select_overlap() 交叉检查重叠;在测试中,结果与光栅化检查一致。
视觉检查:布局 PNG(岛屿、洋红色重叠部分)、从正面、侧面、四分之三视角和制作摄像机检查颜色网格
(方块保持正方形、字母保持正向、接缝隐藏)、角度和密度热力图、bake_review 表(高模、低模、低模 + 贴图),以及在健全性检查标记像素时使用的 map_problem_review。
常见错误
| 错误 | 表现 | 修正 |
|---|---|---|
不带 method 使用 uv.unwrap() | 产生共形面积扭曲 | 传入 method=,或使用 unwrap(method="BEST") |
| 相信 FINISHED | 闭合岛仍保留旧 UV,且已重新打包 | 先将 UV 归零,检查是否有零面积面(unwrap() 会执行此操作) |
| 重新展开时未从岛生成 Seams | 布局丢失;重拓扑标记被当作接缝 | 先运行 seams_from_uv_islands |
| 将每个岛都切成圆盘 | 出现裂缝、折叠的岛 | 使用测量得出的 cut_to_disks(默认值) |
| 拉直后使用 ANY 打包旋转 | 网格倾斜,线条锯齿 | CARDINAL |
| Blender 边距设为 0.005 | 填充量取决于岛的比例 | FRACTION,gap/(2*res) |
| 目标节点处于活动状态但未选中 | 烘焙返回 CANCELED,且没有错误 | 选中并激活;断言为 FINISHED |
| Low 将雕刻细节作为 Multires 携带 | 法线贴图几乎全平 | 烘焙时渲染级别设为 0(bake_high_to_low 会执行此操作) |
| max_ray 短于挤出距离 | 贴图恰好有 90% 完全平坦 | ray = 挤出距离 + 向内深度 |
| 对细小且彼此靠近的部分(如头部上的耳朵)使用统一挤出距离 | 出现反转的区域,邻近部分被烘焙进去 | 使用自适应烘焙(默认值)、拆开模型,或逐对烘焙 |
| AO 期间其他对象仍可见于渲染 | AO 发黑 | 将它们设为渲染不可见;活动的 Low 永远不会遮挡 |
| AO 距离默认值为 10 | AO 全黑或一片平坦 | 约为资产对角线的 0.2 倍 |
| 将堆叠 UV 烘焙到 0-1 范围内 | 一侧的细节出现在两侧 | 使用唯一 UV,或使用 offset_stacked |
| 岛内存在硬边 | 出现裂纹线 | 将其设为接缝,或使用 prepare_low(sharp_from_uv_islands=True) |
| 烘焙后编辑 UV | 出现接缝,切线不匹配 | 切勿这样做;重新烘焙 |
Blender 5.2 笔记
uv.unwrap默认使用 CONFORMAL。失败时会保留岛原有的 UV,并重新打包。它支持use_weights/weight_group(默认组为 "uv_importance"):使用 Minimum Stretch 的重要性权重。加权的上半部分占用的 UV 面积从 31% 提升到 74% [已验证]。- 同步选择默认开启(5.0)。
BMLoopUV只有uv和pin_uv。切换编辑模式后,me.uv_layers[...]引用会失效,因此请保留名称。 - 无界面模式下,
pack_islands(udim_source="CLOSEST_UDIM")会把位于 1002 的区域打包回 1001:先打包,再移动。uv.move_on_axis需要 UV 编辑器。 - 烘焙:目标必须处于选中且活动状态(5.0)。操作器默认值与场景默认值不同(
use_clear为 False 而非 True,EXTEND 而非 ADJACENT_FACES):请传入所有参数。“选中项到活动项”使用低模的渲染求值结果(Multires 的 render_levels、形状键)。Multires 设置位于scene.render.bake.use_multires,并使用object.bake_image()。保存为 PNG 的浮点图像是 16 位。法线贴图节点的convention为 OPENGL/DIRECTX(5.1)。UDIM 图块需要image.tile_add(fill=True)。 - Auto Smooth 已移除(4.1):使用平滑着色并设置锐边;Triangulate 的“Keep Normals”对应
keep_custom_normals。
参考资料
references/expert-notes.md:专家的判断,包含时间戳、不同意见和决策条件,以及我在 5.2.1 中的测量结果。选择缝线、密度或烘焙策略时加载。references/procedures.md:经过测试的流程(硬表面、角色、影视/UDIM、Multires、烘焙修复循环)及测试执行的原始 bpy 代码片段。编写代码前加载。references/critique.md:针对缝线、拉伸、密度、打包、烘焙设置和烘焙贴图的评估标准,包含代理指标和严重程度。每个检查关卡都要加载。references/sources.md:视频、凭据、URL、最佳时间戳和网络参考资料。scripts/bx_uvbake.py:该模块(文档字符串列出了每个函数)。