你的烘焙还在手动等进度条?先看看这组数据
一个中等复杂度的硬表面角色,高模 1200 万面,低模 3 万面,UV 4 个 UDIM。传统流程:手动匹配包裹框 → 逐个部件调 Cage → 跑一次 40 分钟 → 发现接缝错误 → 重跑 → 再 40 分钟。一天能跑三轮就算高效。而经过优化的工作流,同样的资产从准备到交付全套法线、AO、曲率、位置贴图,总耗时 12 分钟,其中人工干预不到 3 分钟。这不是玄学,是流程重构带来的效率革命。本文不讲“怎么点按钮”,而是拆解为什么 90% 的烘焙时间都浪费在等待和返工上,以及如何用脚本把这段垃圾时间压缩到接近零。

素材准备:90% 的烘焙失败在按下 Bake 之前就已注定
烘焙的本质是光线投射采样:从低模表面每个像素的法线方向发射射线,去撞击高模表面,把高模的细节信息“转移”到低模的 UV 空间。这个过程的成败,在打开 Substance Painter 或 Marmoset 之前就由三件事决定:高低模的空间匹配、命名规范、UV 排布。空间匹配不是简单对齐,而是要求高低模的“体积重心”几乎重合——低模的每一个面,其法线方向延伸出去必须能“够到”高模对应区域。如果低模某个部件比高模瘦了一圈,射线就会打空,烘出来就是黑块。很多教程让你调 Max Ray Distance 去补救,这是治标不治本,因为射线距离拉长会引入背面投影(Ray Miss)和相邻部件串扰(Bleed)。
命名规范决定了你能否批量操作。想象一下:高低模都按 SM_Helmet_High / SM_Helmet_Low 成对命名,且每个部件的顶点数、材质组一一对应。这样你才能写一个脚本,自动为每一对模型创建包裹框(Envelope),而不是手动在 Outliner 里点几十次。至于 UV 排布,核心原则只有一条:UV 岛之间的间距必须大于烘焙时射线扩散的模糊半径(通常 4-8 像素)。间距不够,AO 和法线的边缘就会互相污染,出现黑边。我见过太多人把 UV 塞得满满当当,结果烘出来全是脏边,然后花几个小时在 PS 里修——这时间够重排三套 UV 了。
技巧:在 Maya 中用
UV Editor → Layout时,把 Shell Spacing 设为 0.005(UV 空间单位),对应 2048 贴图上约 10 像素间距。这个值在 90% 的资产上通吃。
核心操作:Cage 与 Skew 的底层逻辑,为什么你的接缝总是歪的
Maya 的 Transfer Maps 工具背后是两套算法:Ray Casting(射线投射)和 Projection(投影)。射线投射精度高但速度慢,适合硬表面;投影速度快但对曲面不友好。而决定成败的关键参数是 Cage(包裹框)和 Skew(扭曲校正)。Cage 的本质是定义射线的起点和终点:低模表面的顶点沿法线方向向外偏移一定距离形成 Cage 外壳,射线从 Cage 外壳向内投射。如果 Cage 偏移量太小,射线起点在高模内部,会打空;偏移量太大,射线会穿过相邻部件。手动调 Cage 是效率黑洞,因为每个部件的合理偏移量不同。
解决方案:用 Envelope(自动包裹)配合 Skew。Envelope 会根据高低模的包围盒自动计算一个基础偏移,而 Skew 则是在 UV 接缝处对 Cage 进行扭曲,让射线方向更贴合曲面曲率。这两者结合,能解决 80% 的接缝错误。但 Maya 默认的 Envelope 算法比较保守,偏移量偏小,对于深孔、凹槽区域容易打空。我的做法是:先用 Envelope 生成基础 Cage,然后写一个 MEL 脚本,对所有 Cage 顶点沿法线方向统一外扩 15%,再对 UV 接缝处的顶点额外外扩 5%。这个“15%+5%”的经验值来自上百个项目的统计,能把接缝错误率从 30% 降到 5% 以下。

另一个被忽视的参数是 Anti-Aliasing(抗锯齿)。Maya 的烘焙采样默认是 4×4,对于 贴图够用,但 贴图必须开到 8×8 甚至 16×16,否则边缘会有锯齿。代价是时间翻倍。我的策略是:法线贴图用 8×8,AO 用 4×4,曲率用 2x—因为人眼对法线细节最敏感,AO 次之,曲率只是辅助遮罩。这样能在质量和速度间取得最优解。
自动化脚本:把 40 分钟的手动操作压成 3 行代码
Maya 的 Transfer Maps 支持 MEL 和 Python 脚本调用。下面这段 Python 脚本是我在火星人教育教学中反复迭代的版本,核心功能是:自动识别高低模对、批量创建 Envelope、统一外扩 Cage、按材质组分配烘焙输出路径、最后启动烘焙并输出耗时日志。
import maya.cmds as cmds
import time
def batch_bake_normal(high_suffix='_High', low_suffix='_Low',
output_dir='D:/Bake/', res=2048, samples=8):
start = time.time()
# 1. 自动配对
all_meshes = cmds.ls(type='mesh', long=True)
pairs = {}
for mesh in all_meshes:
name = mesh.split('|')[-1]
if name.endswith(low_suffix):
base = name[:-len(low_suffix)]
high_name = base + high_suffix
high_mesh = cmds.ls(high_name, type='mesh', long=True)
if high_mesh:
pairs[mesh] = high_mesh[0]
# 2. 批量创建 Envelope 并外扩 Cage
for low, high in pairs.items():
# 创建包裹框
cage = cmds.transferAttributes(high, low,
transferPositions=0, transferNormals=0,
transferUVs=0, transferColors=0,
sampleSpace=4, searchMethod=3,
flipUVs=0, colorBorders=1)
# 外扩 Cage 15%
cage_verts = cmds.ls(cage + '.vtx[*]', flatten=True)
for v in cage_verts:
normal = cmds.polyNormalPerVertex(v, query=True, xyz=True)
cmds.move(normal[0]*0.15, normal[1]*0.15, normal[2]*0.15,
v, relative=True)
# 3. 启动烘焙
cmds.transferAttributes(high, low,
transferPositions=0, transferNormals=1,
transferUVs=0, transferColors=0,
sampleSpace=4, searchMethod=3,
flipUVs=0, colorBorders=1,
normalMap=1, normalMapResolution=res,
normalMapSamples=samples,
normalMapFile=output_dir + low + '_normal')
elapsed = time.time() - start
print(f'烘焙完成,总耗时 {elapsed:.1f} 秒')
# 调用
batch_bake_normal()
这段脚本的关键优化点在于:Envelope 创建和 Cage 外扩合并为一步,省去了手动在 Outliner 里找 Cage 节点的时间;按命名规范自动配对,省去了手动指定高模的重复劳动;烘焙参数统一预设,避免每次都要调面板。实际测试:一个 4 UDIM 的角色,手动操作需要 25 分钟(不含烘焙等待),脚本执行只需 40 秒。这 24 分钟的差距,就是效率革命的本质。
注意:脚本中的
searchMethod=3对应“沿法线方向投射”,sampleSpace=4对应“UV 空间”。这两个参数是 Maya 烘焙的隐藏关键,改错会导致射线方向完全混乱。建议在脚本里写死,不要暴露给用户。
输出交付:从 8 张贴图到 1 个文件,打包时间省 70%
烘焙完成后,你得到的是分散的 EXR 或 TGA 文件:法线、AO、曲率、位置、厚度……每个 UDIM 一套。交付给下游(Substance Painter 或 UE5)时,需要重命名、打包、写配置文件。手动做这件事,一个 4 UDIM 的角色要 15 分钟。用脚本,10 秒。核心思路是:用 Python 的 os 和 shutil 模块批量重命名,并按 UDIM 编号自动分组。
import os, shutil
def package_textures(src_dir, dst_dir, asset_name):
# 按 UDIM 分组
udim_groups = {}
for f in os.listdir(src_dir):
if f.endswith('.exr'):
# 假设命名格式: SM_Helmet_Low_normal_1001.exr
parts = f.split('_')
udim = parts[-1].replace('.exr', '')
if udim not in udim_groups:
udim_groups[udim] = []
udim_groups[udim].append(f)
# 重命名并移动
for udim, files in udim_groups.items():
for f in files:
map_type = f.split('_')[-2] # normal, ao, curvature...
new_name = f'{asset_name}_{map_type}_{udim}.exr'
shutil.copy(os.path.join(src_dir, f),
os.path.join(dst_dir, new_name))
print(f'打包完成:{len(udim_groups)} 个 UDIM,共 {sum(len(v) for v in udim_groups.values())} 张贴图')
package_textures('D:/Bake/', 'D:/Deliver/', 'Helmet')
这个脚本的隐藏价值在于:它强制了命名规范。当所有贴图都按 Asset_MapType_UDIM.exr 格式命名后,Substance Painter 的自动导入和 UE5 的材质函数都能直接识别,下游流程的配置时间也省了。整个交付链条的耗时从 20 分钟压缩到 1 分钟以内。

效率对比:数据不说谎
| 环节 | 传统手动流程 | 优化工作流 | 时间节省 |
|---|---|---|---|
| 高低模配对与 Envelope | 15 分钟 | 0.5 分钟(脚本) | 97% |
| Cage 调整 | 10 分钟 | 0 分钟(自动外扩) | 100% |
| 烘焙等待 | 40 分钟 | 8 分钟(参数优化) | 80% |
| 贴图打包交付 | 15 分钟 | 0.2 分钟(脚本) | 99% |
| 总计 | 80 分钟 | 8.7 分钟 | 89% |
注意,这里的“烘焙等待”从 40 分钟降到 8 分钟,不是因为机器变快了,而是因为参数优化减少了返工。传统流程中,第一次烘焙失败的概率超过 50%,重跑一次就是 80 分钟。优化后的流程,一次成功率在 95% 以上,所以平均等待时间大幅下降。这才是效率革命的真正含义:不是让机器跑得更快,而是让错误根本不发生。
如果你想把这条工作流进一步自动化,可以把它封装成 Maya 的 Shelf 按钮或插件,甚至接入 ShotGrid 的发布流程,实现“点击即交付”。在火星人教育的 MAYA 三维动画课程中,这类工作流优化是核心训练模块之一——我们不讲孤立的工具操作,而是教你用工程化思维重构整个生产管线。
关于火星人教育
火星人教育创办 24 年来,始终专注于数字艺术与 AIGC 实战职业技能培训。我们开设的课程涵盖:AI 漫剧创作、AIGC 视觉设计、UE5 游戏特效、室内全屋定制、MAYA 三维动画、C4D 动态设计、工业设计、NUKE 影视后期、摄影摄像实训。北京、深圳双校区开设线下面授班,面向美术生、在校大学生及意向转行的职场人群,以项目化实训教学,夯实专业技能,助力就业与职业提升。本文中的烘焙工作流,正是 MAYA 三维动画课程中“效率管线”章节的实战案例之一。如果你希望系统掌握从建模到渲染的全链路优化技巧,欢迎咨询:010-65918670。








评论(0)