Skip to content

Commit 4e2600b

Browse files
committed
text rendering: convert colours only once per section (#5474)
# Objective - Improve performance when rendering text ## Solution - While playing with example `many_buttons`, I noticed a lot of time was spent converting colours - Investigating, the biggest culprit seems to be text colour. Each glyph in a text is an individual UI node for rendering, with a copy of the colour. Making the conversion to RGBA linear only once per text section reduces the number of conversion done once rendering. - This improves FPS for example `many_buttons` from ~33 to ~42 - I did the same change for text 2d
1 parent 5666788 commit 4e2600b

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

crates/bevy_text/src/text2d.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use bevy_ecs::{
1111
use bevy_math::{Vec2, Vec3};
1212
use bevy_reflect::Reflect;
1313
use bevy_render::{
14+
prelude::Color,
1415
texture::Image,
1516
view::{ComputedVisibility, Visibility},
1617
Extract,
@@ -101,11 +102,16 @@ pub fn extract_text2d_sprite(
101102
HorizontalAlign::Right => Vec3::new(-width, 0.0, 0.0),
102103
};
103104

105+
let mut color = Color::WHITE;
106+
let mut current_section = usize::MAX;
104107
for text_glyph in text_glyphs {
105-
let color = text.sections[text_glyph.section_index]
106-
.style
107-
.color
108-
.as_rgba_linear();
108+
if text_glyph.section_index != current_section {
109+
color = text.sections[text_glyph.section_index]
110+
.style
111+
.color
112+
.as_rgba_linear();
113+
current_section = text_glyph.section_index;
114+
}
109115
let atlas = texture_atlases
110116
.get(&text_glyph.atlas_info.texture_atlas)
111117
.unwrap();

crates/bevy_ui/src/render/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,16 @@ pub fn extract_text_uinodes(
295295
let text_glyphs = &text_layout.glyphs;
296296
let alignment_offset = (uinode.size / -2.0).extend(0.0);
297297

298+
let mut color = Color::WHITE;
299+
let mut current_section = usize::MAX;
298300
for text_glyph in text_glyphs {
299-
let color = text.sections[text_glyph.section_index].style.color;
301+
if text_glyph.section_index != current_section {
302+
color = text.sections[text_glyph.section_index]
303+
.style
304+
.color
305+
.as_rgba_linear();
306+
current_section = text_glyph.section_index;
307+
}
300308
let atlas = texture_atlases
301309
.get(&text_glyph.atlas_info.texture_atlas)
302310
.unwrap();

0 commit comments

Comments
 (0)