origin: one picture, two routes
This chapter is the running account of one particular picture. It is not translated with the rest of the book; in the English edition it stays in Chinese.
✅ 已验证(一次成型:work/shinku-hug-basic-1/、-2/,dtp 0.2.0 / 0.3.0)· 🧪 跑到分层线稿(先分层后上色:work/shinnku-hug-pro/,dtp 0.5.2)· 标「历史」的表来自 v9.0.0 那本书(旧走法「先素描后上色」),step 目录已删、指不到文件,只作参照
正文不认识这张图;它的一切都在这一章。每个数字后面是它来自的 step 目录。
源图与要什么
input/origin.png,1024×1536,一张 diffusion 生成的插画:金发白裙、双臂抱在胸前的少女,黑底一片辉光。要的是画师能接手的分层原画;两条走法各开一个子项目(-basic 一次成型、-pro 先分层后上色),parts.py 同一份。
分割(shinku-hug-basic-1/phase1-layers/step01-segment)
65 个区域 → 手写表 15 个子部件 → 多数票后仍 15 个;alpha 洞补回 5,572 px;多数票改了 34,923 px(主体的 7.9%);12 个 SAM 词(hair / face / eyes / mouth / dress / red bow / shoes / legs / arms / hands / neck / shoulders);38 s。
| 手写表的子部件 | px | 多数票改了 | 去了哪 |
|---|---|---|---|
| Hair_Back | 65,416 | 1,023(1.6%) | Ribbon_Hair |
| Skin_Leg_L / R | 31,144 / 26,954 | 3 / 0 | Shoe |
| Skin_Foot | 8,839 | 496(5.6%) | Shoe |
| Shoe | 6,764 | 2,234(33.0%) | Skin_Foot 1,989、Skin_Leg_L 245(鞋口的袜) |
| Skin_Torso / Skin_Arm | 22,374 / 6,836 | 0 / 0 | |
| Skin_Face | 10,873 | 1,625(14.9%) | Hair_Front(压在脸上的刘海) |
| Dress_Bodice | 10,498 | 2,128(20.3%) | Skin_Torso 1,946、Ribbon_Waist 182 |
| Dress_Skirt | 65,533 | 2,393(3.7%) | Ribbon_Waist 2,232、Ribbon_Hem 160 |
| Dress_Frill | 74,464 | 1,886(2.5%) | Ribbon_Hem 1,023、Ribbon_Waist 857 |
| Ribbon_Waist | 10,082 | 7,755(76.9%) | Hair_Front——手写表把腰边的粉色发梢当成了腰带 |
| Ribbon_Hair | 3,860 | 2,222(57.6%) | Hair_Front 1,544、Hair_Back 678 |
| Hair_Front | 90,473 | 7,586(8.4%) | Skin_Torso 5,255(脖子回到皮肤)、Ribbon_Hair 2,318 |
脖子:手写表里脖子和整头前发是同一个区域,所以一次成型(只用手写表)的脖子是头发画的;多数票里 hair 占这个区域 90%,整区域判给头发,靠 neck / shoulders 两个词当种子按颜色长回来(第 1 章)。neck 只圈到脖子的 45%,shoulders 22%,chest / upper body / skin 都退化成整个人(29% 画面),不能用。剩下的:刘海之间的额头还归前发(face 的 mask 圈不到)。
左手写表(腰边那缕粉发梢是腰带的品红),中多数票,右变动的像素。
线当墙(shinnku-hug-pro/phase1-layers/step03-segment,WALLS = step02-lineart、ASSIGN_FROM = step01-segment,dtp 0.4.0,38 s):step02 的 244 笔线光栅化成 38,997 px 的墙,区域 65 → 71;ASSIGN 表继承 step01;多数票之后与 step01 标签不同的像素 5,472(主体的 1.24%)。变的集中在两处:脖子框(CROPS["neck"],1x 128×128)里 Skin_Torso 9,923 → 9,664、Hair_Front 1,944 → 2,240——step01 在锁骨的皮肤上有几块假的 Hair_Front,右边那缕真头发是断的;step03 假块没了,那缕头发沿着墙成了一条完整的带,Hair_Front 多出来的是真头发(只看计数会得出相反结论);鞋框里 1,901 px 从 Skin_Foot 还给 Shoe(鞋头连蝴蝶结那一片)。脖子本身 step01 就已归 Skin_Torso(neck / shoulders 词),墙没改它;手写表那一半继承老标签,脖子框 Hair_Front 6,812 → 6,835,没变。全图其余的差:Skin_Foot → Shoe 1,901、Skin_Torso → Hair_Front 1,304、Hair_Front → Skin_Torso 849、Dress_Bodice → Skin_Torso 230。特写脚本 phase1-layers/step03-segment/compare_neck.py。闸门结论:过。
源图 | step01 | step03 | 墙(红)。上脖子框,下鞋框。
一次成型(shinku-hug-basic-1/phase3-paint/step02-trace,dtp 0.2.0,4x)
读画(138 s):15 个子部件,13 个切了 5 档、两条腿 4 档,共 73 档;594 个环 + 剪影 13 = 607,20,495 控制点。笔 80,695:soft 38,846 · detail 38,963(中位长 24 px@8x)· strand 2,690 · hatch 196。
| sub-parts | px | 档 |
|---|---|---|
| Hair_Back | 65,416 | Flat · Shadow1 · Light1 · Light2 · Light3 |
| Skin_Leg_L / Skin_Leg_R | 31,144 / 26,954 | Flat · Shadow1 · Shadow2 · Shadow3 / Light1 |
| Skin_Foot · Shoe · Skin_Arm | 8,839 · 6,764 · 6,836 | Flat · Shadow1 · Shadow2 · Shadow3 · Light1 |
| Skin_Torso · Skin_Face · Dress_Bodice · Dress_Skirt · Dress_Frill · Ribbon_Hem | Flat · Shadow1 · Shadow2 · Shadow3 · Shadow4 | |
| Ribbon_Waist · Hair_Front | 10,082 · 90,473 | Flat · Shadow1 · Shadow2 · Light1 · Light2 |
| Ribbon_Hair | 3,860 | Flat · Light1 · Light2 · Light3 · Light4 |
落笔(作业 276 s):建树 100 s——layers.json 317 层 = 73 档 × 4 + 15 个部件组 + 骨架 10(Background、01_BG ×3、04_Color、剪影、06_Line ×2、09_Post ×2),74 个矢量层;逐笔 170 s,80,695 笔 = 99,802 次调用(475 笔/秒),丢弃 0;写像素 2 次;final.kra 96.9 MB。总耗时 414 s。
判据(phase3-paint/step02-trace/gauge.json,归一 2508 px,源图为锚):
| Criteria | 读数 | threshold |
|---|---|---|
| 落笔 / 写像素 | 80,695 笔 / 2 次 | ≤ 2 |
| gradient p99 | 37.7(源图 41.6 的 91%) | ≥ 85% |
| 8 级色数 | 1877(源图 2900 的 65%) | ≥ 55% |
| the 8 px stair fingerprint | 0.81(源图 6.19) | below the source’s |
| low-frequency likeness | 34.79 dB | ≥ 30 |
| 内部锐度 p90 | 9.5(头发 10.8;源图 10.5 / 8.4) | anchored to the source |
| the darkest pixel | (0, 0, 0) | (0,0,0) |
| node | 317(layers.json);规则 ≤ 5 + 10 × 15 = 155,每组 ≤ 10 | 按设计不过 |
1x 全图;六处 1:1 特写(4x):脸、脖子、左手、右手、腿、鞋。脖子上那些黄色发丝——脖子是头发画的。
Skin_Face 的五档形状:Flat / Shadow1(头发投在脸上的影)/ Shadow2(耳影、嘴、腮混在一起)/ Shadow3、Shadow4(两只眼睛的虹膜和瞳孔)。没有一层叫「眼睛」。
只铺皮肤和鞋的档:没有补齐,腿在裙下是断的,手臂是切开的。
核对 v9.0.0 那本书第 6 章的数字(phase3-paint/step02-trace/verify_ch9.py):
| 项 | v9 书 | 本次 | conclusion |
|---|---|---|---|
| 笔 / 落笔调用 / 写像素 | 80,695 / 99,802 / 2 | 一样 | |
| 梯度 p99 / 阶梯 / 内部锐度 p90 | 37.7 / 0.81 / 9.5 | 一样 | |
| 8 级色数 | 1878 | 1877 | 噪声内 |
| likeness | 34.8 | 34.79 | 噪声内 |
| 头发内部 p90 | 11.0 | 10.8 | 噪声内 |
| 源图头发内部 | 9.1 | 8.4 | 书错:v9 换了分割,头发 mask 变了,书没跟着改 |
| 节点 / 矢量层 / 环 / 控制点 | 307 / 74 / 607 / 20,495 | 317 / 74 / 607 / 20,495 | 书里 307 与 317 混用:307 是部件子树,317 是整棵树 |
| 建树 / 落笔 / 读画 | 93 / 162 / 144 s | 100 / 170 / 138 s | 机器噪声 |
| 笔种 | 「六种」 | 4 种 | 书错 |
| 每部件档数 | 2–5 | 4–5 | 书错 |
Skin_Face_Shadow3 = 瞳孔 + 嘴 + 鼻孔 + 耳影 + 脖影 | Shadow3 / 4 = 两只眼睛;嘴、耳影、腮在 Shadow2;脖子不在 Skin_Face | 书错,结论(档没有名字)不变 | |
| 隐藏裙子腿是断的 · 粉发梢当腰带 | 图确认 | 对 |
闸门结论(phase3-paint/step02-trace/README.md):过。数字与第 6 章一致;脖子是头发画的、腿在裙下是断的、档没有名字——这条走法的固有限制。
同一份计划两次落笔(shinku-hug-basic-2/step02-trace,dtp 0.3.0;这个子项目之后删了):读画产物与 basic-1 逐字一致(plan.json 只多一个 crops 键,strokes.jsonl 相同);Krita 落笔第二次:建树 93 s、逐笔 162 s(498 笔/秒)、作业 406 s(含作业自己写 review/ 的 142 s:15 个部件组 + 73 个档 + 12 处特写)。判据(step03-gauge):likeness 34.79 → 34.79(差 −0.0006 dB)、p99 37.71 → 37.74、色数 1877 → 1879、阶梯 0.81 → 0.81、内部锐度 9.51 → 9.51、头发 10.76 → 10.76——这条走法两次落笔的差远小于第 7 章写的噪声上限(0.6 dB / 3 个点 / 0.2);那个上限是先素描后上色量出来的(airbrush 多、随机种子多),一次成型的笔多数是确定性的。节点 317(layers.json),规则 ≤ 155、每组 ≤ 10(最多的一组 21):按设计不过。
先分层后上色(shinnku-hug-pro/)—— 跑到底;上色不过
跑到底(step08)。step01 / step02 在 dtp 0.3.0 上跑,走法在 step02 之后改(线在图层之前抽是顺序错误,第 2 章),step03 起是 0.4.0,step04 是 0.5.0(补齐换成 See-through 合并),step05 是 0.5.2,step06 起是 1.0.0(每个 step 一个 main.py)。上色(step07)人看了判不过——它抄像素,不是画(第 6 章「基线『抄』」);step07 / step08 挪成 -legacy-wrong-1,同一个号等按部位的画法,头发第一个。
| step | 工序 | status | 数 |
|---|---|---|---|
| step01 | segment | 过 | 与 basic-1 逐字一样(上面「分割」) |
| step02 | lineart | 没有单独验收;只当墙和对照 | 下面 |
| step03 | segment 线当墙 | 过 | 上面「分割」末尾 |
| step04 | complete(See-through 合并) | 过 | 下面。一圈一圈的那次不过(step04-complete-legacy-wrong-1),See-through 实验(step04-complete-legacy-experiment-1)都挪到一边,不占号 |
| step05 | lines | 放行(用户不满意,问题没列,底稿上再看) | 下面。第一次不过(step05-lines-legacy-wrong-1,solo 图带了黑剪影) |
| step06 | draft(闸门) | 过 | 下面 |
| step07 | paint | 不过(抄像素) | 下面。挪成 step07-paint-legacy-wrong-1 |
| step08 | gauge | 不过(量的是不过的上色;读数留作基线尺) | 下面。挪成 step08-gauge-legacy-wrong-1 |
线稿(step02-lineart,35 s):轮廓候选 106 + AI 402 = 508,修剪出 114 段,共 622 条;留 244(AI 185 / 轮廓 59),淘汰 378(源图没边 39、被已留的线盖住 339)。线的尺:变号/100 px 中位 1.8,笔长中位 302 px@8x,链 186;按层 Line_Hair 119 笔 · Line_Dress 54 · Line_Body 44 · Line_Ribbon 16 · Line_Shoe 6 · Line_Face 5(变号 3.4,最抖)。三种提取器出的位图线稿(step02-lineart/ai/),只用 manga:
Manga2Anime 单线、细、眼睛线框、发丝分开;AnimeLineArt 粗、灰阶、眼内成块、两侧幻觉格子纹;LineartStandard 是边不是线。
补齐,一圈一圈的做法(step04-complete-legacy-wrong-1,输入 step03 的分割,seed 0,400 s;不过):
| 组 | 圈 | 遮挡区 px | 补出 px | 补出 / 可见 | 取回规则 |
|---|---|---|---|---|---|
| Hair_Back | 8 | 372,831 | 256,831 | 372% | 颜色规则(SAM 退化) |
| Skin | 7 | 260,685 | 163,001 | 145% | SAM person 减 hair shoes |
| Shoe | 0 | 253,743 | 0 | 0% | 第一圈就没取回,停 |
| Dress | 2 | 109,864 | 8,313 | 6% | SAM dress |
| Ribbon | 1 | 95,968 | 0 | 0% | SAM red bow |
| Hair_Front | — | 0 | 0 | 没有遮挡物,不补 |
叠回差异 0,但 layer_Hair_Back.png / layer_Skin.png 是黑白斑块,头发层还收进了裙子、腿、鞋。查过每一圈:给模型看的 solo 图里有一个黑色人形剪影(辉光参考图只从主体边往里填约 96 px,主体内 21% 是黑的),模型顺着黑剪影画黑裙子;SAM hair 对这种图把整个人框进来(前 7 圈每圈收 84–99%),颜色规则的对手是背景,任何比背景亮的都算头发;每圈换 seed 拼成斑块。这个做法留作对照。
See-through 实验(step04-complete-legacy-experiment-1,SIGGRAPH 2026 的分层模型,1280 画布,group offload,348 s):15 层——back hair 270,284 px@1x(一整头头发,含马尾和发带)、topwear 188,463(整条裙子)、legwear 96,760(两条腿,裙下的大腿补出来了)、front hair 36,340(只有刘海)、handwear 30,431、face 27,714(额头在刘海下补出来了)、footwear、neck、irides、eyewhite、eyelash、ears。它重新生成每一层:自己的叠回和源图比主体内 PSNR 18.4 dB(Dress 23.8、Skin 20.0、Hair_Back 16.3、Eye 14.4、Ribbon 10.9),手指、发丝、蕾丝丢,层边锯齿,丝带拆进头发和裙子。所以只供被遮住部分。
补齐,See-through 合并(step04-complete,dtp 0.5.0,复用实验那一步的层,合并 7 s;过):被遮 = 它的层 ∩ 上层区域 − 可见,可见钉死源图,边平滑、只留连通的、黑像素不收、按可见区重叠的均值差调色、接缝羽化。
| 组 | 来源 | 补出 px | 补出 / 可见 |
|---|---|---|---|
| Hair_Back | back hair | 203,988 | 295% |
| Skin | face + neck + handwear + legwear | 59,122 | 53% |
| Dress | topwear | 10,652 | 7% |
| Ribbon | 接缝 2 px | 1,056 | 8% |
| Eye | irides + eyewhite + eyelash | 360 | 17% |
| Shoe / Hair_Front | 没有东西压着 | 0 |
叠回差异 0。后发是一整头头发;皮肤层是头、手臂、腿,额头和脖子补在头发下,大腿补在裙下,裙下的躯干不编;裙子在手臂和头发下面补齐。Skin 单层胸口带几片肩带和荷叶边是 step03 分割的事(Dress_Bodice → Skin_Torso 1,904 px)。
每组单层:左 一圈一圈(legacy-wrong),右 See-through 合并(step04)(后发、皮肤、裙子、前发)。
补出来的像素是编的,账在 amodal.npz。
分层线稿(step05-lines,dtp 0.5.2,每层只给这一层 + 平底色,manga 提取器,85 s):297 笔,其中编出来区域里的 55(后发身后 39、裙子手臂下 14、眼 1)。每层:Hair_Back 轮廓 16 + AI 239 → 89 · Skin 4 + 192 → 41 · Eye 2 + 8 → 7 · Shoe 3 + 28 → 6 · Dress 10 + 150 → 65 · Ribbon 21 + 39 → 28 · Hair_Front 12 + 214 → 61。线的尺:变号中位 1.4 次/100 px,笔长中位约 290 px@8x。对照 step02(源图上的线):可见的 242 笔里 85% 落在源图线 4 px 内,源图线 244 笔里 96% 被盖住,差异在遮挡边界。第一次(step05-lines-legacy-wrong-1)solo 图带了辉光参考图,参考图深处的黑剪影让提取器把整个人的鬼影轮廓画进每层的线稿(留下的线没事,候选只在这一层的 mask 里取),306 笔、一致率 88% / 98%;改成平底之后数字在噪声内。错的和试验的 step 都挪成 legacy 目录,不占号。
底稿(step06-draft,dtp 1.0.0,第一个用 main.py 开的 step,Krita 52 s):7 组 / 40 节点 / 底色 1,335 笔 / 线 297(编出来区域里的 55);线稿层 Line_Hair · Line_Body · Line_Face · Line_Shoe · Line_Dress · Line_Ribbon。闸门:过(用户「ok」)。
上色(step07-paint-legacy-wrong-1,dtp 1.0.0,计划 51 s,Krita 364 s):每组的做法 Hair_Back generic · Skin tiers · Eye eye · Shoe generic · Dress generic · Ribbon generic · Hair_Front generic(两组头发的 hair 做法没启用:上一轮实验里它没赢过基线)。182,248 笔(sharp 141,110 · shade 20,366 · soft 11,991 · blend 7,164 · strand 1,174 · shadow 405 · deep 34 · light 4),落笔调用 185,822;线 297 → 141(外轮廓 49 · 粗 29 · 细 63 · 太淡不画 156);主体内 1x 模拟 PSNR 24.42 dB;树 57 节点。每组(笔数,1x 模拟 PSNR 前 → 后):Hair_Back 78,593(发丝 492)16.4 → 27.4 · Skin 14,364(档 39,468 px,残差 4,917,硬笔 9,085)14.1 → 23.4 · Eye 2,328 · Shoe 1,018 · Dress 15,002 · Ribbon 18,661 · Hair_Front 40,291(发丝 682);背景辉光 11,991 笔。
人的裁决:不过(用户 2026-09-10「画出来的内容很垃圾」)。看的是同位置对比 cmp/(源图 | 一次成型 | 先分层后上色):整张糊——十四万笔 1.5–3 px 的硬小笔加软笔在 1x 规划、4x 落笔,把源图的明暗复制了一遍,不是画;没有干净的阴影形状(只有皮肤那一档);头发是随机发丝加喷枪;荷叶边被几万个小圆点涂成斑驳的一片;眼眶那条线沿着 SAM 的 mask 走成一圈粗棕线;线只按够不够黑筛掉 156 笔,裙褶、发丝那些淡线全丢,留下的又粗又一样。前面的步骤(分层、补齐、每层的线)给出了结构,上色把结构扔了,回到抄像素。结论进了第 6 章:上色按部位、一部位一页、人在 PAINT 表里定画法。
step08-gauge-legacy-wrong-1/cmp/:左源图,中一次成型(shinku-hug-basic-1),右先分层后上色的基线「抄」。脸:眼眶的粗棕线、软的脖子;荷叶边:斑驳的小圆点。
判据(step08-gauge-legacy-wrong-1,归一到 2508 px,源图为锚):五项全过——落笔 183,583 / 写像素 2 · 梯度 p99 39.1(源图 41.6 的 94%)· 8 级色数 1,633(56%)· 阶梯 0.87(源图 6.19)· likeness 31.03 dB · 内部锐度 p90 5.8(头发 6.8;源图 10.5 / 8.4)· 最暗 (0,0,0)。五项全过、人判不过:五项管的是「像不像人画的」,管不了「是不是画」(第 6 章「审阅与改判」)。
| 组 | 像素 | 内部锐度 p90 | 源图 | 硬边处 p50 | 源图 | 1x PSNR |
|---|---|---|---|---|---|---|
| Hair_Back | 69,033 | 4.6 | 4.4 | 2.9 | 12.9 | 23.02 dB |
| Skin | 110,029 | 1.0 | 1.8 | 1.0 | 12.1 | 22.12 dB |
| Eye | 2,141 | 8.8 | 15.2 | 9.3 | 20.9 | 13.25 dB |
| Shoe | 6,942 | 2.9 | 2.9 | 3.2 | 6.6 | 17.81 dB |
| Dress | 143,879 | 2.7 | 6.4 | 1.7 | 18.8 | 22.40 dB |
| Ribbon | 13,896 | 11.5 | 20.9 | 6.3 | 32.2 | 18.69 dB |
| Hair_Front | 95,944 | 8.0 | 10.0 | 3.8 | 19.8 | 22.38 dB |
硬边处全组都远低于源图(裙子 1.7 对 18.8,丝带 6.3 对 32.2)——软笔抄不出硬边,这是「抄」的指纹。档的边(Shape 环两侧 2 px):Skin 阴影 15.5(源图 29.6)· Eye 虹膜 59.9(66.4)· 暗块 51.2(58.2)· 高光 76.4(57.7)——皮肤的档比源图软一半。图层树 57 节点:规则 ≤ 5 + 10 × 7 = 75 过,每组 ≤ 10 不过(Skin 14:Shape · Flat · Shade · Shadow 子组 3 · Blend · Line 加每个成员的 fill)。线的尺:141 笔 · 变号 2.0 / 100 px · 中位 325 px@8x · 链 117 · 编出来区域里的 11。
历史(v9.0.0,dtp 0.2.0,旧走法「先素描后上色」;work/origin/step23–39 已删):
| Criteria | 读数 |
|---|---|
| node | 57(通用做法 42;素描版 40) |
| 笔 / 落笔调用 / 写像素 | 216,470 / 300,051 / 2 |
| 梯度 p99 · 色数 · 阶梯 | 49.0(118%)· 2818(97%)· 0.90 |
| low-frequency likeness | 29.98 dB(通用做法 30.22) |
| 内部锐度 p90 | 6.2(头发 7.1;通用 6.6 / 7.1) |
| 每组 内部 / 硬边处 / 1x PSNR | Skin 1.1 / 1.2 / 20.18 · Eye 8.6 / 9.1 / 14.82 · Hair_Front 8.3 / 4.1 / 21.49 · Hair_Back 4.9 / 3.1 / 22.10 · Dress 2.7 / 1.9 / 22.29 |
| the band edges | Skin 阴影 38.3(源图 29.7)· Eye 虹膜 / 暗块 / 高光 61 / 49 / 79(源图 66 / 58 / 58);眼高光团 3(源图 3,通用 0) |
| lines | 232 笔 · 变号 2.2/100 px · 中位 298 px@8x · 158 链(素描版 350 条,成品按浓淡去掉太淡的);候选 轮廓 95 + AI 400 → 293 → 175 |
| Flat colour | 1,437 笔(这一版还在用笔扫满;换地基后是 0 笔,见下一节) |
| 补齐 | Hair_Back 8 圈 +253,695 px(可见的 363%)· Skin 8 圈 +260,745(246%)· Dress 2 圈 +8,310(6%)· Ribbon 2 圈 +1,811 · Shoe 0 · Hair_Front 无遮挡;叠回差异 0 |
| 固有色 | 头发 (253,224,136) · 眼白 (248,245,244) · 皮肤 (253,241,227) · 裙 (251,251,253) · 丝带三簇 (243,82,138) / (176,6,78) / (249,244,250) · 鞋 (248,246,253) |
| time | segment 34 s · lineart 35 s · complete 424 s · sketch 75 s · paint 585 s(Krita 422 s) |
换地基:一串笔 → 一棵图层树(shinnku-hug-pro/step06-draft + step07-paint,dtp 2.0.0,4x)
同一份输入(step03-segment / step04-complete / step06-draft 的计划一字未改),只换了「画」这件事的表达方式和落笔的路。画法没动——这一轮量的是地基,不是画法。
这一版的笔是什么(重构前的 66,823 笔):笔长不足五个笔半径的 60,926 笔(91.2%)——那是点不是笔;真正顺着形体走的一笔(发丝 + 缕缝)136 笔(0.20%);在「把一块区域填满」的扫线 13,304 笔(19.9%),底稿那 1,341 笔是 100%。矢量层已经填对的形状被笔盖到只剩 < 2.5% 可见。
三条走法换成一个落笔作业之后(probes/probe_bake_equiv.py 按层逐笔对账;同一棵树连跑两遍的噪声底是 54.51 dB):
| node | 逐层逐笔相同 | final.png | |
|---|---|---|---|
| 底稿 step06 | 41 = 41 | 1341 / 1341 = 100% | 46.64 dB |
| 上色 step07 | 65 = 65 | 66869 / 68164 = 98.10% | 43.79 dB |
| 一次成型 basic-1 step02 | 317 = 317 | 80695 / 80695 = 100% | 54.20 dB |
type/clip/blend/opacity/visible 三条走法各 0 处不一致,作画日志的 by_op 计数相同。上色那 1.90% 是一处修好的 bug:老作业只在笔种变了时才换 preset,于是「这一笔用软笔」(soft)只有恰好落在某个笔种连续段第一笔时才生效——1,295 笔平涂带着这个标记却被当硬圆头画了。
换完地基之后(每一列都是当次跑出来的 step):
| 阶段 3(等价重跑) | 阶段 4(填色不用笔) | 阶段 5(色场 + 模糊蒙版) | |
|---|---|---|---|
| 图层树节点 | 64 | 51 | 51 |
| Brushes | 68,316 | 62,998 | 50,855 |
| description numbers | 780,588 = 16.54% | 718,531 = 15.23% | 595,228 = 12.61% |
| bare pixel writes | — | — | 0 |
| 梯度 p99(源图 41.6) | — | 42.1(101%) | 41.7(100%) |
| 8 级色数(源图 2900) | — | 2043(70%) | 2029(70%) |
| low-frequency likeness | — | 28.62 dB | 28.80 dB |
| 内部锐度 p90(源图 10.5 / 头发 8.4) | — | 5.7 / 9.2 | 5.4 / 7.6 |
| Krita 落笔 | 264.6 s | 180.2 s | 282.8 s |
| 底稿 step06 | 40 节点 / 1,578 笔 / 1.51% | 25 / 237 / 1.20% | 同左 |
阶段 4 删掉档内平涂之后档的边比源图还硬(Hair_Back 的几档:源图 16.8 / 成品 28.8,源图 15.5 / 27.7),头发内部锐度 8.0 → 9.2 越过源图的 8.4——那些笔在偷偷干的事是把边揉软。阶段 5 给档组挂一个高斯模糊 FilterMask 补回来:档边 28.8 → 15.8(源图 16.8),头发内部 9.2 → 7.6。
背景(这一轮省得最狠的一处):
| The method | description numbers | 占源图 | the background area against the source |
|---|---|---|---|
| 平涂三遍 + 一遍 soft(11,991 笔) | 127,919 | 2.71% | 34.33 dB |
| 16×24 的色场 | 1,152 | 0.02% | 34.39 dB |
| 32×48 的色场(采用) | 4,608 | 0.10% | 37.09 dB |
| 128×192 的色场 | 73,728 | 1.56% | 39.92 dB |
剩下的 12.61% 在哪(这就是下一步要动的地方):
| node | description numbers | 占全图 |
|---|---|---|
Ribbon_Shade | 199,377 | 33.5% |
Dress_Shade | 152,499 | 25.6% |
Skin_Shade | 88,124 | 14.8% |
Skin_Blend | 45,949 | 7.7% |
Eye_Blend | 21,731 | 3.7% |
| 头发两组合计 | 49,335 | 8.3% |
前五项全是基线「抄」的软笔逐点补差。判据现在直接指着它们说「这里在用点重编码源图」——以前这件事没有数字,只有人看了说不像画。
ir/render.py 不开 Krita 画出来的 1x 预览对真成品 30.32 dB,比老的「一串笔」1x 模拟(29.34 dB)还准;老模拟填的是 amodal 掩码而不是矢量形状,所以它一直和 Krita 画的不是同一张。
头发在新地基上重做(shinnku-hug-pro/step07-paint,dtp 2.1.0,4x)
只改了头发的画法,别的组一字未动。换掉的是「底」是什么:以前一缕是一个固有色加几档量化出来的硬边影,现在一缕是一根圆柱、两条渐变(顺轴绝对色 + 横切乗算)。
| 一缕几个平色 | 一缕一根圆柱 | |
|---|---|---|
| 两组头发的描述数 | 49,335(全图的 8.3%) | 26,319(4.6%) |
| 头发的笔 | 约 5,300 | 210 |
| 头发区残差(对源图,1x,越小越像) | 17.43 | 13.05 |
| 明显偏粉的像素(源图 56.4%) | 34.3% | 53.7% |
| 组内 8 级色数(源图 123) | 11 | 101 |
| 全图描述数 | 12.61% | 12.04% |
| Krita 落笔 | 180 s | 206 s |
为什么定在「一缕一根圆柱」。几种底色的表达都量过(92 缕,只算颜色的数,不含轮廓):
| 底色怎么写 | description numbers | 残差 |
|---|---|---|
| 每组一个固有色 | 6 | 20.58 |
| 每缕一个固有色 | 138 | 17.49 |
| 每组一条线性渐变 | 56 | 18.34 |
| 每缕横切一条渐变(5 stop) | 2,208 | 13.01 |
| 每缕横切 + 顺轴两条 | 4,416 | 11.56 |
| 每缕切 4 条带 + 模糊 | 色 1,101 + 多三圈轮廓 | 12.92 |
条带比渐变贵三倍:每多一档就多一圈轮廓(一缕的轮廓约 100 个数),而渐变把整个剖面压进二十个数。
平滑模型的地板在 12 附近:把源图自己按 σ=8 模糊,残差也只有 12.07;每缕拟一个二维三次曲面(30 个数一缕)是 11.92。所以每缕两条渐变(11.56)已经贴到地板,剩下的差额是发丝那层细纹理——那是几十根笔的活。误差驱动的残差笔(一组三四百笔)因此删掉。
缕数不是越多越好(同样两条渐变):
| 分缕 | 缕 | 轮廓 + 渐变 | 残差 |
|---|---|---|---|
| 粗 | 46 | 8,632 | 12.91 |
| 中 | 67 | 10,868 | 12.03 |
| 细 | 92 | 13,128 | 11.56 |
还剩两处。一是分缕在细缕密排的地方把几条真发缕并成一条,横切一平均就全成了一个颜色;参数扫过,残差只小幅改善。二是上游:分割那一步的 subject 掩膜在左侧有洞,丢掉的发丝约相当于头发面积的 15%,画法只能画掩膜说有头发的地方。
两条走法并排
同一张图、同一份判据(step08-gauge-legacy-wrong-1 的 REF_FINAL 指向 shinku-hug-basic-1/phase3-paint/step02-trace/krita/final.png,同位置对比 cmp/ 13 张):
| Criteria | 一次成型(basic-1 step02-trace) | 先分层后上色(pro step07-paint-legacy-wrong-1,基线「抄」) |
|---|---|---|
| gradient p99 | 37.7(91%) | 39.1(94%) |
| 8 级色数 | 1,877(65%) | 1,633(56%) |
| 阶梯指纹 | 0.81 | 0.87 |
| low-frequency likeness | 34.79 dB | 31.03 dB |
| 内部锐度 p90 | 9.5(头发 10.8) | 5.8(头发 6.8) |
| Layers | 15 个部件组 + 73 个档,档没有名字 | 7 组 57 节点,档有名字(Skin_Shadow、Eye 四样),每层完整 |
| 人的裁决 | 过(这条走法的固有限制:脖子归头发、裙下腿断、档没名字) | 不过:抄像素 |
像的那条图层不是人要的;图层是人要的那条,上色是抄的——两边差的都是「画法」:一次成型没有画法(按亮度切档往上堆点),先分层后上色的基线也没有(软笔复刻)。出路是第 6 章:一部位一个画法,人定。
左源图,中一次成型,右先分层后上色的基线。腿:一次成型的裙下腿是断的、这条路是完整的(补齐),但两边的皮肤都没有画师要的那一档影。
历史(旧走法先素描后上色,v6-* 图):一次成型 34.8 / 9.5(头发 11.0)vs 先素描后上色 29.98 / 6.2(7.1)。
v9 的三个部件实验(历史,v9.0.0;step 目录已删)
第 6 章的三个做法是在这张图上做出来的;变体表留在这里。
皮肤(基线通用做法;Skin 内部 p90 源图 1.5,硬边处 8.3,档的边 30.0):
| 变体 | 内部 p90 | 硬边处 | 1x PSNR | the band edges | 全图 likeness |
|---|---|---|---|---|---|
| A 通用 | 1.3 | 2.7 | 21.35 | 31.3 | 30.40 |
| B 只有档 | 0.0 | 0.5 | 19.99 | 37.7 | 29.85 |
| C 档 + 残差(沉库) | 1.0 | 1.3 | 21.11 | 33.0 | 30.30 |
眼睛(源图:内部 15.0,硬边处 21.6,虹膜 / 暗块 / 高光边 66 / 58 / 58,高光团 3):
| 变体 | 内部 p90 | 硬边处 | 1x PSNR | 三条边 | 高光团 |
|---|---|---|---|---|---|
| 通用 | 11.8 | 8.3 | 15.33 | 58 / 46 / 60 | 0 |
| E1 四样、没有残差(赛璐璐眼) | 28.9 | 3.8 | 14.00 | 74 / 56 / 84 | 3 |
| E2 四样 + 残差 | 8.7 | 8.1 | 15.35 | 56 / 43 / 51 | 0 |
| E2′ 残差避开高光 5 px(沉库) | 8.6 | 9.1 | 14.82 | 61 / 49 / 79 | 3 |
头发(源图头发内部 8.4;Hair_Front 内部 / 硬边处 10.1 / 19.8,Hair_Back 4.4 / 12.9):
| 变体 | 头发内部 p90 | Hair_Front | Hair_Back | 1x PSNR 前 / 后 | likeness | Brushes |
|---|---|---|---|---|---|---|
| 通用 | 7.1 | 8.4 / 4.0 | 4.9 / 3.2 | 21.48 / 22.10 | 30.22 | 219k |
| H2 缕 + 定向发丝,去掉硬笔 | 10.8 | 12.7 / 3.4 | 6.2 / 1.7 | 19.41 / 20.22 | 29.06 | 100k |
| H2s = H2 + 硬笔 | 10.0 | 12.0 / 4.2 | 6.0 / 3.0 | 20.79 / 21.29 | 29.91 | 220k |
| H2s 高光带更淡更少 | 10.0 | 12.0 / 4.2 | 6.0 / 3.0 | 20.79 / 21.29 | 29.91 | 220k |
1x 模拟上头发的 PSNR:通用 27.3 / 25.3,去掉硬笔 23.6 / 21.6,加回 28.0 / 26.2——模拟和 Krita 反着来(第 6 章)。
历史图(v9):皮肤一档阴影的脖影特写;眼睛四样;顶帽亮脊聚出来的缕。
这一章的图
assets/ 里 v10-* 来自 shinku-hug-basic-1,v11-* 来自 shinnku-hug-pro,v13-* 是 shinnku-hug-pro/phase3-paint/step08-gauge-legacy-wrong-1/cmp/ 的同位置对比(脸、腿、荷叶边缩了一半);v6-*、v7-*、v9-* 是历史版本的审阅图,对应的 step 目录已删,留着看形状不看数字。