2d-pixel-perfect
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSet up, diagnose, and fix pixel perfect 2D rendering in Unity projects.
在Unity项目中设置、诊断并修复像素完美2D渲染。
⚠️ There Are Two Completely Separate Implementations
⚠️ 有两种完全独立的实现方式
Pixel perfect rendering in Unity is not one system — it is two separate, incompatible implementations, one per render pipeline. Always detect the pipeline before writing or diagnosing any code.
| URP | Built-in | |
|---|---|---|
| Component | | |
| Package | Built into URP — no extra install | |
| API style | Enums ( | Booleans ( |
Do not install in a URP project.
com.unity.2d.pixel-perfect→ Always call first (), then branch your setup, diagnostics, and fixes based on the result.
DetectPipeline()references/pipeline-detection.csUnity中的像素完美渲染并非单一系统——它是两种相互独立且互不兼容的实现,分别对应不同的渲染管线。在编写或诊断任何代码之前,务必先检测所用的管线。
| URP | Built-in | |
|---|---|---|
| 组件 | | |
| 包 | URP内置 — 无需额外安装 | |
| API风格 | 枚举( | 布尔值( |
请勿在URP项目中安装包。
com.unity.2d.pixel-perfect→ 务必先调用(位于),再根据检测结果分支处理设置、诊断和修复逻辑。
DetectPipeline()references/pipeline-detection.csWhen NOT to use this skill
不适用场景
- HD 2D or high-resolution 2D games — pixel snapping and point filtering will make smooth art look wrong
- UI-only scenes — use Canvas Scaler instead
- HDRP projects — Pixel Perfect Camera is not supported
- 高清2D或高分辨率2D游戏 —— 像素对齐和点过滤会让流畅美术素材的显示效果异常
- 仅含UI的场景 —— 请改用Canvas Scaler
- HDRP项目 —— 不支持Pixel Perfect Camera
Critical Reminders
重要提醒
⚠️ Detect the render pipeline first — URP and Built-in use different Pixel Perfect Camera components that are not interchangeable.
⚠️ Filter Mode = Point is the #1 fix — bilinear filtering is Unity's default and is almost always the cause of blurry sprites.
⚠️ Anti-Aliasing must be disabled — in Quality Settings and on the camera. AA actively blurs pixel edges.
⚠️ 务必先检测渲染管线 —— URP和内置管线使用的Pixel Perfect Camera组件不同,不可互换。
⚠️ 过滤模式设为Point是首要修复方案 —— Unity默认使用双线性过滤,这几乎是精灵模糊的根本原因。
⚠️ 必须禁用抗锯齿 —— 在质量设置和相机设置中都要关闭,AA会主动模糊像素边缘。
Key Principles
核心原则
1. Pipeline Detection & Camera Component Selection
1. 管线检测与相机组件选择
See the two-path comparison table at the top of this file. Assembly name note: the standalone Built-in package installs into a folder, but the asmdef field is — no suffix. HDRP is unsupported — see the HDRP fallback section under Common Issues.
Runtime/"name"Unity.2D.PixelPerfectRuntime→ Code: — , , and migration mismatch check.
references/pipeline-detection.csDetectPipeline()GetPixelPerfectCameraType()参见本文顶部的双方案对比表。
程序集名称说明:独立的内置管线包安装在文件夹下,但其asmdef的字段为——没有后缀。
HDRP不受支持——参见「常见问题」中的HDRP替代方案部分。
Runtime/"name"Unity.2D.PixelPerfectRuntime→ 代码: —— 包含、以及迁移不匹配检查。
references/pipeline-detection.csDetectPipeline()GetPixelPerfectCameraType()2. Diagnostic-First Approach
2. 诊断优先原则
Always diagnose before making changes. Report findings, then fix only what is broken.
始终先诊断再修改。先上报发现的问题,再仅修复已确认的故障。
3. Work in the correct scope
3. 在正确的范围内工作
Default to scene scope. Scan project-wide only when the user explicitly requests it.
默认以场景为作用范围,仅当用户明确要求时才进行全项目扫描。
Diagnostic Checklist
诊断检查清单
Sprite import settings:
- Filter Mode = on all in-scope sprites
Point (no filter) - Mip Maps = disabled
- Compression = / Uncompressed
None - PPU consistent across all sprites in scene
- Sprite pivots set to Custom / Pixels mode — a center pivot on an odd-dimension sprite (e.g. 15×15) lands at 7.5px, causing 0.5px misalignment
→ Code: — and .
references/sprite-settings.csGetImporter()FixSpriteImportSettings()Editor snap settings:
- Grid Size = on all axes (e.g. PPU 16 → 0.0625, PPU 100 → 0.01)
1 / assetsPPU - Grid Snapping enabled in the Grid and Snap overlay
- To snap existing GameObjects: select them → Align Selected → All Axes
Camera setup:
- Camera projection = Orthographic
- Pixel Perfect Camera component present and correct type for pipeline
- ,
allowHDR,allowMSAAallallowDynamicResolutionfalse - Scene view shows two green bounding boxes on the camera gizmo — solid = visible area, dotted = reference resolution
→ Code: — full URP camera + PP Camera configuration.
→ Code: — Built-in standalone configuration.
references/camera-setup-urp.csreferences/camera-setup-builtin.csProject quality settings:
- Anti-Aliasing = 0 in Quality Settings
- Anisotropic Filtering = Disabled
精灵导入设置:
- 所有作用范围内的精灵,过滤模式(Filter Mode)设为
Point (no filter) - 禁用Mip Maps
- 压缩方式设为/ 未压缩
None - 场景中所有精灵的PPU保持一致
- 精灵轴心设为自定义/像素模式——奇数尺寸精灵(例如15×15)的中心轴心会落在7.5px位置,导致0.5px偏移
→ 代码: —— 包含和。
references/sprite-settings.csGetImporter()FixSpriteImportSettings()编辑器对齐设置:
- 所有轴的网格大小(Grid Size)设为(例如PPU为16则设为0.0625,PPU为100则设为0.01)
1 / assetsPPU - 在网格与对齐浮窗中启用网格对齐
- 对齐现有GameObject:选中后 → 对齐所选对象 → 所有轴
相机设置:
- 相机投影模式设为正交(Orthographic)
- 已添加Pixel Perfect Camera组件,且类型与渲染管线匹配
- 、
allowHDR、allowMSAA均设为allowDynamicResolutionfalse - 场景视图中相机的Gizmo显示两个绿色边界框——实线为可见区域,虚线为参考分辨率
→ 代码: —— 完整的URP相机 + PP Camera配置。
→ 代码: —— 内置管线独立版配置。
references/camera-setup-urp.csreferences/camera-setup-builtin.cs项目质量设置:
- 质量设置中的抗锯齿(Anti-Aliasing)设为0
- 禁用各向异性过滤(Anisotropic Filtering)
API Reference
API参考
Full property/method tables, and enum values, and recommended configurations:
→ — read this when writing or reviewing camera setup code.
GridSnappingCropFramereferences/api-reference.mdQuick enum summary:
GridSnappingNonePixelSnappingUpscaleRenderTextureCropFrameNonePillarboxLetterboxWindowboxStretchFill完整的属性/方法表、和枚举值以及推荐配置:
→ —— 编写或审查相机设置代码时请阅读此文件。
GridSnappingCropFramereferences/api-reference.md枚举快速摘要:
GridSnappingNonePixelSnappingUpscaleRenderTextureCropFrameNonePillarboxLetterboxWindowboxStretchFillReference Resolution
参考分辨率
Choose before building any assets. Never change after asset production starts.
| Reference resolution | 1080p | 1440p | 4K |
|---|---|---|---|
| 320 × 180 | 6× | 8× | 12× |
| 480 × 270 | 4× | ~5.3× | 8× |
| 640 × 360 | 3× | 4× | 6× |
320×180 is the safest general choice. For screens with no integer fit (e.g. 1366×768), use to add black bars rather than stretching to a fractional scale.
cropFrame = Windowbox在制作任何资源前确定,资源生产开始后切勿修改。
| 参考分辨率 | 1080p | 1440p | 4K |
|---|---|---|---|
| 320 × 180 | 6× | 8× | 12× |
| 480 × 270 | 4× | ~5.3× | 8× |
| 640 × 360 | 3× | 4× | 6× |
320×180是最稳妥的通用选择。对于无法整数适配的屏幕(例如1366×768),使用添加黑边,而非拉伸为非整数缩放比例。
cropFrame = WindowboxMigration & Compatibility
迁移与兼容性
URP project with the Built-in standalone component
URP项目中使用了内置管线的独立组件
Symptom: returns URP but camera has . Symptoms are subtle because the standalone component has conditional code.
DetectPipeline()UnityEngine.U2D.PixelPerfectCameraENABLE_URPFix:
- Remove from Package Manager
com.unity.2d.pixel-perfect - Remove from each camera
UnityEngine.U2D.PixelPerfectCamera - Add
UnityEngine.Rendering.Universal.PixelPerfectCamera - Reconfigure — booleans (,
pixelSnapping,upscaleRT) become enums (cropFrameX/Y,gridSnapping)cropFrame
→ Detection code: (bottom of file).
references/pipeline-detection.cs症状:返回URP,但相机上挂载的是。症状可能不明显,因为该独立组件包含条件编译代码。
DetectPipeline()UnityEngine.U2D.PixelPerfectCameraENABLE_URP修复方案:
- 从包管理器中移除
com.unity.2d.pixel-perfect - 从每个相机上移除组件
UnityEngine.U2D.PixelPerfectCamera - 添加组件
UnityEngine.Rendering.Universal.PixelPerfectCamera - 重新配置——布尔参数(、
pixelSnapping、upscaleRT)需替换为枚举参数(cropFrameX/Y、gridSnapping)cropFrame
→ 检测代码:(文件底部)。
references/pipeline-detection.csOld URP namespace (pre-Unity 2022 / URP pre-13.x)
旧版URP命名空间(Unity 2022之前 / URP 13.x之前版本)
Symptom: Compiler errors referencing .
UnityEngine.Experimental.Rendering.UniversalFix: Replace with . Update any assembly-qualified type strings. The attribute handles serialization automatically — components on GameObjects survive the upgrade.
using UnityEngine.Experimental.Rendering.Universal;using UnityEngine.Rendering.Universal;[MovedFrom]症状:引用时出现编译错误。
UnityEngine.Experimental.Rendering.Universal修复方案:将替换为。更新所有程序集限定类型字符串。特性会自动处理序列化——GameObject上的组件可正常升级。
using UnityEngine.Experimental.Rendering.Universal;using UnityEngine.Rendering.Universal;[MovedFrom]Common Issues & Solutions
常见问题与解决方案
Blurry sprites
精灵模糊
Fix: Set Filter Mode to Point on all in-scope sprites, disable Mip Maps, disable AA in Quality Settings.
→ Code:
references/sprite-settings.cs修复方案:将所有作用范围内精灵的过滤模式设为Point,禁用Mip Maps,在质量设置中关闭AA。
→ 代码:
references/sprite-settings.csTilemap gaps between tiles
瓦片地图瓦片间有缝隙
Work through in order — workarounds like negative cell gap or PPU = 31.99 break when the camera moves.
| # | Check | Fix |
|---|---|---|
| 1 | Sprite Atlas with Tight Packing off, Padding ≥ 4, Sprite Packer Mode enabled? | Enable Sprite Packer Mode in Editor settings; on the atlas set Padding ≥ 4 and turn Tight Packing off |
| 2 | Mipmaps disabled on tileset textures and atlas? | Disable Generate Mip Maps |
| 3 | AA = 0, MSAA off on camera? | Disable AA globally |
| 4 | Compression = None? | RGBA 32-bit uncompressed |
| 5 | All tile sprites have even pixel dimensions? | Odd dimensions cause 0.5px grid offset |
| 6 | PPU = tile pixel width? (16×16 → PPU 16) | PPU mismatch leaves physical gaps |
| 7 | Gaps only during camera movement after all above pass? | Use PP Camera pixel snapping; do not use |
按顺序排查——诸如负单元格间距或PPU设为31.99之类的变通方法会在相机移动时失效。
| # | 检查项 | 修复方案 |
|---|---|---|
| 1 | 精灵图集(Sprite Atlas)是否关闭了紧密打包(Tight Packing)、内边距(Padding)≥4、且启用了精灵打包器模式? | 在编辑器设置中启用精灵打包器模式;在图集上设置内边距≥4并关闭紧密打包 |
| 2 | 瓦片集纹理和图集是否禁用了Mipmaps? | 关闭生成Mip Maps |
| 3 | AA是否为0、相机上的MSAA是否关闭? | 全局禁用AA |
| 4 | 压缩方式是否为None? | 使用RGBA 32位未压缩格式 |
| 5 | 所有瓦片精灵的像素尺寸是否为偶数? | 奇数尺寸会导致0.5px网格偏移 |
| 6 | PPU是否等于瓦片像素宽度?(16×16瓦片 → PPU 16) | PPU不匹配会导致物理缝隙 |
| 7 | 以上检查都通过,但仅在相机移动时出现缝隙? | 使用PP Camera的像素对齐功能;不要使用 |
Cinemachine conflict
Cinemachine冲突
Cause: Both Cinemachine and the Pixel Perfect Camera write to orthographic size every frame.
Fix: Add extension via the Add Extension dropdown on each Virtual Camera. Do not add it via in code.
CinemachinePixelPerfectAddComponentKnown limitations:
- Camera blends between virtual cameras are not pixel-perfect during transitions
- reduces valid pixel-perfect ortho sizes, which may cause framing to deviate
UpscaleRenderTexture - Target Group + Framing Transposer causes visible choppiness (no fix available)
原因:Cinemachine和Pixel Perfect Camera都会每帧修改正交相机尺寸。
修复方案:在每个虚拟相机(Virtual Camera)的「添加扩展」下拉菜单中添加扩展。请勿通过代码中的添加。
CinemachinePixelPerfectAddComponent已知限制:
- 虚拟相机之间的混合过渡过程无法做到像素完美
- 会减少可用的像素完美正交尺寸,可能导致画面构图偏移
UpscaleRenderTexture - 目标组+构图转置器(Target Group + Framing Transposer)会导致可见卡顿(暂无修复方案)
Post-processing blur with upscaleRT
upscaleRT使用upscaleRT
时后处理模糊
upscaleRTCause: Post-processing runs after the PP Camera upscales the render texture.
Simple fix: Disable . Post-processing then runs at native screen resolution.
upscaleRTAdvanced fix (Unity 6 URP): Inject a at . Use 2D-specific base classes — (3D base class) is silently ignored in a URP 2D renderer.
ScriptableRendererFeature2DRenderPassEvent2D.AfterRenderingPostProcessingScriptableRendererFeature原因:后处理在Pixel Perfect Camera放大渲染纹理之后执行。
简单修复:禁用,后处理将以原生屏幕分辨率运行。
upscaleRT高级修复(Unity 6 URP):在阶段注入。请使用2D专用基类——3D基类在URP 2D渲染器中会被静默忽略。
RenderPassEvent2D.AfterRenderingPostProcessingScriptableRendererFeature2DScriptableRendererFeatureUI text blurry with upscaleRT
upscaleRT使用upscaleRT
时UI文本模糊
upscaleRTStatus: Known Unity bug, declined to fix (still present Unity 6, 2025).
Root causes: (A) Canvas renders into the low-res buffer and is upscaled with the scene. (B) TMP's SDF gradient threshold is miscalibrated at low reference resolutions.
Fixes in order of reliability:
- on Canvas — bypasses the camera, renders at native resolution
Screen Space - Overlay - Dedicated UI camera with no PP Camera component, mode
Screen Space - Camera - Unity 6 only: (mitigates B, not A)
Font Material → Debug Settings → Sharpness = 1
状态:已知Unity bug,官方拒绝修复(截至Unity 6、2025年仍存在)。
根本原因:(A) Canvas渲染到低分辨率缓冲区,随场景一起被放大。(B) TMP的SDF渐变阈值在低参考分辨率下校准错误。
按可靠性排序的修复方案:
- 将Canvas设为模式——绕过相机,以原生分辨率渲染
Screen Space - Overlay - 使用专用UI相机,不挂载Pixel Perfect Camera组件,Canvas设为模式
Screen Space - Camera - 仅Unity 6可用:(可缓解B问题,无法解决A问题)
字体材质 → 调试设置 → 锐度 = 1
Physics / render desync (micro-stutter)
物理/渲染不同步(微卡顿)
Cause: Physics runs at a fixed timestep; interpolated positions produce fractional values that snap to different pixels each frame.
Fix:
- Enable on physics-driven sprites
Rigidbody2D.interpolation = RigidbodyInterpolation2D.Interpolate - Set to match target frame rate
Time.fixedDeltaTime = 1f / 60f - Keep camera tracking in , not
LateUpdateFixedUpdate
原因:物理以固定时间步长运行;插值位置会产生小数值,导致每帧对齐到不同的像素。
修复方案:
- 在受物理驱动的精灵上启用
Rigidbody2D.interpolation = RigidbodyInterpolation2D.Interpolate - 设置以匹配目标帧率
Time.fixedDeltaTime = 1f / 60f - 将相机跟随逻辑放在中,而非
LateUpdateFixedUpdate
Non-integer scaling / pixel decimation
非整数缩放 / 像素抽稀
Cause: Screen resolution is not a clean integer multiple of the reference resolution.
Fix: Choose a reference resolution from the table above. Use when no integer fit exists.
cropFrame = Windowbox原因:屏幕分辨率不是参考分辨率的整数倍。
修复方案:从上表中选择合适的参考分辨率。当无法整数适配时,使用。
cropFrame = WindowboxMissing URP 2D Renderer
缺少URP 2D渲染器
Fix:
Assets > Create > Rendering > URP 2D Renderer Data- Assign it to your URP Asset under Renderer List
- Requires 12.0+
com.unity.render-pipelines.universal
修复方案:
资产 > 创建 > 渲染 > URP 2D Renderer Data- 将其分配到URP资源的渲染器列表中
- 需要12.0及以上版本
com.unity.render-pipelines.universal
HDRP fallback
HDRP替代方案
Pixel Perfect Camera is unsupported in HDRP.
Built-in / Unity 5.x: Use + with .
RenderTextureGraphics.BlitFilterMode.PointUnity 6 URP: Use + injected at with . Note: and are incompatible with Unity 6's render graph.
ScriptableRendererFeature2DScriptableRenderPass2DRenderPassEvent2D.AfterRenderingAddRasterRenderPassOnRenderImageGraphics.BlitPixel Perfect Camera在HDRP中不受支持。
内置管线 / Unity 5.x:使用 + ,并设置。
RenderTextureGraphics.BlitFilterMode.PointUnity 6 URP:使用 + ,在阶段通过注入。注意:和与Unity 6的渲染图(render graph)不兼容。
ScriptableRendererFeature2DScriptableRenderPass2DRenderPassEvent2D.AfterRenderingAddRasterRenderPassOnRenderImageGraphics.Blit