Procházet zdrojové kódy

Adjust StyleBoxFlat antialiasing to account for 2D stretch scale

This prevents the antialiasing feather from becoming too wide
at viewport sizes higher than the default, which can lead to blurry visuals.

This is adjusted to account for the 2D scale factor returned on the root
Window, so it takes both the `canvas_items` scaling and
`content_scale_factor` into account.
Hugo Locurcio před 1 rokem
rodič
revize
b43c47d6dd
2 změnil soubory, kde provedl 30 přidání a 9 odebrání
  1. 1 1
      doc/classes/Viewport.xml
  2. 29 8
      scene/resources/style_box_flat.cpp

+ 1 - 1
doc/classes/Viewport.xml

@@ -108,7 +108,7 @@
 			<return type="Transform2D" />
 			<description>
 				Returns the automatically computed 2D stretch transform, taking the [Viewport]'s stretch settings into account. The final value is multiplied by [member Window.content_scale_factor], but only for the root viewport. If this method is called on a [SubViewport] (e.g., in a scene tree with [SubViewportContainer] and [SubViewport]), the scale factor of the root window will not be applied. Using [method Transform2D.get_scale] on the returned value, this can be used to compensate for scaling when zooming a [Camera2D] node, or to scale down a [TextureRect] to be pixel-perfect regardless of the automatically computed scale factor.
-				[b]Note:[/b] Due to how pixel scaling works, the transform's X scale value may differ slightly from the Y scale, even when [member Window.content_scale_aspect] is set to a mode that preserves pixel aspect ratio. If [member Window.content_scale_aspect] is [constant Window.CONTENT_SCALE_ASPECT_IGNORE], the X value may differ [i]significantly[/i] from Y due to differences between the original aspect ratio and the window aspect ratio.
+				[b]Note:[/b] Due to how pixel scaling works, the returned transform's X and Y scale may differ slightly, even when [member Window.content_scale_aspect] is set to a mode that preserves the pixels' aspect ratio. If [member Window.content_scale_aspect] is [constant Window.CONTENT_SCALE_ASPECT_IGNORE], the X and Y scale may differ [i]significantly[/i].
 			</description>
 		</method>
 		<method name="get_texture" qualifiers="const">

+ 29 - 8
scene/resources/style_box_flat.cpp

@@ -30,6 +30,8 @@
 
 #include "style_box_flat.h"
 
+#include "scene/main/scene_tree.h"
+#include "scene/main/window.h"
 #include "servers/rendering_server.h"
 
 float StyleBoxFlat::get_style_margin(Side p_side) const {
@@ -407,10 +409,28 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
 	Rect2 infill_rect = style_rect.grow_individual(-adapted_border[SIDE_LEFT], -adapted_border[SIDE_TOP], -adapted_border[SIDE_RIGHT], -adapted_border[SIDE_BOTTOM]);
 
 	Rect2 border_style_rect = style_rect;
+
+	real_t aa_size_scaled = 1.0f;
+	if (aa_on) {
+		real_t scale_factor = 1.0f;
+		const SceneTree *tree = Object::cast_to<SceneTree>(OS::get_singleton()->get_main_loop());
+		if (tree) {
+			const Window *window = tree->get_root();
+			const Vector2 stretch_scale = window->get_stretch_transform().get_scale();
+			scale_factor = MIN(stretch_scale.x, stretch_scale.y);
+		}
+
+		// Adjust AA feather size to account for the 2D scale factor, so that
+		// antialiasing doesn't become blurry at viewport resolutions higher
+		// than the default when using the `canvas_items` stretch mode
+		// (or when using `content_scale_factor` values different than `1.0`).
+		aa_size_scaled = aa_size / scale_factor;
+	}
+
 	if (aa_on) {
 		for (int i = 0; i < 4; i++) {
 			if (border_width[i] > 0) {
-				border_style_rect = border_style_rect.grow_side((Side)i, -aa_size);
+				border_style_rect = border_style_rect.grow_side((Side)i, -aa_size_scaled);
 			}
 		}
 	}
@@ -456,26 +476,27 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
 		real_t aa_border_width_half[4];
 		real_t aa_fill_width[4];
 		real_t aa_fill_width_half[4];
+
 		if (draw_border) {
 			for (int i = 0; i < 4; i++) {
 				if (border_width[i] > 0) {
-					aa_border_width[i] = aa_size;
-					aa_border_width_half[i] = aa_size / 2;
+					aa_border_width[i] = aa_size_scaled;
+					aa_border_width_half[i] = aa_size_scaled * 0.5;
 					aa_fill_width[i] = 0;
 					aa_fill_width_half[i] = 0;
 				} else {
 					aa_border_width[i] = 0;
 					aa_border_width_half[i] = 0;
-					aa_fill_width[i] = aa_size;
-					aa_fill_width_half[i] = aa_size / 2;
+					aa_fill_width[i] = aa_size_scaled;
+					aa_fill_width_half[i] = aa_size_scaled * 0.5;
 				}
 			}
 		} else {
 			for (int i = 0; i < 4; i++) {
 				aa_border_width[i] = 0;
 				aa_border_width_half[i] = 0;
-				aa_fill_width[i] = aa_size;
-				aa_fill_width_half[i] = aa_size / 2;
+				aa_fill_width[i] = aa_size_scaled;
+				aa_fill_width_half[i] = aa_size_scaled * 0.5;
 			}
 		}
 
@@ -528,7 +549,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
 	}
 
 	// Compute UV coordinates.
-	Rect2 uv_rect = style_rect.grow(aa_on ? aa_size : 0);
+	Rect2 uv_rect = style_rect.grow(aa_on ? aa_size_scaled : 0);
 	uvs.resize(verts.size());
 	Point2 *uvs_ptr = uvs.ptrw();
 	for (int i = 0; i < verts.size(); i++) {