godotengine / godot

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

Pixel Bleeding #9422

Closed rokasv closed 6 years ago

rokasv commented 7 years ago

Running Godot 2.1.3v.stable.official

When using sub-pixel positioning, the texture of a sprite occasionally bleeds in values from the surrounding pixels in the spritesheet.

Bleeding: bleed

Spritesheet: bleed2

I believe this is a sampling issue in the texture shader used in the engine - you should sample from the center of the pixel, rather than the corner. The theory is reinforced by the fact that if I remove the borders from around the icons (creating a transparent border of 1 pixel for each one) the issue appears to be fixed.

In short, when sampling (0,0,10,10) should become (0.5,0.5,9.5,9.5) and this should be fixed.

reduz commented 7 years ago

in 2.1 you can disable filter for the texture, or in the image loader section of the project settings in 3.0 this problem should no longer exist

On Tue, Jun 27, 2017 at 6:02 PM, rokasv notifications@github.com wrote:

Running Godot 2.1.3v.stable.official

When using sub-pixel positioning, the texture of a sprite occasionally bleeds in values from the surrounding pixels in the spritesheet.

Bleeding: [image: bleed] https://user-images.githubusercontent.com/13801432/27609550-142a63a0-5b83-11e7-9742-bdfe5f0c9356.gif

Spritesheet: [image: bleed2] https://user-images.githubusercontent.com/13801432/27609569-237477e2-5b83-11e7-8f5f-10ec6fb336c9.PNG

I believe this is a sampling issue in the texture shader used in the engine - you should sample from the center of the pixel, rather than the corner. The theory is reinforced by the fact that if I remove the borders from around the icons (creating a transparent border of 1 pixel for each one) the issue appears to be fixed.

In short, when sampling (0,0,10,10) should become (0.5,0.5,9.5,9.5) and this should be fixed.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/9422, or mute the thread https://github.com/notifications/unsubscribe-auth/AF-Z2wHA9JmrLl0v2n6XbQf5Nf2-EVHVks5sIW33gaJpZM4OHL8b .

rokasv commented 7 years ago

All the filtering, scaling options are set as appropriate - the .gif is not scaled up, it's as rendered by the engine with camera zooming.

Is it safe to assume that this is not going to get patched in 2.1?

reduz commented 7 years ago

It's pretty strange to see this happening with all those options active, as it should not be a bug. There was also an use pixel snap option you can use, though not sure how useful it is. If you are using an atlas or region from sprite, try adjusting it a bit to see if itś fixed. Fixing it the same way as in 3.0 is pretty much impossible, as the 2D renderer is completely different in 2.1 and cant distinguish between a rect or polygon being drawn. In 3.0, it forcibiliy clamps the UV inside the shader to aviod bleeding.

On Tue, Jun 27, 2017 at 6:16 PM, rokasv notifications@github.com wrote:

All the filtering, scaling options are set as appropriate - the .gif is not scaled up, it's as rendered by the engine with camera zooming.

Is it safe to assume that this is not going to get patched in 2.1?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/9422#issuecomment-311487842, or mute the thread https://github.com/notifications/unsubscribe-auth/AF-Z21iKtPQS_iNMDy0pYnD6XOPCiZg3ks5sIXERgaJpZM4OHL8b .

rokasv commented 7 years ago

I had the same issue when using OpenGL in my own C++ engine. Offsetting the texture UV positions by 0.5 of a pixel in the shader to read from the pixel centers did fix the issue.

I'm sure you'd know how to implement it (either pass in the already offset texture coordinates for interpolation or calculate the area in the vertex shader), but probably are skeptical of the solution.

I do think it's simple enough to try and the benefits for pixel-based games are gigantic as the bleeding breaks the entire aesthetic. Otherwise, I do hope 3.0 actually patches this.

reduz commented 7 years ago

offsetting is not the solution, because you will move the bleeding to the other side, what I find strange is that hundred of users are doing games with this aesthetic and did not find a problem with filter disabled, so i'm not quite sure what's going on here

On Tue, Jun 27, 2017 at 6:39 PM, rokasv notifications@github.com wrote:

I had the same issue when using OpenGL in my own C++ engine. Offsetting the vertex UV positions by 0.5 of a pixel in the shader to read from the pixel centers did fix the issue.

I'm sure you'd know how to implement it (either pass in the already offset texture coordinates for interpolation or calculate the area in the vertex shader), but probably are skeptical of the solution.

I do think it's simple enough to try and the benefits for pixel-based games are gigantic as the bleeding breaks the entire aesthetic. Otherwise, I do hope 3.0 actually patches this.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/9422#issuecomment-311493947, or mute the thread https://github.com/notifications/unsubscribe-auth/AF-Z21rpJaYexh7h52cEV9XaQz2gLiu3ks5sIXaCgaJpZM4OHL8b .

rokasv commented 7 years ago

Offsetting not just the entire thing to one side - the sampled region becomes 1 pixel shorter in length and in height. If you sampled 4 pixel (2 by 2) texture, in the fragment shader instead of reading the texture using a quad from with vertices (0,0),(0,2),(2,0),(2,2), you would read from (0.5,0.5),(0.5,1.5),(1.5,0.5),(1.5,1.5).

I had found a link explaining the issue in detail, but this was a while back, so I'll edit it back in if I find it, but it is a common procedure rather than an ad-hoc thing I'm proposing.

reduz commented 7 years ago

yeah I understand, 3.0 actually does this. In 2.1 it's very difficult because the renderer is a lot more generic.

On Tue, Jun 27, 2017 at 6:54 PM, rokasv notifications@github.com wrote:

Offsetting not just the entire thing to one side - the sampled region becomes 1 pixel shorter in length and in height. If you sampled 4 pixel (2 by 2) texture, in the fragment shader instead of reading the texture using a quad from with vertices (0,0),(0,2),(2,0),(2,2), you would read from (0.5,0.5),(0.5,1.5),(1.5,0.5),(1.5,1.5).

I had found a link explaining the issue in detail, but this was a while back, so I'll edit it back in if I find it, but it is a common procedure rather than an ad-hoc thing I'm proposing.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/9422#issuecomment-311497315, or mute the thread https://github.com/notifications/unsubscribe-auth/AF-Z230Cp59LeLASgw9KRGCoixzZE1q9ks5sIXoMgaJpZM4OHL8b .

Zylann commented 7 years ago

I do have this problem too, though I didn't considered it as too bad because in my game it doesn't happen frequently so I didn't report it, but it does happen, especially on tilemaps using atlases. I use a variable camera zoom in my game, alongside non-pixel-perfect window, maybe it's related.

All the filtering, scaling options are set as appropriate - the .gif is not scaled up, it's as rendered by the engine with camera zooming.

Zooming = scaling so your sprite IS scaled ;)

reduz commented 7 years ago

Did you try your code in 3.0?

On Wed, Jun 28, 2017 at 9:37 AM, Marc notifications@github.com wrote:

I do have this problem too, though I didn't considered it as too bad because in my game it doesn't happen frequently so I didn't report it, but it does happen, especially on tilemaps using atlases.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/9422#issuecomment-311646828, or mute the thread https://github.com/notifications/unsubscribe-auth/AF-Z29XPvGnPvzMO_cTvGyNbJPlxpgHjks5sIkjxgaJpZM4OHL8b .

Zylann commented 7 years ago

My game is 2.1.3 and relatively big now so can't test it in 3.0, but could try to build a test project.

Calinou commented 6 years ago

@xsellier Please do not bump issues without contributing significant new information, use the 👍 reaction button on the issue's first post instead.

xsellier commented 6 years ago

Here an example of a project pixel-non-perfect.zip

Here an example of the image with a bleeding pixel (from godot engine 2.1.4): selection_638

Here the same picture zoomed using Krita (or using this https://github.com/smaldragon/Pixel-Art-Scaler): selection_639

Zylann commented 6 years ago

@xsellier I see no pixel bleeding here, only a pixel which underlying size isn't integer so they are drawn 1 screen px wider or taller depending on position. Bleeding becomes an actual problem if pixels outside of the sprite/rect end up being drawn (which create ugly coloured lines)

ghost commented 6 years ago

Not sure if this is the right place for this, but I'm getting a weird sprite bug that seems related:

sfffdsdf (The slow speed and jerkiness were caused by my screen-recording software and don't actually happen when running the project.)

Use Pixel Snap is enabled, and the Sprite node's scale has been left at (1, 1). I scaled the window's "test" dimensions to 4x its regular dimensions for visibility, but the stretch mode has been set to viewport so there shouldn't be any weird sub-pixel shenanigans.

The Sprite is a child of a KinematicBody2D moved by a move_and_slide() call. The KB2D starts off stationary and is being accelerated upwards at a rate of 1 px/sec^2 to a maximum velocity of 60 px/sec. When it hits 60 px/sec, the sprite distortion occurs. The problem only seems to occur when the maximum velocity is exactly 60 px/sec and the acceleration is a factor of 60. It also happens when it's being moved downwards.

Here's a test project I made that showcases the bug: Sprite Glitch Test.zip

I'm using Godot 3.0 1c0007b on Linux Mint 18.3 Sylvia x64

ghost commented 6 years ago

I went ahead and made a new issue for my specific problem: #14644

kubecz3k commented 6 years ago

First of all thank you for your report and sorry for the delay.

We released Godot 3.0 in January 2018 after 18 months of work, fixing many old issues either directly, or by obsoleting/replacing the features they were referring to.

We still have hundreds of issues whose relevance/reproducibility needs to be checked against the current stable version, and that's where you can help us. Could you check if the issue that you described initially is still relevant/reproducible in Godot 3.0 or any newer version, and comment about its current status here?

For bug reports, please also make sure that the issue contains detailed steps to reproduce the bug and, if possible, a zipped project that can be used to reproduce it right away. This greatly speeds up debugging and bugfixing tasks for our contributors.

Our Bugsquad will review this issue more in-depth in 15 days, and potentially close it if its relevance could not be confirmed.

Thanks in advance.

Note: This message is being copy-pasted to many "stale" issues (90+ days without activity). It might happen that it is not meaningful for this specific issue or appears oblivious of the issue's context, if so please comment to notify the Bugsquad about it.

akien-mga commented 6 years ago

Our Bugsquad will review this issue more in-depth in 15 days, and potentially close it if its relevance could not be confirmed.

As there was no update since the previous post, we close this issue.

If it is still relevant in the way it was described and discussed above, please comment to ask for it to be reevaluated. If it is only partly relevant, or if the original issue has changed, it would be better to open a new issue (potentially referring to this one) focused on the current state.

droqen commented 4 years ago

This is the only issue I found that is discussing something similar to the particular problem that I'm having. Rather than with purely subpixel positioning, though, the issue I have is with rotation - perhaps in combination with subpixel positioning?

0629-pixel-bleed

Note the specific issue is NOT the pixelated distortion of the sprite, it's just the bleed through at the edge. I am not sure if this is unexpected behaviour or avoidable, but when searching for a solution I came across this issue and thought my problem might be relevant.