Configure, diagnostique e corrija a renderização 2D pixel-perfect em projetos Unity.
⚠️ Existem Duas Implementações Completamente Separadas
A renderização pixel-perfect no Unity não é um sistema único — são duas implementações separadas e incompatíveis, uma por pipeline de renderização. Sempre detecte o pipeline antes de escrever ou diagnosticar qualquer código.
| URP | Built-in | |
|---|---|---|
| Componente | UnityEngine.Rendering.Universal.PixelPerfectCamera | UnityEngine.U2D.PixelPerfectCamera |
| Pacote | Integrado ao URP — sem instalação extra | com.unity.2d.pixel-perfect v6.0.0+ |
| Estilo da API | Enums (gridSnapping, cropFrame) | Booleans (pixelSnapping, upscaleRT, cropFrameX/Y) |
Não instale com.unity.2d.pixel-perfect em um projeto URP.
→ Sempre chame DetectPipeline() primeiro (references/pipeline-detection.cs), depois ramifique sua configuração, diagnósticos e correções com base no resultado.
Quando NÃO usar este skill
- Jogos 2D HD ou de alta resolução — o pixel snapping e o filtro Point deixarão a arte suave com aparência errada
- Cenas apenas de UI — use o Canvas Scaler
- Projetos HDRP — o Pixel Perfect Camera não é suportado
Lembretes Críticos
⚠️ Detecte o pipeline de renderização primeiro — URP e Built-in usam componentes Pixel Perfect Camera diferentes que não são intercambiáveis. ⚠️ Modo de Filtro = Point é a correção #1 — a filtragem bilinear é o padrão do Unity e quase sempre é a causa de sprites borrados. ⚠️ O Anti-Aliasing deve estar desabilitado — nas Configurações de Qualidade e na câmera. O AA borra ativamente as bordas dos pixels.
Princípios Chave
1. Detecção de Pipeline e Seleção do Componente da Câmera
Veja a tabela de comparação dos dois caminhos no topo deste arquivo. Nota sobre o nome do assembly: o pacote standalone Built-in instala em uma pasta Runtime/, mas o campo "name" do asmdef é Unity.2D.PixelPerfect — sem o sufixo Runtime. HDRP não é suportado — veja a seção de fallback HDRP em Problemas Comuns.
→ Código: references/pipeline-detection.cs — DetectPipeline(), GetPixelPerfectCameraType() e verificação de incompatibilidade de migração.
2. Abordagem de Diagnóstico Primeiro
Sempre diagnostique antes de fazer alterações. Relate os resultados e corrija apenas o que está quebrado.
3. Trabalhe no escopo correto
Use o escopo da cena como padrão. Varra o projeto inteiro apenas quando o usuário solicitar explicitamente.
Checklist de Diagnóstico
Configurações de importação de sprites:
- Modo de Filtro =
Point (sem filtro)em todos os sprites do escopo - Mip Maps = desabilitado
- Compressão =
Nenhum/ Descomprimido - PPU consistente em todos os sprites da cena
- Pivôs dos sprites definidos como Personalizado / Modo Pixels — um pivô central em um sprite de dimensão ímpar (ex.: 15×15) cai em 7.5px, causando desalinhamento de 0.5px
→ Código: references/sprite-settings.cs — GetImporter() e FixSpriteImportSettings().
Configurações de snap do editor:
- Tamanho da Grade =
1 / assetsPPUem todos os eixos (ex.: PPU 16 → 0.0625, PPU 100 → 0.01) - Snap da Grade habilitado na sobreposição Grade e Snap
- Para alinhar GameObjects existentes: selecione-os → Alinhar Selecionados → Todos os Eixos
Configuração da câmera:
- Projeção da câmera = Ortográfica
- Componente Pixel Perfect Camera presente e do tipo correto para o pipeline
-
allowHDR,allowMSAA,allowDynamicResolutiontodosfalse - A visualização da cena mostra duas caixas delimitadoras verdes no gizmo da câmera — sólida = área visível, pontilhada = resolução de referência
→ Código: references/camera-setup-urp.cs — configuração completa da câmera URP + PP Camera.
→ Código: references/camera-setup-builtin.cs — configuração standalone Built-in.
Configurações de qualidade do projeto:
- Anti-Aliasing = 0 nas Configurações de Qualidade
- Filtragem Anisotrópica = Desabilitada
Referência da API
Tabelas completas de propriedades/métodos, valores de enum GridSnapping e CropFrame, e configurações recomendadas:
→ references/api-reference.md — leia ao escrever ou revisar código de configuração de câmera.
Resumo rápido dos enums:
GridSnapping: None · PixelSnapping (padrão) · UpscaleRenderTexture (baixa resolução autêntica; incompatível com pós-processamento e texto de UI)
CropFrame: None · Pillarbox · Letterbox · Windowbox (padrão mais seguro) · StretchFill
Resolução de Referência
Escolha antes de construir qualquer asset. Nunca mude depois que a produção de assets começar.
| Resolução de referência | 1080p | 1440p | 4K |
|---|---|---|---|
| 320 × 180 | 6× | 8× | 12× |
| 480 × 270 | 4× | ~5.3× | 8× |
| 640 × 360 | 3× | 4× | 6× |
320×180 é a escolha geral mais segura. Para telas sem ajuste inteiro (ex.: 1366×768), use cropFrame = Windowbox para adicionar barras pretas em vez de esticar para uma escala fracionária.
Migração e Compatibilidade
Projeto URP com o componente standalone Built-in
Sintoma: DetectPipeline() retorna URP, mas a câmera tem UnityEngine.U2D.PixelPerfectCamera. Os sintomas são sutis porque o componente standalone tem código condicional ENABLE_URP.
Correção:
- Remova
com.unity.2d.pixel-perfectdo Gerenciador de Pacotes - Remova
UnityEngine.U2D.PixelPerfectCamerade cada câmera - Adicione
UnityEngine.Rendering.Universal.PixelPerfectCamera - Reconfigure — booleans (
pixelSnapping,upscaleRT,cropFrameX/Y) se tornam enums (gridSnapping,cropFrame)
→ Código de detecção: references/pipeline-detection.cs (final do arquivo).
Namespace URP antigo (pré-Unity 2022 / URP pré-13.x)
Sintoma: Erros de compilação referenciando UnityEngine.Experimental.Rendering.Universal.
Correção: Substitua using UnityEngine.Experimental.Rendering.Universal; por using UnityEngine.Rendering.Universal;. Atualize quaisquer strings de tipo qualificadas por assembly. O atributo [MovedFrom] lida com a serialização automaticamente — componentes em GameObjects sobrevivem à atualização.
Problemas e Soluções Comuns
Sprites borrados
Correção: Defina o Modo de Filtro como Point em todos os sprites do escopo, desabilite Mip Maps e desabilite AA nas Configurações de Qualidade.
→ Código: references/sprite-settings.cs
Lacunas entre tiles no Tilemap
Trabalhe em ordem — soluções alternativas como lacuna de célula negativa ou PPU = 31.99 quebram quando a câmera se move.
| # | Verificação | Correção |
|---|---|---|
| 1 | Sprite Atlas com Tight Packing desligado, Padding ≥ 4, Sprite Packer Mode habilitado? | Habilite o Sprite Packer Mode nas configurações do Editor; no atlas, defina Padding ≥ 4 e desligue Tight Packing |
| 2 | Mipmaps desabilitados nas texturas do tileset e no atlas? | Desabilite Generate Mip Maps |
| 3 | AA = 0, MSAA desligado na câmera? | Desabilite AA globalmente |
| 4 | Compressão = Nenhum? | RGBA 32-bit descomprimido |
| 5 | Todos os sprites de tile têm dimensões de pixels pares? | Dimensões ímpares causam desalinhamento de grade de 0.5px |
| 6 | PPU = largura de pixel do tile? (16×16 → PPU 16) | Incompatibilidade de PPU deixa lacunas físicas |
| 7 | Lacunas apenas durante o movimento da câmera após todos os passos acima? | Use pixel snapping da PP Camera; não use cellGap = -0.01f |
Conflito com Cinemachine
Causa: Tanto o Cinemachine quanto o Pixel Perfect Camera escrevem no tamanho ortográfico a cada quadro.
Correção: Adicione a extensão CinemachinePixelPerfect através do menu Adicionar Extensão em cada Câmera Virtual. Não a adicione via AddComponent em código.
Limitações conhecidas:
- As transições de câmera entre câmeras virtuais não são pixel-perfect durante as transições
UpscaleRenderTexturereduz os tamanhos ortográficos pixel-perfect válidos, o que pode fazer o enquadramento desviar- Target Group + Framing Transposer causa oscilação visível (sem correção disponível)
Borrão de pós-processamento com upscaleRT
Causa: O pós-processamento executa após a PP Camera aumentar a textura de renderização.
Correção simples: Desabilite upscaleRT. O pós-processamento então executa na resolução nativa da tela.
Correção avançada (Unity 6 URP): Injete um ScriptableRendererFeature2D em RenderPassEvent2D.AfterRenderingPostProcessing. Use classes base específicas para 2D — ScriptableRendererFeature (classe base 3D) é silenciosamente ignorada em um renderizador 2D URP.
Texto de UI borrado com upscaleRT
Status: Conhecido no U