Calculate pixel snap in canvas space instead of world space #97260
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This ensures that you are actually snapping to pixels in the viewport and not an arbitrary amount
Fixes: #67164 and maybe others
During the 4.0 rewrite, we added the concept of a world matrix. In Godot 3, we didn't transform into world space ever. The modelview matrix transformed directly from model space into canvas space. In Godot 4 we do that transform in 2 stages and pixel snap was mistakenly done before the transformation to canvas space.
Accordingly, what this actually was doing was snapping to world space units instead of pixels. If your camera was aligned with world space such that a world space unit was the same as a canvas unit, it worked ok. But as soon as you zoom or rotate it would break.
Here is an MRP that really highlights the issue, it's adapted from #71074. Basically all it takes is a highly zoomed in camera. When running this in 4.3, the grid turns into a mess, and the player movement jumps several pixel at a time. With this PR it looks perfect.
PixelSnapMRP.zip
before
after