Expose pixel snapping settings add pixel-art notes

This small in-engine documentation change aims to make it easier to
discover ways to handle pixel art aesthetics.

- I have moved 2D pixel snapping settings out of "Advanced." This now matches other pixel-art-friendly settings for
GUI Snapping and Default Texture filtering.
- I've added notes to the project settings and Sprite/AnimatedSprite sources to hint users towards better understanding of why pixelated sprites may not work correctly and what to do about it. This should help users make informed decisions for their needs.

Context: Proper handling of pixel art in Godot is routinely frustrating for new users: I, like others, assumed that Godot would act on pixels, not subpixels, when I was working a pixel art game. I was confused when my interpolations would appear blurry, and when pixel textures would be distorted for no apparent reason (this was because of centering).
I had naively thought that setting Linear interpolation would be the single "it's a pixel art game" toggle, but that only hid the underlying issues until later. I had no idea there was a snap-to-pixel option because it was hidden in the Advanced options, since my default assumption was that a pixel art game would want no subpixels at all.

Some references for the frustration:

- https://github.com/godotengine/godot/issues/82696
- https://www.reddit.com/r/godot/comments/fah25e/best_way_to_achieve_pixel_perfect_rendering/
- https://shaggydev.com/2021/09/21/project-setup-for-pixel-art/
This commit is contained in:
Sabs, like Sobs 2024-02-17 17:59:22 +00:00
parent 8f0c20ee8d
commit 3475156ae3
4 changed files with 7 additions and 4 deletions

View File

@ -84,6 +84,7 @@
</member>
<member name="centered" type="bool" setter="set_centered" getter="is_centered" default="true">
If [code]true[/code], texture will be centered.
[b]Note:[/b] For games with a pixel art aesthetic, textures may appear deformed when centered. This is caused by their position being between pixels. To prevent this, set this property to [code]false[/code], or consider enabling [member ProjectSettings.rendering/2d/snap/snap_2d_vertices_to_pixel] and [member ProjectSettings.rendering/2d/snap/snap_2d_transforms_to_pixel].
</member>
<member name="flip_h" type="bool" setter="set_flip_h" getter="is_flipped_h" default="false">
If [code]true[/code], texture is flipped horizontally.

View File

@ -2286,12 +2286,12 @@
[b]Note:[/b] This property is only read when the project starts. To change the 2D shadow atlas size at runtime, use [method RenderingServer.canvas_set_shadow_texture_size] instead.
</member>
<member name="rendering/2d/snap/snap_2d_transforms_to_pixel" type="bool" setter="" getter="" default="false">
If [code]true[/code], [CanvasItem] nodes will internally snap to full pixels. Their position can still be sub-pixel, but the decimals will not have effect. This can lead to a crisper appearance at the cost of less smooth movement, especially when [Camera2D] smoothing is enabled.
If [code]true[/code], [CanvasItem] nodes will internally snap to full pixels. Useful for low-resolution pixel art games. Their position can still be sub-pixel, but the decimals will not have effect. This can lead to a crisper appearance at the cost of less smooth movement, especially when [Camera2D] smoothing is enabled.
[b]Note:[/b] This property is only read when the project starts. To toggle 2D transform snapping at runtime, use [method RenderingServer.viewport_set_snap_2d_transforms_to_pixel] on the root [Viewport] instead.
[b]Note:[/b] [Control] nodes are snapped to the nearest pixel by default. This is controlled by [member gui/common/snap_controls_to_pixels].
</member>
<member name="rendering/2d/snap/snap_2d_vertices_to_pixel" type="bool" setter="" getter="" default="false">
If [code]true[/code], vertices of [CanvasItem] nodes will snap to full pixels. Only affects the final vertex positions, not the transforms. This can lead to a crisper appearance at the cost of less smooth movement, especially when [Camera2D] smoothing is enabled.
If [code]true[/code], vertices of [CanvasItem] nodes will snap to full pixels. Useful for low-resolution pixel art games. Only affects the final vertex positions, not the transforms. This can lead to a crisper appearance at the cost of less smooth movement, especially when [Camera2D] smoothing is enabled.
[b]Note:[/b] This property is only read when the project starts. To toggle 2D vertex snapping at runtime, use [method RenderingServer.viewport_set_snap_2d_vertices_to_pixel] on the root [Viewport] instead.
[b]Note:[/b] [Control] nodes are snapped to the nearest pixel by default. This is controlled by [member gui/common/snap_controls_to_pixels].
</member>
@ -2766,6 +2766,7 @@
</member>
<member name="rendering/textures/canvas_textures/default_texture_filter" type="int" setter="" getter="" default="1">
The default texture filtering mode to use on [CanvasItem]s.
[b]Note:[/b] For pixel art aesthetics, see also [member rendering/2d/snap/snap_2d_vertices_to_pixel] and [member rendering/2d/snap/snap_2d_transforms_to_pixel].
</member>
<member name="rendering/textures/canvas_textures/default_texture_repeat" type="int" setter="" getter="" default="0">
The default texture repeating mode to use on [CanvasItem]s.

View File

@ -52,6 +52,7 @@
<members>
<member name="centered" type="bool" setter="set_centered" getter="is_centered" default="true">
If [code]true[/code], texture is centered.
[b]Note:[/b] For games with a pixel art aesthetic, textures may appear deformed when centered. This is caused by their position being between pixels. To prevent this, set this property to [code]false[/code], or consider enabling [member ProjectSettings.rendering/2d/snap/snap_2d_vertices_to_pixel] and [member ProjectSettings.rendering/2d/snap/snap_2d_transforms_to_pixel].
</member>
<member name="flip_h" type="bool" setter="set_flip_h" getter="is_flipped_h" default="false">
If [code]true[/code], texture is flipped horizontally.

View File

@ -1803,10 +1803,10 @@ SceneTree::SceneTree() {
float mesh_lod_threshold = GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "rendering/mesh_lod/lod_change/threshold_pixels", PROPERTY_HINT_RANGE, "0,1024,0.1"), 1.0);
root->set_mesh_lod_threshold(mesh_lod_threshold);
bool snap_2d_transforms = GLOBAL_DEF("rendering/2d/snap/snap_2d_transforms_to_pixel", false);
bool snap_2d_transforms = GLOBAL_DEF_BASIC("rendering/2d/snap/snap_2d_transforms_to_pixel", false);
root->set_snap_2d_transforms_to_pixel(snap_2d_transforms);
bool snap_2d_vertices = GLOBAL_DEF("rendering/2d/snap/snap_2d_vertices_to_pixel", false);
bool snap_2d_vertices = GLOBAL_DEF_BASIC("rendering/2d/snap/snap_2d_vertices_to_pixel", false);
root->set_snap_2d_vertices_to_pixel(snap_2d_vertices);
// We setup VRS for the main viewport here, in the editor this will have little effect.