在 Unity 项目中设置、诊断和修复像素完美 2D 渲染。
⚠️ 存在两种完全独立的实现
Unity 中的像素完美渲染并非一个系统——它是两种独立、不兼容的实现,每种渲染管线各一种。在编写或诊断任何代码前,务必先检测渲染管线。
| URP | 内置渲染管线 | |
|---|---|---|
| 组件 | UnityEngine.Rendering.Universal.PixelPerfectCamera | UnityEngine.U2D.PixelPerfectCamera |
| 包 | 内置于 URP — 无需额外安装 | com.unity.2d.pixel-perfect v6.0.0+ |
| API 风格 | 枚举(gridSnapping、cropFrame) | 布尔值(pixelSnapping、upscaleRT、cropFrameX/Y) |
不要在 URP 项目中安装 com.unity.2d.pixel-perfect。
→ 始终先调用 DetectPipeline()(references/pipeline-detection.cs),然后根据结果分支执行设置、诊断和修复。
何时不应使用此技能
- HD 2D 或高分辨率 2D 游戏 — 像素捕捉和点过滤会使平滑的艺术效果失真
- 仅 UI 场景 — 应使用 Canvas Scaler
- HDRP 项目 — 不支持像素完美相机
关键提醒
⚠️ 首先检测渲染管线 — URP 和内置渲染管线使用不同的像素完美相机组件,两者不可互换。 ⚠️ 过滤模式 = 点采样是头号修复方法 — 双线性过滤是 Unity 的默认设置,几乎总是导致精灵模糊的原因。 ⚠️ 必须禁用抗锯齿 — 在质量设置和相机上均需禁用。抗锯齿会主动模糊像素边缘。
核心原则
1. 管线检测与相机组件选择
请参阅本文档顶部的双路径对比表。程序集名称说明:独立内置包安装到 Runtime/ 文件夹,但 asmdef 的 "name" 字段为 Unity.2D.PixelPerfect — 无 Runtime 后缀。HDRP 不受支持 — 请参见常见问题下的 HDRP 回退部分。
→ 代码:references/pipeline-detection.cs — DetectPipeline()、GetPixelPerfectCameraType() 和迁移不匹配检查。
2. 诊断优先方法
在进行更改之前始终先进行诊断。报告发现,然后仅修复损坏的部分。
3. 在正确的范围内工作
默认以场景为范围。仅在用户明确要求时才进行项目范围的扫描。
诊断检查清单
精灵导入设置:
- 所有作用域内精灵的过滤模式 =
Point (no filter) - 禁用 Mip 贴图
- 压缩 =
None/ 未压缩 - 场景中所有精灵的 PPU 一致
- 精灵枢轴设置为自定义/像素模式 — 奇数尺寸精灵(例如 15×15)的中心枢轴落在 7.5px 处,导致 0.5px 偏移
→ 代码:references/sprite-settings.cs — GetImporter() 和 FixSpriteImportSettings()。
编辑器捕捉设置:
- 所有轴上的网格大小 =
1 / assetsPPU(例如 PPU 16 → 0.0625,PPU 100 → 0.01) - 在网格和捕捉叠加层中启用网格捕捉
- 要捕捉现有游戏对象:选择它们 → 对齐选中项 → 所有轴
相机设置:
- 相机投影 = 正交
- 像素完美相机组件存在且为管线对应的正确类型
-
allowHDR、allowMSAA、allowDynamicResolution均为false - 场景视图在相机 Gizmo 上显示两个绿色边框 — 实线 = 可见区域,虚线 = 参考分辨率
→ 代码:references/camera-setup-urp.cs — 完整的 URP 相机 + 像素完美相机配置。
→ 代码:references/camera-setup-builtin.cs — 内置独立配置。
项目质量设置:
- 质量设置中的抗锯齿 = 0
- 各向异性过滤 = 禁用
API 参考
完整的属性/方法表、GridSnapping 和 CropFrame 枚举值以及推荐配置:
→ references/api-reference.md — 在编写或审查相机设置代码时阅读此文件。
快速枚举摘要:
GridSnapping:None · PixelSnapping(标准)· UpscaleRenderTexture(真实低分辨率;与后处理和 UI 文本不兼容)
CropFrame:None · Pillarbox · Letterbox · Windowbox(最安全的默认值)· StretchFill
参考分辨率
在构建任何资源之前选择。资产生产开始后切勿更改。
| 参考分辨率 | 1080p | 1440p | 4K |
|---|---|---|---|
| 320 × 180 | 6× | 8× | 12× |
| 480 × 270 | 4× | ~5.3× | 8× |
| 640 × 360 | 3× | 4× | 6× |
320×180 是最安全的通用选择。对于没有整数倍适配的屏幕(例如 1366×768),使用 cropFrame = Windowbox 添加黑边,而不是拉伸到分数缩放。
迁移与兼容性
URP 项目中使用了内置独立组件
症状:DetectPipeline() 返回 URP,但相机拥有 UnityEngine.U2D.PixelPerfectCamera。症状可能不明显,因为独立组件包含 ENABLE_URP 条件代码。
修复:
- 从包管理器中移除
com.unity.2d.pixel-perfect - 从每个相机上移除
UnityEngine.U2D.PixelPerfectCamera - 添加
UnityEngine.Rendering.Universal.PixelPerfectCamera - 重新配置 — 布尔值(
pixelSnapping、upscaleRT、cropFrameX/Y)变为枚举(gridSnapping、cropFrame)
→ 检测代码:references/pipeline-detection.cs(文件底部)。
旧 URP 命名空间(Unity 2022 之前 / URP pre-13.x)
症状:编译器错误引用 UnityEngine.Experimental.Rendering.Universal。
修复:将 using UnityEngine.Experimental.Rendering.Universal; 替换为 using UnityEngine.Rendering.Universal;。更新任何程序集限定的类型字符串。[MovedFrom] 属性自动处理序列化 — 游戏对象上的组件在升级后仍然保留。
常见问题与解决方案
精灵模糊
修复:将所有作用域内精灵的过滤模式设置为点采样,禁用 Mip 贴图,在质量设置中禁用抗锯齿。
→ 代码:references/sprite-settings.cs
瓦片地图之间存在间隙
按顺序处理 — 像负单元格间隙或 PPU = 31.99 这样的变通方法会在相机移动时失效。
| # | 检查项 | 修复 |
|---|---|---|
| 1 | 精灵图集是否关闭了紧密打包,内边距 ≥ 4,并且启用了精灵打包器模式? | 在编辑器设置中启用精灵打包器模式;在图集上设置内边距 ≥ 4 并关闭紧密打包 |
| 2 | 瓦片集纹理和图集上的 Mip 贴图是否禁用? | 禁用生成 Mip 贴图 |
| 3 | 抗锯齿 = 0,相机关闭 MSAA? | 全局禁用抗锯齿 |
| 4 | 压缩 = None? | RGBA 32 位未压缩 |
| 5 | 所有瓦片精灵是否为偶数像素尺寸? | 奇数尺寸会导致 0.5px 网格偏移 |
| 6 | PPU 是否等于瓦片像素宽度?(16×16 → PPU 16) | PPU 不匹配会留下物理间隙 |
| 7 | 以上所有检查通过后,仅在相机移动时出现间隙? | 使用像素完美相机像素捕捉;不要使用 cellGap = -0.01f |
Cinemachine 冲突
原因:Cinemachine 和像素完美相机每帧都会写入正交大小。
修复:通过每个虚拟相机的添加扩展下拉菜单添加 CinemachinePixelPerfect 扩展。不要通过 AddComponent 在代码中添加。
已知限制:
- 虚拟相机之间的相机混合在过渡期间不是像素完美的
UpscaleRenderTexture会减少有效的像素完美正交尺寸,可能导致画面偏离- 目标组 + 取景变换器会导致明显的卡顿(无可用修复)
使用 upscaleRT 时的后处理模糊
原因:后处理在像素完美相机上采样渲染纹理之后运行。
简单修复:禁用 upscaleRT。后处理随后以原生屏幕分辨率运行。
高级修复(Unity 6 URP):在 RenderPassEvent2D.AfterRenderingPostProcessing 注入一个 ScriptableRendererFeature2D。使用 2D 特定的基类 — ScriptableRendererFeature(3D 基类)在 URP 2D 渲染器中会被静默忽略。
使用 upscaleRT 时 UI 文本模糊
状态:已知 U