-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix texture atlas generation when source sprite is larger than generated atlas #55095
Fix texture atlas generation when source sprite is larger than generated atlas #55095
Conversation
Thanks! And congrats for your first merged Godot contribution 🎉 |
@boruok Can you send the source images? |
Uh, I'm not sure I understand. is fence_grass.png supposed to be a generated texture atlas? That's the only image I see. What about the images you generated it from? |
@Giwayume if you generate atlas from given texture you can see that right red border doesn't render. |
Interesting edge case. |
@Giwayume im pretty sure that is src_width - 1 for (int xi = (xf > 0 ? int(xf) : 0); xi < (xt < src_width ? xt : src_width - 1); xi++) {
...
for (int xi = (xf < src_width ? int(xf) : src_width - 1); xi >= (xt > 0 ? xt : 0); xi--) {
... |
The original is (atlas_)width - 1, curious if this problem occurs on a 256px wide image in 3.4.stable. Actually, it adds 4px padding to everything so probably can't reproduce the problem in stable due to that. Bug saved by padding. It's gonna take me an hour to rebuild Godot after switching branches to find out either way. =( |
Fixes #41414.
The problem: atlas images getting cut off.
https://github.com/godotengine/godot/blob/3.4/editor/import/resource_importer_texture_atlas.cpp#L134
In this line, "xf" starts at the left margin in the original sprite frame (source) image. Which in my case is a 512x512 image with the eyeball in the middle and a lot of empty space around it. This 512x512 dimension is set to the
src_width
andsrc_height
variables respectively.The variables
width
andheight
in this function refer to the final atlas texture's width and height, which is 256x252 in this case. So the entire generated texture atlas (256x252) is smaller than a single source animation frame (512x512). That exposes this bug.It looks like in this loop it's limiting by the generated atlas's width when it's actually looping through the source image's pixels.
for (int xi = (xf > 0 ? int(xf) : 0); xi < (xt < width ? xt : width - 1); xi++) {
So instead it should limit by the source image's width.
for (int xi = (xf > 0 ? int(xf) : 0); xi < (xt < src_width ? xt : src_width - 1); xi++) {
This indeed produces the correct results. And it makes sense why the images were getting cut off before.
There's already code that guarantees you're not drawing outside of the destination atlas texture's dimensions.
https://github.com/godotengine/godot/blob/3.4/editor/import/resource_importer_texture_atlas.cpp#L147
This width/src_width variable swap seems to have been a type-o. I don't think the same coding problem is present on the y axis, because my sprites would have been clipped off vertically as well.