在 Unity 專案中設置、診斷並修復像素完美 2D 渲染。
⚠️ 有兩個完全分開的實作
Unity 中的像素完美渲染不是一個系統 — 它是兩個分開且不相容的實作,每個渲染管線各一個。在撰寫或診斷任何程式碼之前,務必先檢測管線。
| URP | Built-in | |
|---|---|---|
| 元件 | 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 專案 — Pixel Perfect Camera 不受支援
重要提醒
⚠️ 首先檢測渲染管線 — URP 和 Built-in 使用不同的 Pixel Perfect Camera 元件,兩者不可互換。 ⚠️ 濾鏡模式 = Point 是首要修復方式 — 雙線性濾鏡是 Unity 的預設值,幾乎總是導致精靈模糊的原因。 ⚠️ 必須停用抗鋸齒 — 在品質設定和攝影機上都必須停用。AA 會主動模糊像素邊緣。
關鍵原則
1. 管線偵測與攝影機元件選擇
請參閱本檔案頂部的雙路徑比較表格。組件名稱注意:獨立的 Built-in 套件安裝到 Runtime/ 資料夾,但 asmdef "name" 欄位是 Unity.2D.PixelPerfect — 沒有 Runtime 後綴。HDRP 不受支援 — 請參閱常見問題下的 HDRP 備援部分。
→ 程式碼:references/pipeline-detection.cs — DetectPipeline()、GetPixelPerfectCameraType() 和遷移不匹配檢查。
2. 診斷優先方法
在進行任何更改之前始終先進行診斷。報告發現,然後只修復有問題的部分。
3. 在正確的範圍內工作
預設為場景範圍。僅在使用者明確要求時才掃描整個專案。
診斷檢查清單
精靈導入設定:
- 所有範圍內精靈的濾鏡模式 =
Point (no filter) - Mip Maps = 停用
- 壓縮 =
None/ 未壓縮 - 場景中所有精靈的 PPU 一致
- 精靈軸點設定為「自訂 / 像素」模式 — 奇數尺寸精靈(例如 15×15)的中心軸點落在 7.5 像素處,導致 0.5 像素偏移
→ 程式碼:references/sprite-settings.cs — GetImporter() 和 FixSpriteImportSettings()。
編輯器對齊設定:
- 所有軸的網格大小 =
1 / assetsPPU(例如 PPU 16 → 0.0625,PPU 100 → 0.01) - 在「網格」和「對齊」疊加層中啟用網格對齊
- 要對齊現有遊戲物件:選取它們 → 對齊已選取 → 所有軸
攝影機設定:
- 攝影機投影 = 正交
- Pixel Perfect Camera 元件存在且類型與管線相符
-
allowHDR、allowMSAA、allowDynamicResolution全部為false - 場景檢視在攝影機輔助圖示上顯示兩個綠色邊界框 — 實線 = 可見區域,虛線 = 參考解析度
→ 程式碼:references/camera-setup-urp.cs — 完整的 URP 攝影機 + PP Camera 配置。
→ 程式碼:references/camera-setup-builtin.cs — Built-in 獨立配置。
專案品質設定:
- 品質設定中的抗鋸齒 = 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 添加黑邊,而不是拉伸到分數倍率。
遷移與相容性
使用 Built-in 獨立元件的 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] 屬性會自動處理序列化 — 遊戲物件上的元件在升級後仍會保留。
常見問題與解決方案
精靈模糊
修復方式:將所有範圍內精靈的濾鏡模式設為 Point,停用 Mip Maps,在品質設定中停用 AA。
→ 程式碼:references/sprite-settings.cs
圖塊地圖之間的間隙
按順序處理 — 像負的儲存格間隙或 PPU = 31.99 這類的變通方法會在攝影機移動時失效。
| # | 檢查項目 | 修復方式 |
|---|---|---|
| 1 | 精靈圖集已關閉緊湊打包、填補 ≥ 4、啟用 Sprite Packer 模式? | 在編輯器設定中啟用 Sprite Packer 模式;在圖集上設定填補 ≥ 4 並關閉緊湊打包 |
| 2 | 圖塊集紋理和圖集上的 Mipmaps 已停用? | 停用「產生 Mip Maps」 |
| 3 | AA = 0,攝影機上的 MSAA 已關閉? | 全域停用 AA |
| 4 | 壓縮 = None? | RGBA 32 位元未壓縮 |
| 5 | 所有圖塊精靈的像素尺寸皆為偶數? | 奇數尺寸會導致 0.5 像素網格偏移 |
| 6 | PPU = 圖塊像素寬度?(16×16 → PPU 16) | PPU 不匹配會留下物理間隙 |
| 7 | 通過上述所有檢查後,間隙僅在攝影機移動時出現? | 使用 PP Camera 像素對齊;不要使用 cellGap = -0.01f |
Cinemachine 衝突
原因:Cinemachine 和 Pixel Perfect Camera 都會在每一幀寫入正交大小。
修復方式:透過每個虛擬攝影機上的「添加延伸」下拉選單添加 CinemachinePixelPerfect 延伸。請勿透過程式碼中的 AddComponent 添加。
已知限制:
- 虛擬攝影機之間的攝影機混合在過渡期間不是像素完美的
UpscaleRenderTexture會減少有效的像素完美正交大小,可能導致取景偏差- 目標群組 + 取景變換器會導致可見的卡頓(無可用修復)
使用 upscaleRT 時的後處理模糊
原因:後處理在 PP Camera 放大渲染紋理之後執行。
簡單修復:停用 upscaleRT。後處理隨後以原生螢幕解析度執行。
進階修復(Unity 6 URP):在 RenderPassEvent2D.AfterRenderingPostProcessing 注入 ScriptableRendererFeature2D。使用 2D 特定的基底類別 — ScriptableRendererFeature(3D 基底類別)在 URP 2D 渲染器中會被靜默忽略。
使用 upscaleRT 時的 UI 文字模糊
狀態:已知問題。