From 3475156ae35ef95b299f872aeb9d3a73efb14fa3 Mon Sep 17 00:00:00 2001
From: "Sabs, like Sobs" <57574500+sabslikesobs@users.noreply.github.com>
Date: Sat, 17 Feb 2024 17:59:22 +0000
Subject: [PATCH] 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/
---
doc/classes/AnimatedSprite2D.xml | 1 +
doc/classes/ProjectSettings.xml | 5 +++--
doc/classes/Sprite2D.xml | 1 +
scene/main/scene_tree.cpp | 4 ++--
4 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/doc/classes/AnimatedSprite2D.xml b/doc/classes/AnimatedSprite2D.xml
index 6eab2699053..4b387735052 100644
--- a/doc/classes/AnimatedSprite2D.xml
+++ b/doc/classes/AnimatedSprite2D.xml
@@ -84,6 +84,7 @@
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].
If [code]true[/code], texture is flipped horizontally.
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 2df34b0488f..d8f8b73ca4d 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -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.
- 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].
- 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].
@@ -2766,6 +2766,7 @@
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].
The default texture repeating mode to use on [CanvasItem]s.
diff --git a/doc/classes/Sprite2D.xml b/doc/classes/Sprite2D.xml
index f8622d8f386..e5c4c01d65b 100644
--- a/doc/classes/Sprite2D.xml
+++ b/doc/classes/Sprite2D.xml
@@ -52,6 +52,7 @@
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].
If [code]true[/code], texture is flipped horizontally.
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 2cbcc8e33ee..6b3b2d62601 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -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.