Open MiCurry opened 3 months ago
This is probably a precision or floating point issue. The way the missing pixels appear makes me think that perhaps it has to do with the inability to represent decimal in binary, but that's just a guess. Both the machines listed above are 32 bit. I'm not sure if it's the compiler, render, OS or monitor.
Others have suggested that perhaps it needs some padding like a traditional texture. Perhaps that is the case and something similar is needed for solid sprites?
I suspect this is float precision issue in the vertices itself.
We can add some crazy padding in the atlas to eliminate that issue (at least on my computer)
self.map: arcade.SpriteList = arcade.SpriteList(
use_spatial_hash=True,
atlas=arcade.TextureAtlas((2048, 2048), border=1024)
)
On descrete gpu I can see issue at zoom level 0.06999999999999926 or 0.07 when I round the value. I suspect it's probably slightly more noticeable on iGPUs.
One idea is to capture the emitted vertex data from the sprite shader and inspect it. We should also closely inspect projection and view matrix. Changing the way we calculate the vertices can also have an impact. Instead of using the center point and offset with the half size we can just calculate the corners applying the the width and the height.
We should also compare the instanced version of sprite shader. If that has the same issue there is something deeper.
In latest master you also need this
camera_viewport = arcade.Rect(0, self.width, 0, self.height, self.width, self.height, 0, 0)
self.camera = arcade.camera.Camera2D(viewport=camera_viewport, zoom=self.zoom)
In my case it's happening with nvidia rtx 2060
So, as commented in discord and as a reminder for anyone who may need it in the future:
First this problem is now much smaller with the recent changes in arcade (center pixel interpolation). But still they appear.
"Artifacts" can appear when applying small zoom levels to a camera
To avoid it:
1) Always set zoom levels to the power of 2 (2**-3, etc.) 2) Even doing so, artifacts may still appear if the zoom is small. To avoid this, create a custom atlas and set its border to a confortable number where (by trial and error) see that the artifacts disappear. 3) Note that changing the zoom level to an even smaller number will need for a bigger atlas border.
Atlas can be created like so:
# Default atlas border is 2.
my_atlas = arcade.DefaultTextureAtlas((512, 512), border=3, auto_resize=True)
# then just set the spritelist atlas to your custom atlas
my_sprite_list = arcade.SpriteList(atlas=my_atlas)
Tagging this to a doc issue. It's something we could potentially mention in the manual
Bug Report
Originally found by @alejcas.
A grid of SpriteSolidColors can produce missing pixels on some machines on some irrational zoom levels. These missing pixels appear as very small squares, but also as full lines depending on the zoom level. See the video below:
In this video, there are 25x25 squares (50 squares total) which all have a width and height of 32.
https://github.com/pythonarcade/arcade/assets/2590700/3ea0e1f0-21c5-4c3a-86db-583767d88c88
These missing pixels apparently only appear between the squares. In this example, the grid lines are set to same spacing as the squares.
https://github.com/pythonarcade/arcade/assets/2590700/2c23fe47-9af6-45a3-8e32-fed2390842c9
System Info
This apparently is machine dependent.
Happens on this Intel Mac:
Does not happen on this Windows machine:
Steps to reproduce/example code:
The below program produces the missing pixels, though, it appears to machine dependent. You can use the minus and equal key to subtract and add 0.01 zoom. You can use comma and period to increase or decrease the width and height of the squares and grid. Use 'g' to turn on or off the grid lines.