Pixel art sprites being cut off on the borders
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
Do you have the original texture? This is likely a bug with the fix to reduce border artifacts.
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!
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.
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 😅
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!!!
Fixed and merge in https://github.com/pythonarcade/arcade/pull/2355