ComfyUI 游戏美术资产模板化生产流(一):从管线骨架到三维控制模型
系列第一章,记录两个半小时的 ComfyUI 系统学习过程,深入剖析 SD1.5 基础管线、LoRA 风格注入、img2img 内容驱动、ControlNet 结构约束的底层原理,以及关于约束粒度的思想实验。
学习 Stable Diffusion 用 ComfyUI 还是 WebUI(A1111/Forge)?我的选择是 ComfyUI——不是因为它是”进阶工具”,而是节点化管线让你无法回避理解每个参数的真实含义。在 WebUI 里点一个按钮,背后的链路是黑盒;在 ComfyUI 里,你得亲手把 Checkpoint 连到 Clip Text Encode,把 KSampler 连到 VAE Decode,缺一根线都不出图。
这篇文章记录了我在两个半小时内从零搭建完整 UI 资产生成工作流的全过程,包括概念纠正、LoRA 触发机制、img2img 的 denoise 关键参数、ControlNet 约束粒度的权衡,以及最后关于剪影约束的”思想实验”。
第一阶段:理解管线骨架(txt2img)
最小可出图管线
ComfyUI 最小 txt2img 管线只有 6 个节点:
graph LR
CKPT[Load Checkpoint<br/>SD1.5] -->|MODEL| KSampler
CKPT -->|CLIP| POS[CLIP Text Encode<br/>正向提示词]
CKPT -->|CLIP| NEG[CLIP Text Encode<br/>反向提示词]
CKPT -->|VAE| VAE_DEC[VAE Decode]
EMPTY[Empty Latent Image<br/>512x512] -->|LATENT| KSampler
POS -->|CONDITIONING| KSampler
NEG -->|CONDITIONING| KSampler
KSampler -->|LATENT| VAE_DEC
VAE_DEC -->|IMAGE| PREVIEW[Preview Image]
每个节点的职责非常清晰:Checkpoint 提供模型/CLIP/VAE 三件套;CLIP Text Encode 把自然语言变成模型能理解的向量;KSampler 在潜在空间迭代去噪;VAE Decode 把潜在空间向量还原成像素图。
KSampler 参数逐个拆解
KSampler 是整个管线的核心。6 个参数里,最容易理解错的恰好是最重要的两个。
seed(随机种子) 决定了初始噪声的分布。同一 seed + 同一参数 = 完全相同的图。seed 不变,微调其他参数可以看到这个参数的独立影响,这是理解参数含义的核心实验方法。
steps(采样步数) 模型迭代去噪的次数。SD1.5 的理想区间是 20~30 步:
- < 15 步:去噪不充分,画面噪点多、细节模糊
- 20~30 步:最佳性价比区间,质量稳定
30 步:边际收益急剧递减,某些 scheduler 甚至会画质劣化
steps 越高确实迭代次数越多、吃显卡越重,但不是线性提升质量——25 步之后每多 5 步增加的细节肉眼几乎不可分辨。
cfg(Classifier-Free Guidance) 这是我第一个纠正的认知。CFG 不是”自由发挥程度”,恰恰相反——它是提示词的服从强度。
原理简要版:CFG 工作时混合两个预测——有提示词引导的预测和无条件预测。公式近似为 output = unconditional + cfg × (conditional - unconditional)。cfg=1 时两者等权重,你写”a cat”和”a dog”几乎没区别;cfg=7 时条件预测被放大 7 倍,模型严格跟着提示词走。超过 12 则放大过度,对比度和饱和度异常升高,画面出现”烧焦感”。
记忆口诀:CFG = 听话程度,越大越听话。
sampler_name 和 scheduler sampler 是采样算法(怎么从噪声中恢复画面),scheduler 是噪声调度策略(每步去多少噪声)。dpmpp_2m + karras 是 SD1.5 社区最普遍的选择:dpmpp_2m 收敛快、细节好,karras 在低步数时有更好的信噪比分布。
denoise(去噪强度) 这是我的第二个纠正。denoise 不是控制最终画面的噪点量,而是控制”给 latent 加多少噪声再开始去噪回推”:
- denoise=1.0 → 加满噪声,完全从零重建(txt2img 必须开 1)
- denoise=0.6 → 加 60% 噪声,保留 40% 原始 latent 信息(img2img)
- denoise=0.0 → 不加噪声,直接输出原图
说的不是最终输出有多少噪点,而是扩散过程的起点被加了多少噪声。 denoise 越低,保留源图信息越多,画面越”干净”(接近源图),不是”噪点多”。
SD1.5 基模选择
SD1.5 原始模型经历了多个版本迭代。v1-5-pruned-emaonly.safetensors 是社区公认的最佳版本:
pruned:移除了训练优化器状态,文件从 ~7GB 缩到 ~4GB,出图质量不变emaonly:只保留 EMA(指数移动平均)权重,比常规权重更稳定,图像整体色调更统一- 发布方:RunwayML,2022 年 10 月
配合 LCM 模型时需要注意:LCM(Latent Consistency Model)专为少步数(4~8 steps)设计。如果你误用 LCM 模型跑 25 steps + dpmpp_2m,不仅浪费算力,还可能画质劣化。普通 SD1.5 基模 + dpmpp_2m + karras + 25 steps 是稳妥的标准配置。
第二阶段:LoRA 风格注入
LoRA 工作原理
LoRA(Low-Rank Adaptation)不是一个小模型,而是模型权重的低秩补丁。它在不改变原始模型参数的基础上,训练两个小矩阵 A 和 B,使原始权重 W 变为 W’ = W + α·A·B。推理时直接合并,无额外推理延迟。
核心认知:LoRA 改变了模型”怎么画”,但不改变模型”画什么”。
触发词是激活 LoRA 的钥匙
LoRA 训练时,所有训练图片都会关联一串 trigger words。这些词在训练过程中被反复强化关联,不写触发词就意味着 LoRA 的权重补丁虽然挂载了,但 CLIP 编码器不知道要去激活哪个概念方向,等于白挂。
strength_model 参数控制 LoRA 补丁的权重倍数:
- strength=0.3 → 轻量影响,微调底色
- strength=0.7 → 均衡,大多数 LoRA 的最佳值
- strength=1.0 → 创作者训练时的默认强度,部分 LoRA 过拟合需要降
常见误区:ComfyUI 不吃 WebUI 语法
A1111/Forge WebUI 的 <lora:filename:strength> 标签在 ComfyUI 里完全无效。ComfyUI 通过 LoraLoaderModelOnly 节点单独加载 LoRA,提示词中只写纯文本 + 触发词。<lora:...> 会被当乱码喂进 CLIP 编码器,干扰语义向量。
第三阶段:img2img — 源图驱动内容
管线变更
img2img 与 txt2img 的区别只有一个:把 Empty Latent Image 替换为 LoadImage → VAEEncode。源图像素 → VAE 编码成 latent → 加噪声 → KSampler 去噪重建。
graph LR
subgraph txt2img
EMPTY[Empty Latent Image] --> KS_T[KSampler]
CPT_T[Checkpoint] --> KS_T
end
subgraph img2img
SRC[LoadImage] --> VAE_ENC[VAE Encode] --> KS_I[KSampler]
CPT_I[Checkpoint] --> KS_I
end
denoise 是 img2img 的核心调参旋钮
img2img 和 txt2img 共享同一个 KSampler,唯一的区别就是 denoise。它不是”控制最终噪点”,而是控制加噪幅度:
denoise=0.55~0.65 是游戏 UI 资产的最佳区间:保留源图的结构和构图骨架,同时让 LoRA 风格充分渗透。超过 0.7 源图信息被大量抹除,低于 0.4 风格变化微弱。
第四阶段:ControlNet — 结构约束
Canny 边缘检测
ControlNet 的核心思想是给扩散过程的每一步叠加上结构信号。Canny 是最经典的结构约束方式——从源图提取边缘线框,强制生成图保持同样的轮廓。
graph TD
SRC[LoadImage 源图] --> CANNY[Canny 边缘检测]
SRC --> VAE_ENC[VAE Encode]
CANNY --> CTL_APPLY[ControlNetApply]
CTL_NET[ControlNet Loader<br/>control_v11p_sd15_canny] --> CTL_APPLY
POS[正向提示词] --> CTL_APPLY
NEG[反向提示词] --> CTL_APPLY
CTL_APPLY -->|正/负 conditioning| KSampler
VAE_ENC -->|latent| KSampler
LORA[LoRA] --> MODEL
MODEL --> KSampler
Canny 双阈值
1
low_threshold=0.56, high_threshold=0.72
Canny 算法的双阈值规则:
- 像素梯度 > high_threshold → 确定是边缘(强边缘)
- 像素梯度 < low_threshold → 确定不是边缘(丢弃)
- 介于两者之间 → 如果和强边缘相连则保留,否则丢弃
阈值差越小 → 选中的边缘越少、越纯净。UI 资产通常用窄阈值(0.5~0.75),只保留主体的核心轮廓线,避免复杂纹理干扰生成。
ControlNet strength
strength 控制结构约束的强弱——不是”识别”结构,而是强行约束潜在空间去贴合边缘。strength=0.5 给模型留了一半的”不听话”空间,strength=1.0 完全锁死结构。
第五阶段:全流程整合
完整管线
graph TD
CKPT[Load Checkpoint SD1.5] -->|MODEL| LoRA
CKPT -->|CLIP| POS_ENC[CLIP Text Encode 正向]
CKPT -->|CLIP| NEG_ENC[CLIP Text Encode 反向]
CKPT -->|VAE| VAE_DEC
CKPT -->|VAE| VAE_ENC
LoRA[LoraLoaderModelOnly] -->|MODEL| KSampler
SRC[LoadImage 源图] --> CANNY[Canny 边缘检测]
SRC --> VAE_ENC[VAE Encode] -->|latent| KSampler
CANNY --> CTL_APPLY[ControlNetApply]
CTL_LOADER[ControlNet Loader] --> CTL_APPLY
POS_ENC --> CTL_APPLY
NEG_ENC --> CTL_APPLY
CTL_APPLY -->|正conditioning| KSampler
CTL_APPLY -->|负conditioning| KSampler
KSampler -->|latent| VAE_DEC[VAE Decode]
VAE_DEC --> REMBG[Remove Background] --> SAVE[SaveImage PNG]
参数对照表
| 参数 | UI icon 推荐值 | UI button 推荐值 | banner 推荐值 |
|---|---|---|---|
| 尺寸 | 512×512 | 512×128 | 1024×384 |
| steps | 25 | 25 | 25 |
| cfg | 7 | 7 | 7 |
| sampler/scheduler | dpmpp_2m/karras | dpmpp_2m/karras | dpmpp_2m/karras |
| denoise | 0.6 | 0.6 | 0.6 |
| LoRA strength | 0.7 | 0.7 | 0.7 |
| ControlNet strength | 0.75 | 0.75 | 0.75 |
| Canny low/high | 0.5/0.7 | 0.5/0.7 | 0.5/0.7 |
关键提示词策略
正向提示词(游戏 UI):
1
2
3
masterpiece, best quality, game ui asset, game icon, clean design,
flat vector style, vibrant colors, sharp edges, centered composition,
solid background, simple shapes, [LoRA Trigger Word]
反向提示词:
1
2
3
lowres, bad anatomy, blurry, text, watermark, jpeg artifacts,
signature, ugly, mutated, deformed, extra fingers, messy lines,
photorealistic, 3d render, gradient background, complex scene
“photorealistic”和 “3d render” 在反向提示词中至关重要——UI 资产需要的是平面矢量感,而非写实/3D 感。这两个词能显著减少出图的”过真实”倾向。
概念纠正记录
学习过程中我踩了两个经典的”反直觉”坑,必须单独记一笔:
CFG 方向反转
| 我的初始理解 | 正确理解 |
|---|---|
| cfg ↑ → 模型自由发挥程度高 | cfg ↑ → 模型越严格遵循提示词 |
| 类比:创意自由度 | 类比:服从强度/听话程度 |
denoise ≠ 最终画面噪点
| 我的初始理解 | 正确理解 |
|---|---|
| denoise ↓ → 画面噪点多 | denoise ↓ → 源图保留多、画面更干净 |
| 控制最终品质 | 控制加噪幅度(扩散起点) |
WebUI 语法混用
ComfyUI 节点化挂 LoRA 后,提示词里不需要(也不应该)写 <lora:...> 标签。这是 A1111 的约定,在 ComfyUI 里被视为乱码文字。
思想实验:约束粒度的权衡
RGB Canny vs Alpha 剪影 Canny
这是学习过程中最有价值的发现。一开始我想”先把背景抠干净再给 Canny 做边缘”,用 Remove Background → ImageToMask(alpha) → MaskToImage → Canny 这条链路。结果发现 Canny 只输出了一条外轮廓剪影线——物体表面的纹理、接缝、装饰线全丢了。
但这不一定是错误,而是一个设计选择:
| RGB Canny | Alpha 剪影 Canny | |
|---|---|---|
| 输入信息 | 全部 RGB 像素 | 仅 alpha 通道(剪影) |
| 约束层级 | 外轮廓 + 内部细节 | 仅整体外形 |
| 模型自由度 | 低(忠实复刻源图) | 高(形状框住,内容自由发挥) |
| 适合场景 | 精修现有设计、改色/材质 | 给定形状 → 生成全新设计 |
| UI 资产应用 | 不要改变原有 icon 的风格 | 给定方形区域 → LoRA 往里填充内容 |
形状驱动生成:一个新的 UI 资产范式
这就引出了一个有趣的思路:用简单的形状图(方框、圆形、特定轮廓)+ Canny 作为形状约束,配合 LoRA 做内容填充。
具体做法是画一张”垃圾形状图”——一个纯色方块、一个纯色圆圈——喂进 Canny,Canny 提取出干净的单线轮廓,ControlNet 用这条轮廓约束扩散过程,LoRA 往里填充风格化内容。结果是一个形状由你定义、风格由 LoRA 定义的 UI 资产。
这本质上是”模板化资产生成”——给定按钮的形状模板,批量生成不同风格变体,确保所有按钮大小形状一致。
待实验:多路 ControlNet 叠加
一个值得后续探索的方向:在单次生成中同时使用两路 ControlNet:
1
2
3
形状图 → Canny → ControlNetApply(strength=0.8) # 管外形
参考图 → LineArt/Depth → ControlNetApply(strength=0.3) # 管内部结构引导
→ 汇合到同一 KSampler
以及把 Alpha 剪影直接做成 MASK 连入 KSampler 的 latent_image 做局部重绘(inpainting),让模型只在 mask 白色区域内生成,外部完全保持透明。这对 UI 资产直接输出透明 PNG 有实用价值。
学习路线总结
graph LR
A[第一阶段<br/>txt2img 骨架<br/>30min] --> B[第二阶段<br/>LoRA 风格注入<br/>30min]
B --> C[第三阶段<br/>img2img 源图驱动<br/>30min]
C --> D[第四阶段<br/>ControlNet 结构约束<br/>30min]
D --> E[第五阶段<br/>全流程整合<br/>30min]
style A fill:#dbeafe,stroke:#3b82f6
style B fill:#fef3c7,stroke:#f59e0b
style C fill:#fce7f3,stroke:#ec4899
style D fill:#dcfce7,stroke:#22c55e
style E fill:#ede9fe,stroke:#8b5cf6
每阶段 30 分钟,每次只加一个新概念。调通再往前走——这是最核心的学习原则。在 ComfyUI 里,节点不会骗你:连错一根线就报错,参数写错一个就出黑图。这种”即时反馈”远比 WebUI 的模糊滑块更高效。
核心认知地图
SD 生图的本质是三维控制:风格(LoRA)+ 内容(img2img denoise)+ 结构(ControlNet strength)。这三个维度互相独立,可以任意叠加,每一维都有各自的”强度旋钮”。理解了这个三维模型,就能精确控制出图效果——不再是”抽卡”,而是”调参”。
结语
两个半小时,从最小 txt2img 管线到全流程 SD1.5 + LoRA + img2img + ControlNet 整合,把 ComfyUI 节点一条线一条线搭通。最大的收获不是能出多少张图,而是建立了对每个参数的精确心智模型——cfg 是服从强度不是自由度,denoise 是加噪幅度不是最终噪点,LoRA 改的是风格不是内容,ControlNet 管的是结构不是识别。
ComfyUI 的节点化不是学习门槛,恰恰相反——它是理解 SD 底层原理最快的路径。在 WebUI 里你可以永远不弄懂这些也能出图,但在 ComfyUI 里你每连一根线都在问自己”这个节点的输出是什么,为什么要连到那个节点”。这种因果链的可视化,才是真正学会 Stable Diffusion 的方式。
下一步:多路 ControlNet 叠加 + MASK 局部重绘。明天继续。
本系列文章由 AI 参与指导学习。
