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:
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.
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)
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 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.)
With rotation, it can be very difficult to get pixels lined up, and edge artifacts are common.
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.
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
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.