Replies: 2 comments
-
This comment by @clayjohn I believe is highly relevant to this discussion and worth reading for anyone interested: godotengine/godot#87847 (comment) Specifically, solution 2: "See if we can do something to improve the data coming in to the fragment shader (i.e. consider flooring + offsetting pixel positions in |
Beta Was this translation helpful? Give feedback.
-
It was also noted in https://chat.godotengine.org/channel/rendering?msg=75ce7jsZgTWTz8E3Z that having clamping of UV coordinates in the fragment shader was too slow on mobile targets to be on by default. If this is still an issue worth fixing, one other idea would be to slightly shrink the source rectangle to ensure that samples remain within the user-picked source rectangle even if some floating point rounding errors occur. |
Beta Was this translation helpful? Give feedback.
-
The problem
There have been multiple reports of sprites bleeding between spritesheets, such as godotengine/godot#67164, godotengine/godot#95050, and godotengine/godot#81998. I have also encountered this issue myself on a project I was helping with.
Part of what I believe makes this issue difficult to resolve is that not all machines can reproduce it, and there are similar-sounding issues with entirely different root causes and solutions. There has even some disagreement over whether this is an engine bug to begin with, and much discussion has been focused on workaround the user could do rather than looking for a root cause. I wanted to start this discussion to try to focus more on the root cause aspect.
Root cause
I had detailed what I believe to be the root cause in a comment I wrote earlier (godotengine/godot#67164 (comment)). Put more briefly, the underlying rendering engine (OpenGL/Vulkan/etc.) is not guaranteed to use texture coordinates one might expect, as, due to floating point precision limitations, the texture coordinates for a fragment can lie outside the bounds set by the texture coordinates of the vertices for the triangle producing that fragment, even in the most basic rendering modes (no anti-aliasing).
This is most likely to happen when the edge of a triangle has pixel coordinates halfway between two integers (like 137.5). This problem is exacerbated by the fact that, at least on my graphics card, triangle vertex positions are rounded to the nearest 1/256 of a pixel before being rasterized, so triangles that would normally be too far from the halfway point to cause problems end up being snapped to this halfway point, making this bug much more frequently occurring than it otherwise would be.
Tentatively proposed solution
I believe that one solution to this would be to force the fragment shader to do its own clamping of texture coordinates to the source rectangle to better ensure that the source texture is always sampled in the expected area. There already exists code to do that (https://github.com/godotengine/godot/blob/b2b13d46c2fcd75502eec12c768caa23ee952900/servers/rendering/renderer_rd/shaders/canvas.glsl#L496), but that code is locked behind a flag that's off by default. Checking "Filter Clip Enabled" for Sprite2d enables that flag, but based on godotengine/godot#87847 (comment), I don't think that's its main purpose, so it might be better to do this clamping unconditionally, but I'm not sure.
One issue is that some epsilon fudge factors would also be needed somewhere to ensure that the coordinates we're clamping to actually lie within the part of the spritesheet the user intended, since floating point precision and various edge cases would still be able to cause sprite bleed otherwise.
I think it would make some sense to use a half-pixel fudge factor for this clamping, but based on godotengine/godot#12828, there are likely reasons this is considered too big.
I'm also not convinced this is the right solution for the underlying issue to begin with, as I do not have much experience with Godot's renderer. This is partially why I created a discussion instead of filing an issue or creating a PR.
Beta Was this translation helpful? Give feedback.
All reactions