For Text2d, add a way to round the text position to the nearest pixel
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
## What problem does this solve or what need does it fill?
When using `Text2d`, the text is almost always at least somewhat blurry, such as with this code:
```rust
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window { resolution: (100, 100).into(), ..default() }),
..default()
}))
.add_systems(Startup, startup)
.insert_resource(ClearColor(Color::WHITE))
.run();
}
fn startup(mut commands: Commands) {
commands.spawn(Camera2d);
commands.spawn((
Text2d::new("Test"),
TextColor(Color::BLACK),
TextFont { font_size: 16.0, ..default() },
));
}
```
In some cases, such as when using `Anchor::TOP_LEFT`, it's possible to manually round the translation of the text's transform component so that it's aligned with the pixel grid, which substantially reduces the blurriness. But that solution doesn't work with centered text (which my app needs).
Here's some screenshots demonstrating the issue: one with blurry text (with the above code, in Bevy 0.18) and one with less blurry text (with the above code with `bevy::sprite::Anchor::TOP_LEFT` added to the text entity):
If you zoom in, you can see that even the text in the right screenshot is still slightly blurry (though maybe not enough to matter). I don't know of any way to avoid this blurriness at the moment.
## What solution would you like?
My best idea so far is to add a marker component, something like `RoundToNearestPixel`, which can be added to entities containing a `Text2d` component, which will cause the rendered text to be rounded to the nearest pixel to avoid this blurriness.
## What alternative(s) have you considered?
For my particular use case, an immediate mode API for rendering text (similar to gizmos) might actually work better than the current `Text2d` API. Unfortunately the new text gizmo API doesn't look like it'll work for my use case because it only supports ASCII. Text gizmos also have some other issues at the moment (they're blurry in a similar way to `Text2d`, the text has an aliasing-like effect on some letters, and the text seems larger for a given font size than for `Text2d`) so the current version of text gizmos doesn't seem suitable for my use case.
## Additional context
Here's a screenshot of my WIP app demonstrating this issue (please ignore the details of the circuit in the screenshot, it's just for testing). Most of the text next to the circuit elements is at least somewhat blurry.
Here's a screenshot of the text "Hello worldΩ" rendered with `gizmos.text_2d` with font size 16 (which should be the same size as the text above), showing some of the issues with it:
Contributor guide
Research direction
Start by tracing the Text2d rendering path and how Anchor::TOP_LEFT affects positioning, then compare it with the gizmos.text_2d behavior mentioned in the issue. Define how a marker such as RoundToNearestPixel should work for centered text, and consider the issue done when Text2d can opt into pixel-aligned rendering without losing its requested anchor behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- computer-graphics, game-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100