把一张二次元立绘拆成 23 个互不重叠、且被挡住的部分都补好的图层,最后输出成 PSD——这件事以前是 Live2D 画师几个小时的体力活。
读完本文你将了解:可直接跑的最小命令链 | 8 GB 到 16 GB 显存的四条路线怎么选 | 为什么“逐层拆”会失败、“一起拆”才对 | 哪些图它会拆坏。
这个项目解决什么问题?
图片是三维场景的二维投影,一旦发生遮挡,被挡住的像素就永久丢失了。想让角色动起来,就必须把丢失的那部分画回来——这是 Live2D 工作流里最耗人的环节:画师要把一张立绘手工切成几十上百层,还要逐层“脑补”被挡住的区域(头发后面的后脑、衣服底下的身体),最后手动指定每一层谁盖谁。
See-through 把这三件事自动化了。输入一张图,输出一个 PSD:最多 23 个带透明通道的语义图层(前发、后发、脸、眼、衣服、配饰等),每个图层都已经把被遮挡的部分补全,并且附带推断出的绘制顺序。📄
它来自 SIGGRAPH Conference Papers '26 的第 30 篇论文,作者来自中国香港的圣方济各大学、东京 Spellbrush 与宾夕法尼亚大学,仓库 Apache-2.0 开源。📄
先说清楚它不是什么:官方在 README 里专门写了一节「这是 Image-to-Live2D 吗」,答案是“不是,至少现在不是”。缺的三样是——面向形变的艺术性分层(自动分层优先保证语义正确,画师会按动作需要切)、rigging(形变网格与物理参数)、以及分层与绑骨的整体艺术意图。它产出的是一份高质量的 PSD 草稿,不是可以直接开播的模型。📄
快速上手(动手环节)
环境是这套东西第一个门槛:Python 3.12、PyTorch 2.8.0、CUDA 12.8。依赖按用途分档,走推理只需要装推理档;如果要用交互式 UI,还要额外装mmdet那一档(detectron2 / SAM2 / mmcv / mmdet 的组合)。🌐
克隆后先确认主入口存在,再按显存选路线:
gitclone https://github.com/shitagaki-lab/see-through.gitcdsee-through&&python-c"import torch; print(torch.__version__, torch.cuda.is_available())"# 路线 A:16 GB 以上,bf16 全精度python inference/scripts/inference_psd.py--srcpassets/test_image.png--save_to_psd# 路线 B:12 GB,开 group offload(约 1.5 倍慢,峰值降到 ~10 GB)python inference/scripts/inference_psd.py--srcpassets/test_image.png--save_to_psd--group_offload# 路线 C:8 GB,NF4 量化(默认 depth 720,可再降 layerdiff 到 1024)pipinstall-rrequirements-inference-bnb.txt python inference/scripts/inference_psd_quantized.py--srcpassets/test_image.png--save_to_psd--resolution1024# 路线 D:8 GB 但坚持 bf16,走 block swappython inference/scripts/inference_psd_blockswap.py--srcpassets/test_image.png--save_to_psd--srcp既可以接单张图,也可以接一个目录,批量时会逐张处理。默认产物落在workspace/layerdiff_output/,里面除 PSD 还有中间深度图和分割 mask——这两样别删,后面调层序全靠它们。
拿到 PSD 之后还有一步常常被忽略:再劈一层。同一层内部如果横跨了明显的前后关系(典型是头发从脸前绕到脸后),需要按深度切开;左右对称的部件(比如左右手套)需要按左右切:
python inference/scripts/heuristic_partseg.py seg_wdepth--srcpworkspace/layerdiff_output/xxx.psd--target_tagshandwear python inference/scripts/heuristic_partseg.py seg_wlr--srcpworkspace/layerdiff_output/xxx_wdepth.psd--target_tagshandwear-1显存这件事有个容易被误读的点:NF4 路线画质损失很小(对 bf16 基线 PSNR 约 30 dB、SSIM 约 0.96),代价主要在量化后的权重体积和轻微速度,而--group_offload是反过来——画质不动,速度掉约 1.5 倍。所以 12 GB 卡别急着上量化,先试 offload。📄
技术原理:为什么“逐层拆”一定会失败
这套管线的骨架是三个模型的组合,而不是一个端到端网络:LayerDiff 3D 负责生成带 alpha 的透明图层,Marigold 的二次元微调版负责逐像素伪深度,SAM Body Parsing 负责 19 类的语义分割。📄
真正的技术含量在训练策略上。第一版的做法很自然:给模型输入“原图 + 目标类名”,一次抠一个部件。跑出来的问题是每一层都不知道别的层在干什么——夹克和袖子颜色接近时,夹克层会几乎变空,像素被袖子层吸走;换个说法,19 个层在互相抢地盘。
第二版换了思路,也是这篇论文的核心:
把 19 个层的 latent 按视频帧的方式摞起来同时降噪,再让注意力跨层流动,等于给每个部件配了一份实时的“占用地图”。这个改动在数字上是可验证的:加上模块后深度误差 AbsRel 从 0.1549 降到 0.0943。📄
第二把刀是层序。既然要给 23 个层排前后,就得有一个连续量,而不是让模型直接输出“第 3 层压第 7 层”这种离散判断。See-through 用的是伪深度 + 部件内 K-Means 聚类:同一“头发”层内部按深度一劈为二,前发和后发就分开了,“头发夹在脸层前后”的三明治结构才复现得出来。📄
整体收益对比 SAM+LaMa 基线:PSNR 从 12.28 升到 18.30,FID 从 81.14 降到 18.37。📄 速度上,第三方转述论文的数据是 RTX 4090 上图层分解约 74 秒、深度约 10 秒——一次性预处理,这个量级可以接受。🌐
架构分析:三模型组合与一份自己造的数据集
推理链路的形状很清晰,代价也很清晰:链越长,错一次就传到底。
还有个工程细节值得单独提:仓库里头部和身体是两个连续阶段分别拆的,所以实际耗时比论文里报的模型更长。这是官方自己在 README 里挂出来的代价,不是外部评测发现的。📄
比架构更值得看的是数据从哪来。2.5D 分层这件事没有现成标注——世界上不存在“这个角色第 7 层是后发”的公开数据集。作者的做法是从商用 Live2D 模型反推真值:
这套流程的价值在于把“画师脑子里的分层直觉”变成了可训练信号。9,102 个模型、总人工标注约 12 小时,平均下来一个模型不到 5 秒——这不是靠人力堆出来的数据集,是靠流程设计换来的。🌐 另有一步容易被忽略:用 Live2D 的 angle tracking 自动生成不同角度的姿态做数据增广,同样不需要额外标注。
优缺点 & 适用场景
能用的一面
- 输入输出都是行业标准格式:进去是 PNG/JPG,出来是 PSD。画师不需要学新工具,直接在 Photoshop 里接着改。
- 分层是语义的,不是按颜色或连通域切的。这一点决定了它的产物能直接进 2.5D 流程,而不是一堆需要重新归类的碎片。
- 三档显存路线覆盖了从 8 GB 笔记本到 24 GB 工作站,量化版画质损失很小(PSNR 约 30 dB)。
会翻车的一面(第三方上手记录的失效面,🌐)
- 适合:单角色、正面到微侧、上色干净、发/衣/饰符合二次元视觉语法的图。
- 吃力:极复杂的褶皱、手或道具明显挡住脸、极端透视、带完整背景的插画、重度 Q 版变形、半透明材质或重特效。
- 官方明说它不能替代 rigging,也不做艺术性分层。
所以合理的预期是“三小时手工拆层变成一小时修图”,而不是“点一下出成品”。这个差别在采购决策上很关键:它省的是体力活,不是判断力。
总结
See-through 真正的贡献,是把一件依赖画师直觉的事拆成了两个可计算的量:补什么交给生成先验(LayerDiff 3D),谁在前交给连续几何量(伪深度)。中间那个跨层注意力模块,解决的是“多层同时决策时如何不打架”这个通用问题——同样的思路在需要输出多个互斥结果的场景里都能借用。
想动手的话,建议顺序是:先用官方示例图把三条显存路线各跑一遍确认环境,再拿一张结构最简单的正面立绘试真图,最后才上复杂稿。别一上来就丢最贵的那张。
本文产出:一份可直接复制的四路线命令清单(见「快速上手」)、一份显存与画质取舍对照(bf16 / offload / NF4 / blockswap)、三个 Mermaid 流程图(训练策略、推理链路、数据引擎)。
信息来源说明:本文未做运行验证(git clone在采集时超时失败,未实际生成 PSD)。📄 标记为官方 README / 论文口径,🌐 标记为第三方上手记录或论文转述。显存与画质数字以官方说明为准,实际表现随驱动、分辨率与图片复杂度变化。