godotengine / godotengine/godot
"Snap Controls to Pixel" only partially works
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Tested versions
v4.4.dev7.mono.official [46c8f8c5c]
### System information
Godot v4.4.dev7.mono - Windows 11 (build 22631) - Multi-window, 2 monitors - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 4070 Ti SUPER (NVIDIA; 32.0.15.6614) - 13th Gen Intel(R) Core(TM) i9-13900K (32 threads)
### Issue description
Snapping controls to pixels only works consistently for the position of the control, not its size.
I pasted a screenshot into Aseprite and zoomed to 25% (my game is scaled by 4x). It should look perfectly scaled, but the TextEdit and OptionButton nodes are blurry due to non-integer sizes:


Note that I had stretch mode set to CanvasItems for this screenshot (so the issue would be visible in Aseprite). Using Viewport stretching obviously renders at the correct pixel resolution, but causes other issues like the bottom row of pixels of some control nodes to occasionally be cut off.
In this screenshot, the first two control nodes have a height of 18.5, causing the bottom edge to blur. The first OptionButton has its text blurred due to the size, but the TextEdit at the top does not have this issue. The second OptionButton has a height of 19, which causes its text to render at a non-integer Y-position (9.5 offset from the top). The Position property of each node is snapped to an integer, but their sizes and internal nodes seem to ignore this.
### Steps to reproduce
In Project Settings:
- gui/common/snap_controls_to_pixels = On
- display/window/size/viewport_width = 640
- display/window/size/viewport_height = 360
- display/window/size/mode = Exclusive Fullscreen
- display/window/stretch/mode = viewport (for native pixel resolution, causes issues with rows of pixels being lost) or canvas_items (to test blurring when downscaling to viewport size)
- display/window/stretch/aspect = expand
- display/window/stretch/scale_mode = integer
### Minimal reproduction project (MRP)
N/A
Contributor guide
Research direction
Start by reproducing the issue with gui/common/snap_controls_to_pixels enabled and the listed viewport or canvas_items stretch settings. Search the implementation of that project setting and trace how Control sizes and internal content are positioned. Done means Control sizes and their rendered text or edges remain aligned to integer pixels without regressing the viewport-stretch behavior described.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, godot
- Domain
- game-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100