纤细或经典:24个像素决定一切,究竟是哪些像素?
如果 (46,20)–(47,31) 区域的 24 个像素中,不透明像素少于 6 个,则皮肤为纤细型。本文还将详细介绍完整的 UV 贴图、为何旧版 64×32 皮肤会被镜像,以及为何基岩版 (Bedrock) 的 128×128 皮肤无法在 Java 版中加载。
皮肤 PNG 文件中没有任何地方明确写着“纤细”。没有标记、没有元数据,也没有文件名约定——模型是通过图像本身推断出来的,具体方法是查看一个特定的 2 × 12 矩形,并计算其中实际有多少像素。
检测方法
sample x 46–47, y 20–31 — 2 wide, 12 tall = 24 pixels
count pixels with alpha > 0
slim if fewer than 6 are opaque
经典手臂宽 4 像素;纤细手臂宽 3 像素。因此,纤细皮肤会使第四列手臂像素为空,而这一列正是采样区域所在的位置。24 个像素决定了你的角色模型。
阈值是24 个像素中的 6 个,而不是 1 个——必须填充四分之一的列才算作经典。这种容差很重要:即使纤细皮肤在空白列中有几个流浪者 (Stray) 像素,它仍然会被识别为纤细,这是你想要的结果,因为这些流浪者像素几乎总是编辑失误而非有意为之。
这也意味着失败模式是“静默”的。如果你绘制了一个经典皮肤,但只轻微使用了第四列——例如细线轮廓,或几个阴影像素——你可能会低于 6 个像素的阈值,并被自动检测为纤细,从而失去一个像素的手臂宽度,却没有任何解释。如果皮肤模型不正确,就应该检查这一列。
完整的 UV 贴图
皮肤的每个部分都是一个固定的矩形,并且每个部分在贴图上的其他位置都有一个叠加层:
| 部位 | 基础 | 叠加层 | 偏移 | 大小 |
|---|---|---|---|---|
| 头部 | (8, 8) | 帽子 (40, 8) | 向右 32 | 8 × 8 |
| 身体 | (20, 20) | 夹克 (20, 36) | 向下 16 | 8 × 12 |
| 右臂 | (44, 20) | 袖子 (44, 36) | 向下 16 | 4 × 12 |
| 右腿 | (4, 20) | 裤子 (4, 36) | 向下 16 | 4 × 12 |
| 左臂 | (36, 52) | 袖子 (52, 52) | 向右 16 | 4 × 12 |
| 左腿 | (20, 52) | 裤子 (4, 52) | 向左 16 | 4 × 12 |
六个叠加层中的五个与其基础部分相距 16 像素——但方向不同。 最初的三个部分向下偏移 16 像素。左臂和左腿是后来添加的,被挤压到下半部分,下方没有空间,因此它们改为横向偏移 16 像素——而且方向彼此相反。
帽子是唯一一个不偏移 16 像素的:它在与头部相同的行上,向右偏移 32 像素。
所以“叠加层在基础层下方”这个规则只适用于贴图的一半。复制一个基础矩形并向下偏移以找到其叠加层,这种方法适用于身体、右臂和右腿,但对于其他三个部分则会悄无声息地定位到错误的位置。
在纤细皮肤上,每个 4 像素宽的手臂矩形都会被读取为3 像素宽。矩形本身不会移动;只有从中读取的宽度会改变。
旧版 64 × 32 皮肤完全没有左侧
1.8 版本之前的皮肤是 64 × 32——贴图的下半部分根本不存在,而左臂和左腿就位于那里。没有可供绘制它们的数据。
解决方法是镜像:右腿 (0, 16) 被复制到 (16, 48),右臂 (40, 16) 被复制到 (32, 48),两者都水平翻转。这就是为什么旧皮肤是完全对称的,而现代皮肤则不必如此——不对称是 64 × 32 格式无法表达的唯一特性,任何你转换的旧皮肤都会被强制对称,无论它是否愿意。
基岩版 (Bedrock) 的 128 × 128 是一种不同的格式,而非更大的格式
Java 版接受 64 × 64 或旧版 64 × 32。基岩版 (Bedrock) 接受 128 × 128,别无其他。两个版本的查看器都无法显示对方的文件——这不是一个可缩放的分辨率差异,而是一种不同尺寸下的不同 UV 布局。
这是一道硬性障碍,而非不便。Java 皮肤不会“升级”到基岩版 (Bedrock),而加载到 Java 查看器中的基岩版 (Bedrock) 皮肤也不会以一半大小渲染——它会被拒绝。本页面的编辑器正是因为这个原因将两者视为独立的构建。