Skip to content

Commit 55b786c

Browse files
rparrettmockersf
andauthored
Fix blurry text (#12429)
# Objective Fixes #12064 ## Solution Prior to #11326, the "global physical" translation of text was rounded. After #11326, only the "offset" is being rounded. This moves things around so that the "global translation" is converted to physical pixels, rounded, and then converted back to logical pixels, which is what I believe was happening before / what the comments above describe. ## Discussion This seems to work and fix an obvious mistake in some code, but I don't fully grok the ui / text pipelines / math here. ## Before / After and test example <details> <summary>Expand Code</summary> ```rust use std::f32::consts::FRAC_PI_2; use bevy::prelude::*; use bevy_internal::window::WindowResolution; const FONT_SIZE: f32 = 25.0; const PADDING: f32 = 5.0; fn main() { App::new() .add_plugins( DefaultPlugins.set(WindowPlugin { primary_window: Some(Window { resolution: WindowResolution::default().with_scale_factor_override(1.0), ..default() }), ..default() }), //.set(ImagePlugin::default_nearest()), ) .add_systems(Startup, setup) .run(); } fn setup(mut commands: Commands, asset_server: Res<AssetServer>) { commands.spawn(Camera2dBundle::default()); let font = asset_server.load("fonts/FiraSans-Bold.ttf"); for x in [20.5, 140.0] { for i in 1..10 { text( &mut commands, font.clone(), x, (FONT_SIZE + PADDING) * i as f32, i, Quat::default(), 1.0, ); } } for x in [450.5, 700.0] { for i in 1..10 { text( &mut commands, font.clone(), x, ((FONT_SIZE * 2.0) + PADDING) * i as f32, i, Quat::default(), 2.0, ); } } for y in [400.0, 600.0] { for i in 1..10 { text( &mut commands, font.clone(), (FONT_SIZE + PADDING) * i as f32, y, i, Quat::from_rotation_z(FRAC_PI_2), 1.0, ); } } } fn text( commands: &mut Commands, font: Handle<Font>, x: f32, y: f32, i: usize, rot: Quat, scale: f32, ) { let text = (65..(65 + i)).map(|a| a as u8 as char).collect::<String>(); commands.spawn(TextBundle { style: Style { position_type: PositionType::Absolute, left: Val::Px(x), top: Val::Px(y), ..default() }, text: Text::from_section( text, TextStyle { font, font_size: FONT_SIZE, ..default() }, ), transform: Transform::from_rotation(rot).with_scale(Vec2::splat(scale).extend(1.)), ..default() }); } ``` </details> Open both images in new tabs and swap back and forth. Pay attention to the "A" and "ABCD" lines. <details> <summary>Before</summary> <img width="640" alt="main3" src="https://github.com/bevyengine/bevy/assets/200550/248d7a55-d06d-433f-80da-1914803c3551"> </details> <details> <summary>After</summary> <img width="640" alt="pr3" src="https://github.com/bevyengine/bevy/assets/200550/26a9d292-07ae-4af3-b035-e187b2529ace"> </details> --------- Co-authored-by: François Mockers <[email protected]>
1 parent baaf4c8 commit 55b786c

File tree

1 file changed

+7
-4
lines changed
  • crates/bevy_ui/src/render

1 file changed

+7
-4
lines changed

crates/bevy_ui/src/render/mod.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -640,10 +640,13 @@ pub fn extract_uinode_text(
640640
// * Multiply by the rounded physical position by the inverse scale factor to return to logical coordinates
641641

642642
let logical_top_left = -0.5 * uinode.size();
643-
let physical_nearest_pixel = (logical_top_left * scale_factor).round();
644-
let logical_top_left_nearest_pixel = physical_nearest_pixel * inverse_scale_factor;
645-
let transform = Mat4::from(global_transform.affine())
646-
* Mat4::from_translation(logical_top_left_nearest_pixel.extend(0.));
643+
644+
let mut transform = global_transform.affine()
645+
* bevy_math::Affine3A::from_translation(logical_top_left.extend(0.));
646+
647+
transform.translation *= scale_factor;
648+
transform.translation = transform.translation.round();
649+
transform.translation *= inverse_scale_factor;
647650

648651
let mut color = LinearRgba::WHITE;
649652
let mut current_section = usize::MAX;

0 commit comments

Comments
 (0)