mcpField
2
2d-pixel-perfect

2d-pixel-perfect

github.com/unity-technologies开发1.2k3.6k 次安装1 天前更新
代码仓库

关于 2d-pixel-perfect

用于诊断和修复 Unity 像素级 2D 渲染的技能。它区分 URP 与 Built-in 的不同实现,并提供对应的设置、故障排查和迁移检查。

主要功能

  1. 01设置前检测 URP 或 Built-in
  2. 02配置匹配的 Pixel Perfect Camera
  3. 03诊断精灵导入与相机设置
  4. 04排查瓦片地图缝隙和图像模糊
  5. 05检查兼容性与迁移问题

适用场景

  1. 01修复像素艺术精灵模糊
  2. 02设置 Unity 像素级渲染相机
  3. 03排查瓦片地图中的缝隙
  4. 04检查项目是否使用错误的相机组件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/unity-technologies/skills --skill 2d-pixel-perfect

安装后在 Claude Code 中输入/2d-pixel-perfect确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
api-reference.md
camera-setup-builtin.cs
camera-setup-urp.cs
pipeline-detection.cs
sprite-settings.cs

详细介绍

在 Unity 项目中设置、诊断并修复像素级精准的 2D 渲染。


⚠ 两套完全独立的实现

Unity 中的像素级精准渲染并非一个系统,而是两套彼此不兼容的实现,分别对应一种渲染管线。编写或诊断任何代码之前,务必先检测渲染管线。

URPBuilt-in
组件UnityEngine.Rendering.Universal.PixelPerfectCameraUnityEngine.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 项目——不支持 Pixel Perfect Camera

重要提醒

⚠ 先检测渲染管线——URP 和 Built-in 使用不同的 Pixel Perfect Camera 组件,二者不可互换。
⚠ Filter Mode = Point 是首要修复方法——双线性过滤是 Unity 的默认设置,几乎总是导致精灵模糊的原因。
⚠ 必须禁用抗锯齿——在 Quality Settings 和摄像机上都要禁用。抗锯齿会主动模糊像素边缘。

核心原则

1. 渲染管线检测与摄像机组件选择

请参阅本文件顶部的两种方案对比表。关于程序集名称的说明:独立的 Built-in 软件包会安装到 Runtime/ 文件夹,但 asmdef 的 "name" 字段为 Unity.2D.PixelPerfect——没有 Runtime 后缀。HDRP 不受支持——请参阅“常见问题”下的 HDRP 替代方案部分。

→ 代码:references/pipeline-detection.cs——DetectPipeline()、GetPixelPerfectCameraType() 和迁移不匹配检查。

2. 先诊断

始终先诊断,再进行更改。报告检查结果,然后只修复存在问题的部分。

3. 在正确的范围内操作

默认仅针对场景范围。只有用户明确要求时,才扫描整个项目。


诊断清单

精灵导入设置:

  • 所有目标范围内的精灵均设置 Filter Mode = Point (no filter)
  • 禁用 Mip Maps
  • Compression = None / Uncompressed
  • 场景中所有精灵的 PPU 保持一致
  • 精灵轴心设为 Custom / Pixels 模式——奇数尺寸精灵(例如 15×15)的中心轴心会落在 7.5 px 处,导致 0.5 px 错位

→ 代码:references/sprite-settings.cs——GetImporter() 和 FixSpriteImportSettings()。

编辑器吸附设置:

  • 所有轴上的 Grid Size = 1 / assetsPPU(例如 PPU 为 16 → 0.0625,PPU 为 100 → 0.01)
  • 在 Grid and Snap 覆盖层中启用 Grid Snapping
  • 吸附现有 GameObject:选中它们 → Align Selected → All Axes

摄像机设置:

  • 摄像机投影模式 = Orthographic
  • 存在 Pixel Perfect Camera 组件,且类型与渲染管线匹配
  • allowHDR、allowMSAA、allowDynamicResolution 均为 false
  • Scene 视图中的摄像机辅助图标显示两个绿色边界框——实线框 = 可见区域,虚线框 = 参考分辨率

→ 代码:references/camera-setup-urp.cs——URP 摄像机和 PP Camera 的完整配置。
→ 代码:references/camera-setup-builtin.cs——Built-in 独立配置。

项目质量设置:

  • Quality Settings 中的 Anti-Aliasing = 0
  • Anisotropic Filtering = Disabled

API 参考

完整的属性/方法表、GridSnapping 和 CropFrame 枚举值,以及推荐配置: → references/api-reference.md — 编写或审查相机设置代码时,请阅读此文档。

枚举快速摘要:

GridSnapping:None · PixelSnapping(标准)· UpscaleRenderTexture(真实低分辨率;与后处理和 UI 文本不兼容)

CropFrame:None · Pillarbox · Letterbox · Windowbox(最安全的默认选项)· StretchFill


参考分辨率

在构建任何资源前选择。资源制作开始后切勿更改。

参考分辨率1080p1440p4K
320 × 1806×8×12×
480 × 2704×~5.3×8×
640 × 3603×4×6×

320×180 是最稳妥的通用选择。对于无法整数倍适配的屏幕(例如 1366×768),请使用 cropFrame = Windowbox 添加黑边,而不要拉伸到非整数倍比例。


迁移与兼容性

使用 Built-in 独立组件的 URP 项目

症状:DetectPipeline() 返回 URP,但相机具有 UnityEngine.U2D.PixelPerfectCamera。由于独立组件包含 ENABLE_URP 条件代码,因此症状并不明显。

修复:

  1. 从 Package Manager 移除 com.unity.2d.pixel-perfect
  2. 从每个相机中移除 UnityEngine.U2D.PixelPerfectCamera
  3. 添加 UnityEngine.Rendering.Universal.PixelPerfectCamera
  4. 重新配置 — 布尔值(pixelSnapping、upscaleRT、cropFrameX/Y)将变为枚举(gridSnapping、cropFrame)

→ 检测代码:references/pipeline-detection.cs(文件底部)。

旧版 URP 命名空间(Unity 2022 之前/URP 13.x 之前)

症状:编译器报错,提示引用了 UnityEngine.Experimental.Rendering.Universal。

修复:将 using UnityEngine.Experimental.Rendering.Universal; 替换为 using UnityEngine.Rendering.Universal;。更新所有程序集限定类型字符串。[MovedFrom] 属性会自动处理序列化 — GameObject 上的组件在升级后仍会保留。


常见问题与解决方案

精灵模糊

修复:将所有相关精灵的 Filter Mode 设为 Point,禁用 Mip Maps,并在 Quality Settings 中禁用 AA。 → 代码:references/sprite-settings.cs

Tilemap 瓦片之间有缝隙

按顺序逐项排查 — 诸如负 cell gap 或 PPU = 31.99 的变通方法会在相机移动时失效。

#检查项修复
1Sprite Atlas 是否关闭了 Tight Packing、将 Padding 设为 ≥ 4,并启用了 Sprite Packer Mode?在 Editor 设置中启用 Sprite Packer Mode;在图集中将 Padding 设为 ≥ 4 并关闭 Tight Packing
2Tileset 纹理和图集是否禁用了 Mipmaps?禁用 Generate Mip Maps
3AA = 0,且相机已关闭 MSAA?全局禁用 AA
4Compression = None?使用 RGBA 32 位无压缩
5所有瓦片精灵的像素尺寸是否为偶数?奇数尺寸会导致 0.5px 网格偏移
6PPU = 瓦片像素宽度?(16×16 → PPU 16)PPU 不匹配会留下物理间隙
7以上各项均通过后,仅在相机移动时出现缝隙?使用 PP Camera 像素对齐;不要使用 cellGap = -0.01f
Cinemachine 冲突

原因:Cinemachine 和 Pixel Perfect Camera 每帧都会写入正交尺寸。

修复:通过每个 Virtual Camera 上的 Add Extension 下拉菜单添加 CinemachinePixelPerfect 扩展。不要在代码中通过 AddComponent 添加。

已知限制:

  • 虚拟相机之间的混合在过渡期间无法做到像素完美
  • UpscaleRenderTexture 会减少有效的像素完美正交尺寸,可能导致取景偏移
  • Target Group + Framing Transposer 会造成明显卡顿(暂无解决方法)
使用 upscaleRT 后的后处理模糊

原因:后处理在 PP Camera 放大渲染纹理后运行。

简单修复:禁用 upscaleRT。这样后处理便会以屏幕原生分辨率运行。

进阶修复(Unity 6 URP):在 RenderPassEvent2D.AfterRenderingPostProcessing 注入一个 ScriptableRendererFeature2D。使用专为 2D 设计的基类——ScriptableRendererFeature(3D 基类)在 URP 2D 渲染器中会被静默忽略。

使用 upscaleRT 后的 UI 文本模糊

状态:已知 Unity Bug,官方拒绝修复(Unity 6 中仍存在,2025 年)。

根本原因:(A) Canvas 渲染到低分辨率缓冲区后,随场景一起放大。(B) TMP 的 SDF 渐变阈值在低参考分辨率下校准不准确。

按可靠性排序的修复方法:

  1. 在 Canvas 上设置 Screen Space - Overlay——绕过摄像机,以原生分辨率渲染
  2. 使用不带 PP Camera 组件的专用 UI 摄像机,并设置为 Screen Space - Camera 模式
  3. 仅限 Unity 6:Font Material → Debug Settings → Sharpness = 1(可缓解 B,不能缓解 A)
物理与渲染不同步(微卡顿)

原因:物理以固定时间步长运行;插值后的位置会产生小数值,导致物体每帧跳到不同的像素位置。

修复方法:

  • 为受物理驱动的精灵启用 Rigidbody2D.interpolation = RigidbodyInterpolation2D.Interpolate
  • 设置 Time.fixedDeltaTime = 1f / 60f,使其与目标帧率一致
  • 将摄像机跟踪逻辑放在 LateUpdate 中,而不是 FixedUpdate
非整数缩放/像素抽取

原因:屏幕分辨率不是参考分辨率的整数倍。

修复方法:从上表中选择参考分辨率。如果无法实现整数倍适配,则使用 cropFrame = Windowbox。

缺少 URP 2D Renderer

修复方法:

  1. Assets > Create > Rendering > URP 2D Renderer Data
  2. 在 URP Asset 的 Renderer List 中指定该项
  3. 需要 com.unity.render-pipelines.universal 12.0+
HDRP 回退方案

HDRP 不支持 Pixel Perfect Camera。

Built-in / Unity 5.x:使用 RenderTexture + Graphics.Blit,并设置 FilterMode.Point。

Unity 6 URP:使用 ScriptableRendererFeature2D + ScriptableRenderPass2D,通过 AddRasterRenderPass 在 RenderPassEvent2D.AfterRendering 注入。注意:OnRenderImage 和 Graphics.Blit 与 Unity 6 的渲染图不兼容。

评论

支持 Markdown