09 · 2D 技术美术专项
大量独立游戏是 2D 的,而 2D 的技术美术问题和 3D 完全不同,却常被忽略。
本文件覆盖:像素完美、图集、2D 光照、2D 动画、2D shader、性能。
1. 像素完美(Pixel Perfect)—— 像素游戏的第一红线
核心参数
| 项 |
设置 |
| PPU(Pixels Per Unit) |
全项目统一(常见 16 / 32 / 100) |
| 参考分辨率 |
如 384×216 / 640×360 / 320×180(16:9) |
| 相机 |
正交(Orthographic),Size = 参考高度 / 2 / PPU |
| 缩放 |
整数倍缩放(1×/2×/3×),非整数会撕裂像素 |
| 过滤器 |
Point (no filter),绝不 Bilinear |
| Mipmap |
关闭(像素图不需要) |
| 压缩 |
像素图用无压缩或无损(有压缩会糊边缘) |
| 抗锯齿 |
关闭(后处理 AA 会毁掉像素风) |
| 精灵 Pivot |
统一(底部中心 / 中心) |
| 位置 |
对齐到像素网格(脚本吸附) |
整数缩放实现
逻辑分辨率 = 参考分辨率(如 640×360)
scale = floor(屏幕高度 / 参考高度) // 2, 3, 4...
实际渲染分辨率 = 参考分辨率 × scale,居中显示,两侧留黑边或用背景填充
常见坑:
- 相机 Size 算错 → 像素尺寸不一致
- 用了非整数缩放 → 部分像素 1.5 倍宽,出现"摩尔纹"
- 开了 mipmap + 相机缩放 → 远处像素图变糊
- UI 与游戏用不同 PPU → 比例错乱
非像素的 2D(手绘高清)
| 项 |
设置 |
| 过滤器 |
Bilinear(可接受) |
| Mipmap |
开(如果会缩放) |
| 抗锯齿 |
可开(但如果追求手绘锐利感,用 SMAA 而非 TAA) |
| 压缩 |
BC7 / ASTC |
| 分辨率 |
按屏幕 1:1 设计,为 2× 屏准备 2× 资源(或用矢量/高清源导出) |
2. 图集(Atlas)策略
为什么要图集
- 减少 DrawCall(同图集同材质可合批)
- 减少内存碎片
- 加快加载
图集规划原则
| 原则 |
说明 |
| 按使用场景分图集 |
同一屏出现的东西放一个图集(角色/敌人/UI/场景A/场景B) |
| 不要全塞一张 |
会导致不相关的场景也加载整张图集(内存浪费) |
| 尺寸上限 |
2048(移动端)/ 4096(PC);超过就分多张 |
| 留白与 padding |
2–4px padding 防止 mip 时渗色(像素图用 extrude 更好) |
| 动态/静态分开 |
频繁变动的单独放 |
| UI 单独 |
UI 图集与游戏图集分开 |
| 特效 Flipbook 单独 |
通常数量多、尺寸大 |
图集变体(Variant)
- 多分辨率变体:1× / 2× 图集,按设备选
- Palette 变体:同一图集不同调色板(换色敌人)
- 语言变体:含文字的图集按语言分
图集检查
| 检查 |
说明 |
| 填充率 |
> 80% 为佳(太低说明分得太碎) |
| 是否有跨图集引用 |
一个动画引用 3 张图集 → 无法合批,要重排 |
| 是否有未使用精灵 |
清理 |
| 运行时是否在内存里常驻了不该常驻的图集 |
检查 |
3. 2D 光照与材质
方案选择
| 方案 |
成本 |
效果 |
适用 |
| 无光照(纯贴图) |
0 |
平 |
像素风、扁平风 |
| 法线贴图 + 2D 光照 |
中 |
立体、有光 |
主流 2D 高级做法 |
| 手绘阴影贴图 |
低(美术成本高) |
风格化 |
手绘风 |
| 遮罩光照(区域遮罩) |
低 |
分区明暗 |
简单氛围 |
| SDF/距离场光照 |
中 |
软阴影 |
高级 |
| 屏幕空间光照 |
中高 |
动态 |
谨慎 |
2D 法线贴图要点
- 法线贴图需要额外绘制(美术成本),或用工具从高度图生成
- 法线贴图不勾 sRGB
- 光源必须是 2D 光源(或 3D 光打在平面上)
- 法线强度:2D 的法线通常比 3D 更强(0.8–1.5)才有立体感
- 性能:2D 光照是逐像素的,屏幕上有多少 2D 光 = 多少倍填充开销
- 预算:同屏 2D 光 ≤ 4(Low)/ ≤ 8(Mid)
- 优先烘焙到贴图,只在动态处用实时光
2D 阴影
| 方式 |
成本 |
说明 |
| 手绘阴影 sprite |
低 |
最可控 |
| Blob shadow(椭圆投影) |
极低 |
性价比最高,一个圆片搞定 |
| 法线光照产生的阴影 |
中 |
需 shadow caster |
| 遮罩阴影 |
低 |
区域变暗 |
4. 2D 动画技术
| 方式 |
资产量 |
表现力 |
适用 |
| 逐帧 |
极高 |
最高 |
手绘风、Cuphead 类 |
| 骨骼动画(Spine/DragonBones/Unity 2D Animation) |
低 |
中高 |
主流 |
| 网格变形 |
中 |
高 |
柔体感 |
| 切图+变换 |
极低 |
低 |
UI、简单物件 |
| 程序化 |
低 |
中 |
简单生物 |
骨骼动画要点
- 骨骼数预算:20–40(2D 比 3D 少)
- 网格绑定(Mesh)比切图绑定表现力好很多(能做形变)
- IK:2D 的脚部 IK 很好用
- 换装:分层精灵 + 同骨骼
- 权重:2D 的权重通常硬边(1 或 0)就够,不需要柔和过渡
2D 动画资产量控制
一个角色:
逐帧: 12 动作 × 12 帧 × 2 方向 = 288 张
骨骼: 12 条动画 = 12 个数据文件(可复用、可镜像、可混合)
独立游戏建议:骨骼为主 + 关键动作(大招/死亡)补逐帧。
5. 2D Shader 技法库
| 技法 |
用途 |
成本 |
说明 |
| 闪白 |
受击 |
极低 |
用一个 _Flash 参数 lerp 到白色 |
| 溶解 |
死亡/出现 |
极低 |
噪声纹理 + clip/alpha |
| 描边 |
风格/可读性 |
低 |
采样周围 alpha 求边缘;或预烘焙描边 |
| Palette Swap |
变体/受击/中毒 |
极低 |
用索引色 + 查表 LUT |
| 色板循环 |
水/火焰/能量流动 |
极低 |
UV 偏移在色板上循环 |
| 抖动 Dither |
复古/渐变 |
极低 |
Bayer 矩阵 |
| 水/折射 |
水面 |
中 |
屏幕空间 UV 扰动 |
| 视差层 |
景深 |
低 |
多层按不同速度移动 |
| 剪影遮罩 |
被遮挡的玩家 |
低 |
深度/层判断后输出纯色 |
| 轮廓高亮 |
可交互提示 |
低 |
外扩描边 + 呼吸 |
| CRT/扫描线 |
复古 |
低 |
后处理 |
| 2D 阴影投影 |
立体 |
低 |
精灵投影矩阵 |
| 液态/果冻 |
程序化形变 |
低 |
顶点位移 or UV 扰动 |
| 粒子遮罩 |
特效 |
低 |
精灵作为遮罩 |
Palette Swap(调色板替换)—— 独立游戏神器
原理:精灵用索引色(每个像素存的是色板索引,不是颜色),渲染时查当前色板纹理。
1 张精灵 + N 张色板 = N 个视觉变体(敌人变体、季节、中毒/燃烧状态)
成本:几乎为零;调换色板是 1 次纹理切换
适用:像素风、复古风。做敌人变体和状态变化的最佳手段。
6. 2D 视差与相机
| 层 |
速度系数 |
内容 |
| 远景 |
0.1–0.2 |
天空、远山 |
| 中远景 |
0.3–0.5 |
建筑、树林 |
| 中景 |
0.6–0.8 |
背景装饰 |
| 主层 |
1.0 |
玩法层 |
| 前景 |
1.2–1.5 |
遮挡、氛围 |
要点:
- 视差层用相机位移驱动,不要用脚本每帧移动物体(会抖动)
- 前景层可加轻微模糊 + 降饱和,增强景深
- 视差层数:3–5 层足够(超过收益递减且成本高)
7. 2D 性能要点
| 问题 |
症状 |
解法 |
| DrawCall 高 |
|
图集 + 同材质合批;排序层不要频繁切换 |
| Overdraw 高 |
半透明精灵堆叠 |
减少全屏半透明;精灵挖空透明区 |
| 2D 光照贵 |
多光源掉帧 |
光源数预算;烘焙 |
| 精灵太多 |
内存 |
图集 + 清理未使用 |
| 骨骼动画 CPU |
|
减少骨骼;用 GPU 或烘焙 |
| 像素图被压缩 |
糊 |
像素图用无损/无压缩 |
| 精灵排序闪烁 |
z-fighting |
用 Sorting Layer + Order,不要用 Z 坐标 |
| 大图集常驻 |
内存高 |
按场景分图集,动态加载 |
2D DrawCall 预算:< 100(Low)/ < 300(Mid)(2D 通常比 3D 低)
8. 常见 2D 坑
| 坑 |
表现 |
解法 |
| PPU 不统一 |
元素大小比例错 |
全项目统一 PPU |
| 非整数缩放 |
像素撕裂 |
整数缩放 + 黑边 |
| 开了 mipmap 的像素图 |
远看糊 |
关 mipmap |
| Bilinear 过滤像素图 |
糊 |
Point 过滤 |
| 精灵 pivot 混乱 |
旋转/缩放错位 |
统一 pivot |
| Sorting Layer 混乱 |
穿插闪烁 |
明确层级表 |
| 图集跨引用 |
DrawCall 高 |
按场景重排图集 |
| 2D 光太多 |
掉帧 |
预算 + 烘焙 |
| 像素风开了抗锯齿 |
糊 |
关 AA |
| 手绘高清开了 Point 过滤 |
锯齿 |
改 Bilinear |
| 纹理压缩像素图 |
边缘脏 |
无压缩/无损 |
| 逻辑坐标与渲染坐标不一致 |
抖动 |
相机移动用整数像素对齐 |
9. 2D 分层结构建议
Sorting Layers(从后到前):
0 Background 天空/远景
1 FarParallax 视差远景
2 MidParallax 视差中景
3 GroundBack 地面装饰
4 Entities 敌人/NPC
5 Player 玩家
6 GroundFront 地面前景
7 Effects 特效
8 Foreground 前景遮挡
9 UI 屏幕 UI
每个角色/物件明确归属一个层,不要动态切层。
10. 自检清单
- PPU 统一了吗?参考分辨率定了吗?
- (像素风)整数缩放实现了吗?Point 过滤?关了 mipmap 和 AA?
- 图集按场景分了吗?填充率 > 80% 吗?有跨图集引用吗?
- Sorting Layer 表定了吗?有动态切层吗?
- 2D 光源数量在预算内吗?能烘焙的烘焙了吗?
- 动画方式(逐帧/骨骼)与预算匹配吗?
- Palette Swap 用上了吗?(变体/状态)
- DrawCall / Overdraw 多少?
- 真机测过吗?(尤其是移动端 2D 光照)
- 关掉所有特效和光照,画面还成立吗?
- 招牌技术在 2D 版本里是什么?
11. 一句话总结
2D 的技术美术核心是**"别让便宜的东西变贵"**。
像素游戏最贵的错误是"开了抗锯齿";手绘游戏最贵的错误是"用了 Point 过滤"。
而 Palette Swap 和图集,是 2D 独立游戏最该掌握的两个省钱技术。