pythonarcade / arcade

Easy to use Python library for creating 2D arcade games.
http://arcade.academy
Other
1.68k stars 319 forks source link

Pixel art sprites being cut off on the borders #2353

Open egeres opened 3 weeks ago

egeres commented 3 weeks ago

While using the latest version: https://github.com/pythonarcade/arcade/releases/tag/3.0.0-dev.33, it seems that rendering pixel-perfect images draws the border pixels in half?

My code is:

import arcade

class MyGame(arcade.Window):
    def __init__(self):
        super().__init__(800, 800)
        self.a = arcade.SpriteList()
        self.a.append(arcade.Sprite("grass_dark_0.png", scale=50))
        self.camera = arcade.Camera2D()

    def on_draw(self):
        self.clear()
        self.camera.use()
        self.a.draw(pixelated=True)

if __name__ == "__main__":
    window = MyGame()
    arcade.run()

I'm struggling to find new information about the usage of Camera2D, I'm not even sure if it's what I should be using for pixel-perfect graphics. Am I missing any parameters?

Edit 0:

This also seems to be happening with a sprite of scale 1 and a camera with zoom:

import arcade
from pyglet.math import Vec2

class MyGame(arcade.Window):
    def __init__(self):
        super().__init__(800, 800)
        self.a = arcade.SpriteList()
        self.a.append(arcade.Sprite("grass_dark_0.png"))
        self.camera = arcade.Camera2D(zoom=50)
        self.camera.bottom_left = Vec2(0, 0)

    def on_draw(self):
        self.clear()
        self.camera.use()
        self.a.draw(pixelated=True)

if __name__ == "__main__":
    window = MyGame()
    arcade.run()

Edit 1:

Checking out version 3.0.0.dev29 seems to solve the problem, I'm confused about this because for that I'm cloning the repo and running git checkout tags/3.0.0-dev.30, anyways, when I check out git checkout tags/3.0.0-dev.31, which would be version 3.0.0.dev30 the display breaks

I exported the atlas and texture images but they seem to be okay, my best guess is that the issue comes from the UV mapping being displaced 0.5 pixels inside or something

einarf commented 3 weeks ago

Do you have the original texture? This is likely a bug with the fix to reduce border artifacts.

egeres commented 3 weeks ago

Here it is! But I suspect the issue doesn't come from the texture itself, you just need a 16x16 .png image with distinguishable pixels. And yeah, what you're saying makes sense!

grass_dark_0

einarf commented 2 weeks ago

Thanks. We likely need to disable or tone down the uv offset when rendering in pixelated/nearest mode. It works great as long as you don't have scaling.

The uv offset needs to be moved into the geometry shader were we offset by 1.0 / atlas_size and multiply with some [0.0, 1.0] bias value based on the current texture interpolation. Possibly we modify the bias to 1.0 if there is no scale.

einarf commented 2 weeks ago

Started working on a fix here: https://github.com/pythonarcade/arcade/pull/2355

Quick preview: pip install -I https://github.com/pythonarcade/arcade/archive/refs/heads/uv-fix.zip

Also, thank you again for creating this issue. It was a pretty bad oversight 😅

egeres commented 2 weeks ago

It's okay! (I'm not sure how I would have tested for this) I tried solving this myself, but I'm not very familiar about how the UV mapping is made and I got lost in the code 😥

Other than that the library is going on a good direction and I'm impressed by the work this team has made, congratulations!!!