Saturday, October 29, 2016

scale - What makes scaling pixel art different than other images?


Recently I was coaching a developer who's new to making pixel art games, and realized there's some "conventional wisdom" around scaling pixel art that's not obvious to a newcomer, and might not be well documented. So, here's an attempt to fix that....






  1. I've heard I should only scale pixel art by 200%, 300% etc. not in-between sizes like 120%




    • Why is that? Shouldn't scaling "just work" the way it does with other images?

    • What if I really need to make my character just a fraction larger or smaller to get the right gameplay or look? How do I fix this?




  2. I'm told it's "bad" to use pixel art at different scales in one game - why?



    • For example, if I scaled up my character so each sprite texel is 4x4 screen pixels, while my background art is scaled up so each sprite texel is 6x6 screen pixels. Isn't a pixel a pixel at the end of the day?






Answer



Scaling by Whole Numbers


Scaling by 2x, 3x...nx is simple - each pixel just becomes an nxn square of pixels, and the look of the original sprite is perfectly preserved (including all the sharp lines, corners, and staircase zig-zags).


We run into trouble though when scaling pixel art by a fractional amounts (eg. 1.5x) because pixels are discrete by nature. We can't really have "half a pixel."


For other kinds of art we can often get away with blending adjacent source pixels where the pixel should be "half coloured," and at high resolutions the artifacts usually aren't noticeable. But on big chunky pixel art this quickly destroys the crisp look.


So instead we'll usually use "Nearest Neighbour" filtering (also called Point filtering) so that each pixel after scaling takes its colour from exactly one pixel in the original sprite.


This has another wrinkle: since the number of pixels after scaling isn't a whole-number multiple of the number of source pixels, some source pixels will get duplicated more than others (if scaling up) or skipped entirely (if scaling down).


Unfortunately, image editing software and GPU texture filtering aren't very choosy about where they duplicate or skip pixels - they just follow basic rounding rules - which can make the result look distorted and uneven.


Check out the example below. In the middle we've scaled up the mushroom sprite by 150% using Nearest Neighbour filtering, and the result looks wonky and haphazard. One eye is bigger than the other, some outlines are thick while others stay thin, and the rounded spots look blocky... it doesn't look like something a pixel artist would draw on purpose.



Example of artifacts from using a non-integer scale


If we really need the sprite to be 150% bigger (say, to make the gameplay feel right, or to support alternate display resolutions), then we can repaint the problem areas like the example on the right. Now it looks more like something an artist would make, and stylistically consistent with other art in the game. (Though I'm not a great pixel artist myself, so it could still be better 😉)


Unfortunately there aren't a lot of great shortcuts for this. For whole-number scales, you can use specially-designed pixel art upscaling algorithms - a wide variety are available in tools like ImageResizer - to get a less blocky starting point than Nearest Neighbour, but it still takes an artist's eye and some elbow grease to get a high-quality result.




Aside: fractional scales can also crop up at runtime.


Imagine your game is in NES resolution (256 x 240), and you want to display it on a 1080p screen.


1080 ÷ 240 = 4.5, so some of the source pixels or "texels" in your scene get blown up to 5 screen pixels across, while others are only 4, creating distortions like we saw above. In motion they tend to make sprites ripple and shimmer distractingly, without an obvious cause:


Example of a fractional-scaled mushroom moving, showing rippling artifacts


You'll often see people suggest rounding camera or object positions to integer pixel coordinates, but that doesn't really fix the problem. Rounding already happens as part of the nearest neighbour filtering - the problem is that some screen pixels round to the same source texel (duplicating it), while others don't, leading to an uneven result.


The solution is to use a combination of padding/cropping or alternate asset sets to get back to a consistent, whole number ratio of screen pixels to texels for each display resolution you want to support - see some Unity examples here. This is another case where there's no easy universal fix, and you'll have to apply some judgement and artistry to keep your game looking sharp.



Keeping Pixel Scale Consistent


This "rule" comes down to stylistic consistency.


When you use pixel art at different scales, it can look like assets have been cobbled together from different games, instead having a unified aesthetic.


Example of scaling assets differently in a single game


In the example on the left, I put together some sprites from Super Mario World, all at the same scale, and it looks great.


In the middle, I scaled up Mario and the level to twice the resolution of the background, and the mole to triple the resolution. Since I used whole-number scales, we don't get distortions or ripples anywhere, but it still looks a little funny.


For one, the background is so much more detailed than the foreground. It's able to represent smooth curves and sharp highlights, which makes the foreground look particularly "blocky" in contrast, rather than having a consistent pixel art feel. And the mole's outlines are noticeably thicker and more jagged than the rest of the foreground.


At the right I show that again, by repainting the assets in a common pixel scale, we can bring back a more unified and intentional feel with the new asset sizes.


But Do I Have To?


No, not really. It's your game, and you can make it the way you want.



Especially when prototyping and finding the fun in your game, being able to try stuff fast is more important than having it look perfect. You'll probably get the size of important things like your character wrong many times before you find what's best for your game, and it would suck to have to repaint every animation frame each time you want to try something different. So, early on, don't sweat it.


For the released game, it's a judgement call. No pixel art police will ban you from distributing your game if you don't follow the rules, and many players wouldn't be able to describe the difference. But attention to these pixel details is something many players (and reviewers) consider an important sign of quality - so get to know your audience, and decide what's best for the experience you want to offer them.


One last consideration is that a lot of pixel art games have very high-precision gameplay. Think of hopping between 1-block platforms in the early Mega Man games. In these situations, a consistent pixel grid (and tile grid) can be an important cue for the player in judging and executing their moves. Introducing irregularity in the art might actually make the game harder to learn, which can be frustrating.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...