godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
88.81k stars 20.14k forks source link

Region-selected Sprite2Ds, or AnimatedSprited2Ds created from spritesheets, sometimes show artifacts by rendering a part of their adjacent neighbor from the spritesheet (Easily reproducible). #95050

Open masoud-ata opened 1 month ago

masoud-ata commented 1 month ago

Tested versions

-Reproducible in Godot 4.3.rc2, 4.3rc1, all 4.3 betas, and 4.2.2.stable

System information

Windows 10 - v4.3.rc2.official - Vulkan (Forward+) Windows 10 - v4.3.rc2.official - Compatibility Windows 10 - v4.3.rc2.official - Mobile

Issue description

Let's say you have a spritesheet with 32x32 sprites. By creating a sprite or animated sprite from this sheet, if you choose to make your sprites exactly 32x32, this causes for the sprite above this one to sometimes appear for a moment, especially if you have a smoothing camera. Here is an example spritesheet with two 32x32 sprites, that is, a yellow block, and red spikes.

sheet

Now, in the still image below you can see the glitch on the 3 left spikes. These spikes have their region set to width and height of 32, so they touch the yellow sprite above in the sheet. But the two spikes on the right have a height of 31, so they have one pixel separation to the yellow sprite, and they don't show the artifact.

still

Now, this glitch doesn't happen all the time. I'd say it happens 1 out of every 20 times or something, but still, it happens a lot, and is clearly noticeable. Here's the gif of the above experiment, although sometimes you have to let the gif repeat to see the glitch.

sprite_artifact

Steps to reproduce

Create a project for pixel art games (nearest neighbor default and stretch mode set to viewport). Create a jumping player with a camera attached and smoothing enabled for the camera. Create a sprite from the a spritesheet, making sure it exactly touches the sprite right above it in the sheet (enable pixel snap). Create a ground and jump around the screen and behold the glitch! Maximizing the window or making it fullscreen, I think, makes it more visible or frequent.

Minimal reproduction project (MRP)

Sprite Artifact Test.zip

kleonc commented 1 month ago

Related: #76435, #81998.

System information

Windows 10 - v4.3.rc2.official - Vulkan (Forward+)

@masoud-ata Can you reproduce this in Compatibility/Mobile renderers as well?

masoud-ata commented 1 month ago

Related: #76435, #81998.

System information

Windows 10 - v4.3.rc2.official - Vulkan (Forward+)

@masoud-ata Can you reproduce this in Compatibility/Mobile renderers as well?

Yes, it's the same across all of these. I updated the System Information in the post.

Calinou commented 1 month ago

There is uneven pixel scaling going on, as evidenced by the sprites' look. Assuming your Camera2D zoom is an integer value already (or a divider of the form 1/2, 1/3, ...), make sure you've set the Stretch Scale Mode to integer in the Project Settings as described in the Multiple resolutions documentation.

masoud-ata commented 1 month ago

There is uneven pixel scaling going on, as evidenced by the sprites' look. Assuming your Camera2D zoom is an integer value already (or a divider of the form 1/2, 1/3, ...), make sure you've set the Stretch Scale Mode to integer in the Project Settings as described in the Multiple resolutions documentation.

Setting Stretch Scale Mode to integer didn't really help. I experimented a lot with the reproduction project I have on this post, and to make everything clean multiples of integers I set the viewport size to 640x480, with window overrides set to 1920x1440, with stretch mode of canvas_items, aspect keep, scale 1, and scale mode integer.

Now by running the game and switching to full screen, I can still see the artifacts. But I discovered something. Seemingly, the artifacts only show if there's a transparent border around the sprite, and I think only the top and left sides matter.

So for instance, I changed the sprite sheet to the following, and the green block in the middle with transparent pixels around it glitches sometimes at the top and left sides.

experiment

NibblyPig commented 3 weeks ago

I reported this issue with some others around a year ago now and it hasn't been fixed, none of the workarounds are reliable other than cutting your spritesheet up into individual frames. I would have thought this would be a priority issue as it's quite a fundamental thing to display a sprite from a spritesheet when making a 2D game.

masoud-ata commented 3 weeks ago

I reported this issue with some others around a year ago now and it hasn't been fixed, none of the workarounds are reliable other than cutting your spritesheet up into individual frames. I would have thought this would be a priority issue as it's quite a fundamental thing to display a sprite from a spritesheet when making a 2D game.

Yea, I wonder why. Maybe it's because this issue is not widespread, and happens under specific device-driver settings or what have you. Otherwise, it's super easily reproducible, extremely jarring, hard to miss, and, to me, feels like it should be a priority, as Godot prides itself in it 2D capabilities.