How to do Pixel Perfect in Unity

What is it?

What is (my definition of) pixel perfect and why is it relevant? In Unity, objects are free to roam to any decimal co-ordinates whereas in “retro games” we often get the impression of integer co-ordinates because the low-resolutions result in “big-pixels”.

no-snap
Decimal co-ordinates are the default in Unity.
snap
Old games had low-resolution screens with big-pixels, nothing can be “in between a pixel”.

 

To get this effect, we have two options:

pro-cons

 

 

Unity’s developers have made a “Pixel Perfect Camera” component.

You can find an example project here: Unity-Technology’s GitHub (External).

NOTE: Examples and “pixel perfect camera” only work in Unity 2018.2 and above.

The Basics

The first thing is to implement the “big-pixel” look. The second thing is to make every pixel snap to the grid.

For big-pixels you could:

  1. Use the pixel perfect camera component’s “upscale rendering” option (best option)
  2. Implement upscale rendering yourself using render to texture (bad option)
  3. Change the PPU on every sprite that needs to render with big-pixels (worse option)
  4. Make the artwork 5x bigger in Photoshop (worst option)

Then, to avoid overlapping:

  1. Use the pixel perfect camera component’s “pixel snap” option (best option)
  2. Implement pixel snapping yourself using a script (bad option)
  3. Disable Unity physics and write your own physics code (worst option)

We want pixel snapping so that the artwork aligns perfectly to the screen AND upscale rendering so that no objects smaller than a big-pixel are rendered.

pixel-vs-upscale.png
Only doing “pixel snapping” allows details smaller than a big-pixel to show on the screen. Look at the irregular big-pixel sizes in the flame. Only doing “Upscale Rendering” averages any pixels which aren’t aligned to the big-pixel grid – sometimes making them disappear! Look at the flame, it’s no longer an oval shape because a whole column of pixels has disappeared.

Sadly, we can’t use pixel snapping and upscale rendering options on the Pixel Perfect Camera component – I’ve opened an issue on Github (External) to start the conversation.

On Captain Candleface, my work-around is to use pixel snapping AND manually ensure there are no objects rendering smaller than a big-pixel (i.e. 5×5). To do this, make sure every “Transform” has an integer scale and every “Sprite Texture” uses the same PPU.

Using Pixel Perfect Camera

It provides the following settings:

pixel-perfect-settings.JPG

To use pixel snapping:

  • Set “Assets Pixels Per Unit” to match your sprites (Captain Candleface uses 20 PPU).
  • Tick “Pixel Snapping” (this will disable upscale render texture).

Or, to use upscale rendering:

  • Enter the low-resolution to render at (it will be stretched to the output resolution).
    • For example, to render with 5×5 big-pixels at 1920×1080, we need (1920/5)x(1080/5) which is 384 x 216.
  • Select Upscale Render Texture (this will disable Pixel Snapping).

Use “Crop Frame” to add bars to the x and/or y. Use “Stretch Fill” to stretch the upscaled render so that it fits the screen resolution in x and/or y (e.g. 1920 x 1080). I recommend experimenting with these to get the best settings for your game.

Enabling Pixel Perfect Camera will update the camera’s “Orthographic size” to ( 0.5 * ( Reference Y / Assets PPU ) ).

For more information: 2D Pixel Perfect Package – Unity Documentation (External)

Get a Pixel Perfect Camera in your game!

NOTE: Your game will need to be in Unity 2018.2 and above.
If you created a game with an older version,
I recommend making a backup copy
before
opening with your newly installed Unity 2018.2
in case there are problems with the upgrading process

Your game is open in Unity 2018.2? Great!

Now, modify your “Packages/manifest.json” (or equivalent package.json) as below.

manifest.JPG

"com.unity.2d.pixel-perfect": "1.0.1-preview"

"registry": "https://staging-packages.unity.com"

Save it, and when you go back to the Unity window, it should tell you to hold on while it grabs the pixel-perfect preview package (requires Internet connection).

You now have a “Pixel-perfect camera” component to add to your camera.

pixel-perfect-comp

 

Did this post help? Did you have a good or a bad time? I’d love to hear your experience in the comments.

 

Edits

07 Nov 2018 – restructured the tutorial for simplicity, simpler explanation of PPU scaling, removed incorrect and confusing PPU instructions, shortened guide and added reference to Unity package docs.

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s