Edge Artifacts

When working with images, particularly ones with transparency, graphics cards can create graphic artifacts on their edges. Images can have ‘borders’ where they aren’t wanted. For example, here there’s a line on the top and left:

../../_images/p0.png

Why does this happen? How do we fix it?

Why Edge Artifacts Appear

This happens when the edge of an image does not fall cleanly onto an image.

Edge Mis-Alignment

Typically edge artifacts happen when the edge of an image doesn’t land on an exact pixel boundary. Below in Figure 1, the left image is 128 pixels square and drawn at (100, 100), and looks fine. The image on the right is drawn with a center of (100, 300.5) and has an artifact that shows up as a line on the left edge. That artifact will not appear if the sprite is drawn at (100, 300) instead of (100, 300.5)

../../_images/p1.png

Figure 1: Edge artifacts caused by images that aren’t on integer pixel boundaries.

The left edge falls on a coordinate of 300.5 - (128/2) = 236.5. The computer tries to select a color that’s an average between 236 and 237, but since there is no 237 we get a dark color. Typically this only happens if the edge is transparent.

A shape that has a height or width that is not evenly divisible by two can also cause artifacts. If the shape is 15 pixels wide, then the center will fall between the 7th and 8th pixel making it harder to line up the pixels to the screen.

Scaling

Scaling an image can also cause artifacts. In Figure 2, the second sprite is scaled down by two-thirds. Since 128 pixels doesn’t evenly scale down by two-thirds, we end up with edge artifacts. If we had scaled down by one-half, that is possible to do with 128 pixels (to 64), so there would be no artifacts.

The third image in Figure 2 is scaled up by a factor of two. The edge spans two pixels and we end up with a line artifact as well. (Scaling down by two usually works if the image is divisible by four. Scaling up typically doesn’t.)

../../_images/p2.png

Figure 2: Edge artifacts caused by scaling.

Rotating

With rotation, it can be very difficult to get pixels lined up, and edge artifacts are common.

Improper Viewport

If a window is 800 wide, and the viewport is set to 799 or 801, then lines can also appear. Alternatively, if a viewport left or right edge is set to a non-integer number such as 23.5, this can cause the artifacts to appear.

../../_images/p3.png

Figure 3: Incorrect viewport

Solutions

Keeping sprite sizes to a power of two or at least have a width and heights divisible by 2. For pixel-art types of games, using the pixelated drawing mode will greatly reduce the problem.

Aligning to the Nearest Pixel

By default, Arcade draws sprites with a filter called “linear” which makes for smoother scaling and lines. If instead you want a pixel-look, you can use a different filter called “nearest.” This filter also reduces issues with edge artifacts.

You enable the nearest filter using the pixelated argument when drawing

def on_draw(self):
    self.my_sprite_list.draw(pixelated=True)

Double-Check Viewport Code

Double-check your viewport code to make sure the edges are only set to integers and the size of the window matches up exactly, without any off-by-one errors.