Search Unity

2D Pixel Perfect: How to set up your Unity project for retro 16-bit games

, Август 2, 2019

In our first 2D Pixel Perfect guide for retro games, we showed you how to set up the 2D Pixel Perfect tool and how 8-bit graphics were made back in the day. In this post, we fast-forward to the 16-bit era. With the help of Mega Cat Studios, you’ll learn how to create authentic art for Sega Genesis (or Mega Drive) and Super NES-style games using Unity settings, graphics structures, and color palettes.



Mega Cat Studios has turned the creation of highly accurate retro games into an art form. So much so, in fact, that several of their titles can also be acquired in cartridge form and played on retro consoles like the Sega Genesis.

Using 2D Pixel Perfect for retro games

Before you plunge into this post, we recommend you familiarize yourself with our previous retro guide, where we covered the 2D Pixel Perfect settings and how to recreate 8-bit-style graphics. 

With Unity 2019.2, 2D Pixel Perfect is now part of the 2D Renderer, which is in the Lightweight Render Pipeline (LWRP) package. 2D Pixel Perfect also exists as a standalone package (with the same functionality) for creators who don’t use LWRP. For this guide, we’ll show you how to set up the project in LWRP. 

Setting up a new project in Unity 2019.2 and LWRP

  1. In the Unity Hub, click New, select 2D, then name your project. 

2. To import the 2D Pixel Perfect package, click the Window menu in the toolbar and select Package Manager. In the pop-up window, select the Lightweight RP package, making sure you get version 6.9.0 or higher.

3. Next, you will configure the 2D Renderer in the Editor and create a new Pipeline Asset. In the Project window, right-click the Assets view and select Create > Rendering > Lightweight Render Pipeline > Pipeline Asset.

4. In the Assets view of the Project window, create a new 2D Renderer by right-clicking and selecting Create > Rendering > Lightweight Render Pipeline > 2D Renderer.

5. Select the Pipeline Asset you created. Select General, then change the Renderer Type from Forward Renderer to Custom.

6. Assign the 2D Renderer you created to the data field.

7. In the Graphics settings, set your Scriptable Render Pipeline Settings to use the new Pipeline Asset you created.

The 2D Renderer should now be configured, including the 2D Pixel Perfect Camera.

In Unity 2019.2, 2D Sprites can have a “Sprite-Lit” material, which allows them to react to 2D lighting conditions. If you are not using 2D lights in your project, make sure you have material that doesn’t require 2D Lights to make the Sprites visible, in which case you can change the material to “Sprites-Default.”

Setting up Pixel Perfect for 16-bit graphic styles

You need to add the Pixel Perfect Camera component to your Main Camera. We recommend checking Run In Edit Mode.

The Sega Genesis console has a resolution of 320×224 px (or a grid of 40×28 tiles of 8×8 pixels). That is the NTSC version. The Super NES has a resolution of 256×224 (30×28 tiles of 8×8 pixels) also in its NTSC version.

Using a height resolution of 224 px and designing assets with 8 PPU is recommended for both graphic styles.

Using a reference Sprite (shown is a full-screen 320×224 image from Sonic the Hedgehog for the Sega Genesis), you can observe how the Sprite at 8 pixels per unit (PPU) fits into a Scene view of the same resolution and PPU.

If you need a refresher on what each option does in the 2D Pixel Perfect Camera component, see our previous retro game blog post.

Creating authentic Genesis-style artwork

In this section, we’re going to cover the workflow for creating artwork that mimics the look of different consoles, as we did in our NES blog post. There are fewer restrictions than in an 8-bit project and more freedom with color, but the Genesis has its own limitations. We also think it’s important to explain how the original hardware works so you can apply those limitations to your own retro project.

Palettes and sub-palettes

Making the jump from 8- to 16-bit consoles gives you more options on more-sophisticated hardware. That said, the fundamentals of doing great NES artwork still apply. All of the graphics are still stored in 8×8 tiles, for instance, and then assembled into larger images, whether they’re Sprites or background elements. You still need to work within limited sub-palettes with a common transparent color, although 16 bits offers greater freedom in palettes in some ways. You will likely be relieved to hear that 16-bit consoles generally do not have a hard-coded color palette like their 8-bit counterparts, which means the available colors are greatly expanded from the NES. 

Next, the Genesis boasts sub-palettes that contain 15 colors plus the common color used for Sprite transparency and layer transparency. One of the weaknesses of designing art for Genesis comes from the sub-palettes, though. Sub-palettes can be freely assigned to either Sprites or background tiles, but the Genesis only allows four sub-palettes to be used at a time. Because of this, artists must be mindful of which colors are being used in a sub-palette so that they can be maximized for both Sprite and background use. A sub-palette for the Genesis usually contains colors that are being used by both backgrounds and Sprites in order to fit everything in cleanly.

Above is a Genesis scene and below are the sub-palettes used.

To create for any 16-bit platform, you need to work with an indexed palette. For this, Gimp can be an open-source alternative to Photoshop that allows a lot of indexed palette manipulation.

To create the indexed palette in Gimp, go to Image > Mode > Indexed… 

The Indexed Color Conversion window appears.

Set the Maximum number of colors to 15. You can use automatic dithering patterns, but these tend to look better when they’re created manually.

The image’s colors are now indexed. This information is automatically saved with the image so that the color index can be used. If you need to change the order of the colors in the index, you can simply right-click the color map and select Rearrange Colormap…

A pop-up menu appears, allowing you to drag and drop colors into a new order.

One popular trick for creating greater color depth is to control the palette along a specified raster line, much as parallax scrolling was achieved on the NES. The Genesis is capable of changing the sub-palette selections for the artwork along a specified raster line. This trick is frequently used to create the illusion that part of a level is underwater. The “underwater” colors are added to a completely separate sub-palette selection, and the sub-palette selection is loaded once a certain raster line is rendered on-screen.

Tile-based storage and loading on the original hardware

In general, 16-bit consoles do not load graphics tiles in the same way as 8-bit consoles do. 8-bit consoles will load Sprite and background tiles separately and in large chunks of data to avoid using a lot of processing power, while 16-bit consoles have the processing power for greater flexibility. They can load and swap out individual tiles on the fly, allowing you to load in only the graphics you need when you need them. This allows a greater range of artwork to be used within a single level or screen of a game. 

Another aspect that’s unique to the Genesis/Mega Drive is that graphic tile and palette data are not the only things being loaded into the console’s VRAM during the game. That can make designing art for the console tricky because the number of graphic tiles that can be loaded into memory at a given time varies depending on what else is going on in the game. Generally speaking, most games will allow enough space to load in ~1000 tiles, and if there is a dynamic element then the tiles can always be swapped in and out freely.

Tiles loaded into memory in the previous scene. The large blank space in the middle and the artifacts at the bottom are space to allocate enemies and other game elements in memory.

Although a greater range of available tiles can be loaded into VRAM at once, most of the time that extra freedom gets reserved for the Sprites, to allow for more varied animations and more types of Sprites on-screen at once. That means the basic design philosophy of using repeating segments of tiles tends to still be used a lot in 16-bit art so that the background doesn’t take up too much of the available space. The resolutions of the NES, Genesis, and SNES are all pretty similar, so 16×16 segments tend to be the starting point for these kinds of designs.

Here the artist used a pattern of clean 32×32 blocks to create the majority of the walkable space in the background.

Working with background layers

The Genesis/Mega Drive allows for two background layers to be active at once on the screen. This means that layered elements are more readily available for designing backgrounds. That said, it’s still only two layers, so the artist and developer might have to rely on some raster-line tricks in order to create greater depth in a scene. Luckily, because all of those can go onto a second layer, designers are free to place foreground objects in front of the background without breaking the illusion. 

Having a second layer also makes the use of Sprite-priority tricks to create foreground objects obsolete. Instead of having to repeatedly change Sprite priorities on the fly, now you can simply set the second background layer to display in front of the player, although more advanced layering might still require quick manipulation of Sprite priorities. The second background pane also features a sub-pane that can be used for heads-up displays (HUDs). The sub-pane will be locked in place and never scroll.

Due to the game’s top-down view, special tiles needed to be created for the tree in order to manipulate Sprite layer order.

Sprite limitations

When you work with Sprites there is greater freedom when making the jump to 16-bit. The Genesis/Mega Drive lets you have 80 Sprites on-screen at a time and about 20 on a single horizontal line before it stops rendering any new Sprites. Beyond that, Sprites are no longer counted as individual 8×8 tiles. The Genesis is capable of generating single Sprites made of multiple tiles. These can be as small as a single tile and as large as 4×4 tiles in size. Anything larger than that would still require making it out of multiple Sprites.

The final boss uses a large number of animated background elements, layers, and lots of Sprites. None of this would be possible on an 8-bit platform.

Dithering patterns and contrast

One of the defining features of 16-bit era artwork is the use of dithering. Games back then were displayed on CRT monitors, where pixels on-screen had a tendency to bleed into one another. Artists would take advantage of this fact by using dithering patterns in the artwork, so when one pixel bled into another in a repeating pattern it created the illusion of having more colors than were actually available. To this day, dithering is heavily used in pixel art, despite upgrades in our displays, to maintain an accurate aesthetic.

Dithering was used prominently in 16-bits. On a CRT, the pattern of pixels would blend together creating new colors or transparency effects that were not otherwise possible.

Of the two major 16-bit consoles, the Genesis/Mega Drive displays its colors with much greater contrast. This is also something you need to be aware of when choosing your sub-palettes. Making something with more muted and dull tones won’t end up looking quite how it’s expected to when it comes to actually rendering the image on hardware. Art should generally be created with a high-contrast color palette so the final result will stay in line with the artist’s original vision.

Creating authentic SNES-style artwork

For Super NES projects, we are still working with 8×8 pixels in size tiles/grid, so working with repeatable tiles is extremely useful. Generally speaking, these will be in some multiple of eight.

Color palette

The first fundamental difference between the Genesis/Mega Drive and the SNES pertains to the color palette. Much like the Mega Drive, the SNES does not have a hard-coded color palette, so you can choose their colors. 

The tricky thing about the SNES is that it uses 5 bits per pixel (BPP) colors, which aren’t very common today. You can address this by using Gimp to create artwork, then you can simply posterize the image to 32 shades of RGB, which will work out to 5 BPP colors, even if you didn’t save the image as such. This allows your image colors to display accurately on the console.


You can find this option in Gimp under Colors > Posterize… A pop-up window appears, where you can set the Posterize levels to 32 to create 5 BPP-compatible colors.

Screen-resolution considerations

The next big difference between the two systems pertains to screen resolution. Since SNES is the successor of NES, the two systems share similar screen resolutions. The internal resolution of the SNES is 256×224. This allows any images that are being rendered to display within the safe zones of most CRT televisions, so none of the image will be cut off. This resolution never changes, so this will be the image size an artist will need to use as a reference.

This image is set to use the full-screen resolution of the SNES, which is used in most of the screen modes.

Screen modes of the original hardware

This section provides a quick reference to what the various screen modes have to offer.

The most significant difference between the systems is that the SNES can render background graphics in seven different screen modes. The SNES is capable of rendering a total of 256 colors on-screen at one time in a single sub-palette in certain screen modes. Here are some of the most popular screen modes:

  • Mode 1: This is one of the most commonly used screen modes for the SNES. It boasts the best average showing of the console’s capabilities. Mode 1 allows you to have three background layers where two of them have their own 16-color sub-palette, and the final layer has a 4-color sub-palette.
  • Mode 3: This mode is generally used for larger static images like title screens and story screens. It boasts two background planes. The first uses a full 256-color sub-palette, and the second allows for a 16-color sub-palette.
  • Mode 7: This was one of the main features of the SNES. It was shown off in most of the promotional material for the console, Mode 7 was the first time that a home console was able to apply transformations to an image in real-time, allowing scaling, rotation, stretching, and skewing in the background plane. This was used to create the pseudo-3D effects seen in a lot of racing and flight games for SNES. 

The single background plane in Mode 7 is handled much differently than all other screen modes to allow these features to work. First, there is only a single 256-color background plane to work with, which means that all Sprites need to share their colors with the sub-palette of the background plane. Next, instead of working with the normal screen size of the SNES, a Mode 7 background plane is 1024×1024 pixels in size. It is then sized and adjusted to fit the screen however the designer wants.

The office uses Mode 1 with one sub-palette (the other two are for the UI). The Thanks for Playing screen uses Mode 3, which allowed the artist to take advantage of a 256-color palette.

Sprite sizes

After the complexity of the background screen modes, the rules for Sprites are relatively simple. The SNES has multiple different Sprite modes, much like the Mega Drive did, but with the hard limitation of only being able to use two different Sprite modes for the entirety of the game. 

Sprites can be 8×8, 16×16, 32×32 or 64×64. Not only that, but designers must choose from a predetermined list of Sprite size combinations. Games on the SNES can include the following combinations:

  • 8×8, 16×16
  • 8×8, 32×32
  • 8×8, 64×64
  • 16×16, 32×32
  • 16×16, 64×64
  • 32×32, 64×64

These sizes are “set in stone” once you choose them, and all Sprites in the game must conform to them. The SNES is capable of rendering 32 Sprites on a single horizontal raster line at a time, but boasts a hefty 128 Sprite limit on what can be shown on-screen at a time. Anything beyond that will not be rendered on-screen.

Fork Parker’s Crunch-Out used a combination of 32×32 and 16×16 for all of the Sprites in the game.

Sprites have eight 16-color sub-palettes to work with. Much like all retro consoles, the first color of any sub-palette is a common shared color that’s used for transparency. The extensive quantity of sub-palettes compared to the other consoles covered gives you greater freedom when choosing colors for Sprites. You just need to keep in mind that there’s a hard 256-color limit.

 

Next steps

We hope you enjoyed this post on how to create 8- and 16-bit retro games using 2D Pixel Perfect in the latest version of Unity.

We’re not done with 2D Pixel Perfect yet, as the feature will be verified for production in Unity 2019.3, and will also be more compatible with Cinemachine 2D.

Let us know how your own 2D Pixel Perfect project goes, and don’t forget to visit the 2D forum to engage with the Unity community and 2D development team.

Комментарии закрыты.

  1. I find it a bit odd that you discussed the bit depth of the SNES but not the Genesis…. The reason the Genesis «displays its colors with much greater contrast» is because its palette is stored in 3 bits-per-channel format, meaning it had fewer possible shades than the SNES.

    Also, «BPP» usually refers to the number of bits per *pixel,* not the number of bits per *palette entry.* For the reader’s reference: SNES uses 5 bits per *channel of a palette entry*, for a total of 15 bits per entry.

    Didn’t know about the posterize trick, though. That could be very handy! Now if only I could make it treat 248 as the top of a channel rather than 255….

  2. Do we have to go through lightweight RP or can we just use the pixel perfect package?

  3. These 8-bit and 16-bit Pixel Perfect posts are great! Thank you very much for creating them! :D
    A question, is there already in Unity a feature to natively (i.e: no use of shaders) indexed palette swapping? If it’s not, is it planned for the (hopefully not too distant) future? :)

    1. Thanks, we are glad you like them :) there’s no feature for that, but you can find some options on the Asset Store, for example: https://assetstore.unity.com/packages/tools/particles-effects/color-palette-swapper-131292

  4. There’s a bug where clicking UI elements becomes inaccurate if you use a custom 2D Renderer data in the LWRP Data.

  5. Hi, which version of Unity are you using? The available version of LWRP only goes up to 4.10.0

  6. This. Looks. Adorable!! Thanks for taking the time to write about this! Even though I mostly do 3D, I’m definitely gonna save this and look at it later. There’s something magical about this kind of pixel-art/art style… ah…

  7. Nice

  8. *Sigh* Someone delete this spam comment.

  9. «Since SNES is the predecessor of NES…» what?

    1. Thanks for spotting that, text is updated now

  10. I don’t get this it seems using the lightweight renderer stops pixel snap from working?

    1. Hi Joseph, make sure you look at the Game view and not the Scene view, you can also make sure that «Upscale Render Texture» is activated in the camera component, additionally in the menu Edit>Snap Settings…, you can define the minimum pixel size for the Snapping effect, Move X, Move Y, Move Z with value of 1 should work well

      1. Wenceslao Villanueva Jr

        Сентябрь 30, 2019 в 2:18 дп

        He is correct. It appears after including the LWRP, Pixel Perfect settings do not function in or out of editor anymore. I debugged it to the fact that OnPreCull, OnPreRender and OnPostRender don’t seem to be called anymore. Without OnPreCull called, the orthographic size does not get calculated. I struggled with this for a few hours and decided to just drop the LWRP in favor of getting going.

        1. Wenceslao Villanueva Jr

          Сентябрь 30, 2019 в 9:09 дп

          Ok, I just figured it out. Don’t import the Pixel Perfect Package from the Previous Blog Tutorial about 8-bit games. The new LWRP for 2D comes with an experimental pixel perfect component. You need to use that one on your camera. Not the one from the Pixel Perfect Camera. It’s posted on the forum and I’m not sure if I can link to it from here but search for «Experimental 2D Lights and Shader Graph support in LWRP»