Configura, diagnostica y corrige el renderizado 2D perfecto en píxeles en proyectos Unity.
⚠️ Hay Dos Implementaciones Completamente Separadas
El renderizado perfecto en píxeles en Unity no es un sistema único — son dos implementaciones separadas e incompatibles, una por pipeline de renderizado. Siempre detecta el pipeline antes de escribir o diagnosticar cualquier código.
| URP | Built-in | |
|---|---|---|
| Componente | UnityEngine.Rendering.Universal.PixelPerfectCamera | UnityEngine.U2D.PixelPerfectCamera |
| Paquete | Integrado en URP — sin instalación extra | com.unity.2d.pixel-perfect v6.0.0+ |
| Estilo de API | Enumeraciones (gridSnapping, cropFrame) | Booleanos (pixelSnapping, upscaleRT, cropFrameX/Y) |
No instales com.unity.2d.pixel-perfect en un proyecto URP.
→ Siempre llama primero a DetectPipeline() (references/pipeline-detection.cs), luego bifurca tu configuración, diagnóstico y correcciones según el resultado.
Cuándo NO usar esta habilidad
- Juegos 2D HD o de alta resolución — el pixel snapping y el filtrado Point harán que el arte suave se vea incorrecto
- Escenas solo de UI — usa Canvas Scaler en su lugar
- Proyectos HDRP — Pixel Perfect Camera no es compatible
Recordatorios Críticos
⚠️ Detecta el pipeline de renderizado primero — URP y Built-in usan componentes Pixel Perfect Camera diferentes que no son intercambiables. ⚠️ Filter Mode = Point es la solución #1 — el filtrado bilineal es el valor predeterminado de Unity y casi siempre es la causa de sprites borrosos. ⚠️ El Anti-Aliasing debe estar desactivado — en la Configuración de Calidad y en la cámara. El AA desenfoca activamente los bordes de los píxeles.
Principios Clave
1. Detección del Pipeline y Selección del Componente de Cámara
Consulta la tabla de comparación de dos rutas al inicio de este archivo. Nota sobre el ensamblado: el paquete independiente Built-in se instala en una carpeta Runtime/, pero el campo "name" del asmdef es Unity.2D.PixelPerfect — sin el sufijo Runtime. HDRP no es compatible — consulta la sección de fallback para HDRP en Problemas Comunes.
→ Código: references/pipeline-detection.cs — DetectPipeline(), GetPixelPerfectCameraType(), y verificación de migración incorrecta.
2. Enfoque Diagnóstico-Primero
Siempre diagnostica antes de hacer cambios. Reporta hallazgos, luego corrige solo lo que está roto.
3. Trabaja en el ámbito correcto
Por defecto, trabaja en el ámbito de la escena. Escanea en todo el proyecto solo cuando el usuario lo solicite explícitamente.
Lista de Verificación de Diagnóstico
Configuración de importación de sprites:
- Filter Mode =
Point (sin filtro)en todos los sprites del ámbito - Mip Maps = desactivados
- Compresión =
Ninguna/ Sin comprimir - PPU consistente en todos los sprites de la escena
- Pivotes de sprites configurados en Modo Personalizado / Píxeles — un pivote central en un sprite de dimensión impar (ej. 15×15) cae en 7.5px, causando desalineación de 0.5px
→ Código: references/sprite-settings.cs — GetImporter() y FixSpriteImportSettings().
Configuración de ajuste (snap) del Editor:
- Tamaño de cuadrícula =
1 / assetsPPUen todos los ejes (ej. PPU 16 → 0.0625, PPU 100 → 0.01) - Ajuste de cuadrícula habilitado en la superposición de Cuadrícula y Ajuste
- Para ajustar GameObjects existentes: selecciónalos → Alinear Seleccionados → Todos los Ejes
Configuración de cámara:
- Proyección de cámara = Ortográfica
- Componente Pixel Perfect Camera presente y del tipo correcto para el pipeline
-
allowHDR,allowMSAA,allowDynamicResolutiontodos enfalse - La vista de Escena muestra dos cuadros delimitadores verdes en el gizmo de la cámara — sólido = área visible, punteado = resolución de referencia
→ Código: references/camera-setup-urp.cs — configuración completa de cámara URP + PP Camera.
→ Código: references/camera-setup-builtin.cs — configuración independiente Built-in.
Configuración de calidad del proyecto:
- Anti-Aliasing = 0 en Configuración de Calidad
- Filtrado Anisotrópico = Desactivado
Referencia de API
Tablas completas de propiedades/métodos, valores de enumeración GridSnapping y CropFrame, y configuraciones recomendadas:
→ references/api-reference.md — léelo al escribir o revisar código de configuración de cámara.
Resumen rápido de enumeraciones:
GridSnapping: None · PixelSnapping (estándar) · UpscaleRenderTexture (baja resolución auténtica; incompatible con post-procesado y texto UI)
CropFrame: None · Pillarbox · Letterbox · Windowbox (valor predeterminado más seguro) · StretchFill
Resolución de Referencia
Elige antes de construir cualquier activo. Nunca cambies después de que comience la producción de activos.
| Resolución de referencia | 1080p | 1440p | 4K |
|---|---|---|---|
| 320 × 180 | 6× | 8× | 12× |
| 480 × 270 | 4× | ~5.3× | 8× |
| 640 × 360 | 3× | 4× | 6× |
320×180 es la opción general más segura. Para pantallas sin ajuste entero (ej. 1366×768), usa cropFrame = Windowbox para agregar barras negras en lugar de estirar a una escala fraccionaria.
Migración y Compatibilidad
Proyecto URP con el componente independiente Built-in
Síntoma: DetectPipeline() devuelve URP pero la cámara tiene UnityEngine.U2D.PixelPerfectCamera. Los síntomas son sutiles porque el componente independiente tiene código condicional ENABLE_URP.
Corrección:
- Elimina
com.unity.2d.pixel-perfectdel Administrador de Paquetes - Elimina
UnityEngine.U2D.PixelPerfectCamerade cada cámara - Agrega
UnityEngine.Rendering.Universal.PixelPerfectCamera - Reconfigura — los booleanos (
pixelSnapping,upscaleRT,cropFrameX/Y) se convierten en enumeraciones (gridSnapping,cropFrame)
→ Código de detección: references/pipeline-detection.cs (al final del archivo).
Espacio de nombres URP antiguo (pre-Unity 2022 / URP pre-13.x)
Síntoma: Errores de compilación que referencian UnityEngine.Experimental.Rendering.Universal.
Corrección: Reemplaza using UnityEngine.Experimental.Rendering.Universal; con using UnityEngine.Rendering.Universal;. Actualiza cualquier cadena de tipo calificado por ensamblado. El atributo [MovedFrom] maneja la serialización automáticamente — los componentes en GameObjects sobreviven a la actualización.
Problemas Comunes y Soluciones
Sprites borrosos
Corrección: Configura Filter Mode en Point en todos los sprites del ámbito, desactiva Mip Maps, desactiva AA en Configuración de Calidad.
→ Código: references/sprite-settings.cs
Espacios entre tiles del Tilemap
Trabaja en orden: las soluciones alternativas como espacio negativo entre celdas o PPU = 31.99 se rompen cuando la cámara se mueve.
| # | Verificación | Corrección |
|---|---|---|
| 1 | ¿Sprite Atlas con Tight Packing desactivado, Padding ≥ 4, Sprite Packer Mode habilitado? | Habilita Sprite Packer Mode en la configuración del Editor; en el atlas, establece Padding ≥ 4 y desactiva Tight Packing |
| 2 | ¿Mipmaps desactivados en las texturas del tileset y el atlas? | Desactiva Generate Mip Maps |
| 3 | ¿AA = 0, MSAA desactivado en la cámara? | Desactiva AA globalmente |
| 4 | ¿Compresión = Ninguna? | RGBA 32 bits sin comprimir |
| 5 | ¿Todos los sprites de tiles tienen dimensiones de píxeles pares? | Las dimensiones impares causan un desplazamiento de cuadrícula de 0.5px |
| 6 | ¿PPU = ancho de píxel del tile? (16×16 → PPU 16) | La falta de coincidencia de PPU deja espacios físicos |
| 7 | ¿Solo espacios durante el movimiento de la cámara después de pasar todo lo anterior? | Usa pixel snapping de PP Camera; no uses cellGap = -0.01f |
Conflicto con Cinemachine
Causa: Tanto Cinemachine como Pixel Perfect Camera escriben en el tamaño ortográfico cada fotograma.
Corrección: Agrega la extensión CinemachinePixelPerfect a través del menú desplegable Agregar Extensión en cada Cámara Virtual. No lo agregues mediante AddComponent en código.
Limitaciones conocidas:
- Las transiciones de cámara entre cámaras virtuales no son perfectas en píxeles durante las transiciones
UpscaleRenderTexturereduce los tamaños ortográficos perfectos en píxeles válidos, lo que puede desviar el encuadre- Target Group + Framing Transposer causa entrecortamiento visible (no hay corrección disponible)
Desenfoque de post-procesado con upscaleRT
Causa: El post-procesado se ejecuta después de que la PP Camera escala la textura de renderizado.
Corrección simple: Desactiva upscaleRT. El post-procesado entonces se ejecuta en la resolución nativa de la pantalla.
Corrección avanzada (Unity 6 URP): Inyecta un ScriptableRendererFeature2D en RenderPassEvent2D.AfterRenderingPostProcessing. Usa clases base específicas para 2D — ScriptableRendererFeature (clase base 3D) se ignora silenciosamente en un renderizador 2D de URP.
Texto UI borroso con upscaleRT
Estado: Limitación conocida de U