Droggelbecher / bevy-fast-tilemap

Lightning fast tilemaps for bevy.
MIT License
68 stars 13 forks source link

Screen door effect / gaps between tiles during camera pan/zoom. #49

Open phlafoo opened 3 weeks ago

phlafoo commented 3 weeks ago

Loving the performance with this crate! I just migrated from bevy_ecs_tilemap since I didn't really need per tile entities.

I'm having an issue with gaps appearing between tiles when the camera is moved around or zooming in/out.

The screen door effect should be visible for one frame in this clip where the camera is moving. For me it happens maybe once every 5-10 seconds while moving.

https://github.com/user-attachments/assets/df3aec05-61fe-4695-b1e9-def261d7f967

The gaps in between tiles should be visible here while the camera is zooming in and out.

https://github.com/user-attachments/assets/20dc0917-e7a6-45a2-8282-3f5302900af2

I have tried various map sizes from 36x36 to 1280x1280, I have tried 16x16 textures and 32x32 textures, and I have tried playing with window/camera settings but the issue persists.

It's worth noting that I have the default camera scale set so that 1 pixel in tile texture maps to 1 pixel on my display -- I get ugly pixel aliasing otherwise. If the mapping is not 1-to-1 then the lines appear much more frequently. The lines usually only appear for 1 frame but it is possible to set the camera zoom to get the lines to persist (but it's finicky to find the right zoom level).

I am not scaling/rotating the tilemap at all I am only updating the camera transform and scale of the OrthographicProjection.

If there are any tips on mitigating this or if you'd like a minimal example please let me know.

Droggelbecher commented 2 weeks ago

Hm that shouldnt be happening, esp not with power of two sizes and scale factor 1. Will take a look as soon as i have time, knowing your OS would certainly be helpful and perhaps if you could share a tileset with which the problem occurs.

Droggelbecher commented 2 weeks ago

Also: you observed this on latest master or some release?

phlafoo commented 2 weeks ago

I am using Windows 10. This is on latest master and I am using Bevy 0.14.1.

Here is a link to the tileset I am using for testing.

I did some more testing and found that the I can easily reproduce the screen door effect by setting the camera translation to any float ending with .5 (or very close to -- the margin gets larger with larger float values). The horizontal lines appear when the y coord of the camera ends in .5 and the vertical lines appear when the x coord ends in .5. Note this only applies to camera scale set to 1.0 with 1-to-1 pixel mapping.

image

Above settings results in screen door effect:

image

For the sparse lines that appear when not at camera scale 1.0 I couldn't really find a pattern but it did consistently appear at camera scale 0.6.

phlafoo commented 2 weeks ago

Did some more testing and found that the problem goes away if I remove all padding from the tileset. I would really like to keep the padding though. 😅

I have 1 pixel padding on the tileset and when I create the Map I am using vec2(1.0, 1.0) for both inner and outer padding (using with_padding()).

Droggelbecher commented 2 weeks ago

Sorry,likely won't have time to actually look into code yet before next weeks weekend or so. From your research I suspect that neighbouring tiles sometimes disagree about how to round to a texture position, similar as in https://github.com/Droggelbecher/bevy-fast-tilemap/issues/21 .

The black lines you see there are likely directly from your padding. Could you please try:

phlafoo commented 2 weeks ago

I tried 2x2, 8x8, and 16x16 padding (for 16x16 tiles) and they all had the black lines. What I have not tried is having the total pixel width/height of the tileset be a power of 2.

You are right that it is directly from the padding. The line color matches the padding color. When I made it transparent then the lines are whatever the background color is, which in my case is very dark.

For now I will use no padding as a workaround.

phlafoo commented 2 weeks ago

More things to report. Even with no padding there are some issues but they were harder to spot. I was still occasionally noticing screen dooring but it was yellow. I made the background tile black to make it easier to spot in this clip:

https://github.com/user-attachments/assets/4e673f0f-5b3a-4757-a9d6-f7f31d009bfb

This is happening because the pixels directly above my "empty" tile texture are yellow. Moving the empty texture to a different position in the atlas did resolve the issue for me. For reference I was experiencing the problem with the texture in the bottom right of the atlas which is 8 tiles wide and 6 tiles tall (16x16 no padding).

Then if I moved the background tile to the bottom right corner I would get the screen dooring again. So it seems to just be related to the position of the texture in the atlas.

I went back to try different texture positions with padding but I was still getting screen dooring.

Droggelbecher commented 2 weeks ago

I can reproduce the problem now and could narrow it down somewhat.

The most common occurrence for me is that the lower half triangle of the map shows vertical lines. On very specific ".5" positions I get also the horizontal ones in addition.

After some digging, here are some observations:

Best possible short-term workaround should be to have sufficiently "friendly" atlas texture (eg. power-of-two tile sizes, tile positions and number of tiles in each axis).

As for longer term solutions I'm thinking perhaps we should be rendering the tilemap per default on a single triangle (iirc that technique is actually used inside bevy somewhere). This is perhaps the cleanest approach, but the problem would still remain for custom meshes.

Droggelbecher commented 2 weeks ago

Ok another update: With a single-triangle mesh it seems to work if you also ensure the tile atlas image has a power-of-two size. @phlafoo would you like to take a look at the branch at the test_screen_door_effect example to see how that behaves for you?

phlafoo commented 2 weeks ago

I tried out test_screen_door_effect and it works as expected! I'm still on master so for my 16x16 tiles I resized the atlas image size to 256x256 with 1 pixel padding ( (17*15)+1 = 256 ) and the lines seem to be gone!

Hopefully you are able to resolve the issue fully but this is a good workaround for now. Thanks for your help.

Droggelbecher commented 2 weeks ago

@phlafoo is it ok if I put the tilemap you linked into the repo so we can keep test_screen_door_effect around (license-wise)?

phlafoo commented 1 week ago

Yes just note that the desert-esque textures are from the examples shipped with the Tiled program since I used that as a starting point.