Path: blob/main/examples/stress_tests/many_gradients.rs
6849 views
//! Stress test demonstrating gradient performance improvements.1//!2//! This example creates many UI nodes with gradients to measure the performance3//! impact of pre-converting colors to the target color space on the CPU.45use argh::FromArgs;6use bevy::{7color::palettes::css::*,8diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},9math::ops::sin,10prelude::*,11ui::{12BackgroundGradient, ColorStop, Display, Gradient, InterpolationColorSpace, LinearGradient,13RepeatedGridTrack,14},15window::{PresentMode, WindowResolution},16winit::{UpdateMode, WinitSettings},17};1819const COLS: usize = 30;2021#[derive(FromArgs, Resource, Debug)]22/// Gradient stress test23struct Args {24/// how many gradients per group (default: 900)25#[argh(option, default = "900")]26gradient_count: usize,2728/// whether to animate gradients by changing colors29#[argh(switch)]30animate: bool,3132/// use sRGB interpolation33#[argh(switch)]34srgb: bool,3536/// use HSL interpolation37#[argh(switch)]38hsl: bool,39}4041fn main() {42let args: Args = argh::from_env();43let total_gradients = args.gradient_count;4445println!("Gradient stress test with {total_gradients} gradients");46println!(47"Color space: {}",48if args.srgb {49"sRGB"50} else if args.hsl {51"HSL"52} else {53"OkLab (default)"54}55);5657App::new()58.add_plugins((59LogDiagnosticsPlugin::default(),60FrameTimeDiagnosticsPlugin::default(),61DefaultPlugins.set(WindowPlugin {62primary_window: Some(Window {63title: "Gradient Stress Test".to_string(),64resolution: WindowResolution::new(1920, 1080).with_scale_factor_override(1.0),65present_mode: PresentMode::AutoNoVsync,66..default()67}),68..default()69}),70))71.insert_resource(WinitSettings {72focused_mode: UpdateMode::Continuous,73unfocused_mode: UpdateMode::Continuous,74})75.insert_resource(args)76.insert_resource(WinitSettings::continuous())77.add_systems(Startup, setup)78.add_systems(Update, animate_gradients)79.run();80}8182fn setup(mut commands: Commands, args: Res<Args>) {83commands.spawn(Camera2d);8485let rows_to_spawn = args.gradient_count.div_ceil(COLS);8687// Create a grid of gradients88commands89.spawn(Node {90width: percent(100),91height: percent(100),92display: Display::Grid,93grid_template_columns: RepeatedGridTrack::flex(COLS as u16, 1.0),94grid_template_rows: RepeatedGridTrack::flex(rows_to_spawn as u16, 1.0),95..default()96})97.with_children(|parent| {98for i in 0..args.gradient_count {99let angle = (i as f32 * 10.0) % 360.0;100101let mut gradient = LinearGradient::new(102angle,103vec![104ColorStop::new(RED, percent(0)),105ColorStop::new(BLUE, percent(100)),106ColorStop::new(GREEN, percent(20)),107ColorStop::new(YELLOW, percent(40)),108ColorStop::new(ORANGE, percent(60)),109ColorStop::new(LIME, percent(80)),110ColorStop::new(DARK_CYAN, percent(90)),111],112);113114gradient.color_space = if args.srgb {115InterpolationColorSpace::Srgba116} else if args.hsl {117InterpolationColorSpace::Hsla118} else {119InterpolationColorSpace::Oklaba120};121122parent.spawn((123Node {124width: percent(100),125height: percent(100),126..default()127},128BackgroundGradient(vec![Gradient::Linear(gradient)]),129GradientNode { index: i },130));131}132});133}134135#[derive(Component)]136struct GradientNode {137index: usize,138}139140fn animate_gradients(141mut gradients: Query<(&mut BackgroundGradient, &GradientNode)>,142args: Res<Args>,143time: Res<Time>,144) {145if !args.animate {146return;147}148149let t = time.elapsed_secs();150151for (mut bg_gradient, node) in &mut gradients {152let offset = node.index as f32 * 0.01;153let hue_shift = sin(t + offset) * 0.5 + 0.5;154155if let Some(Gradient::Linear(gradient)) = bg_gradient.0.get_mut(0) {156let color1 = Color::hsl(hue_shift * 360.0, 1.0, 0.5);157let color2 = Color::hsl((hue_shift + 0.3) * 360.0 % 360.0, 1.0, 0.5);158159gradient.stops = vec![160ColorStop::new(color1, percent(0)),161ColorStop::new(color2, percent(100)),162ColorStop::new(163Color::hsl((hue_shift + 0.1) * 360.0 % 360.0, 1.0, 0.5),164percent(20),165),166ColorStop::new(167Color::hsl((hue_shift + 0.15) * 360.0 % 360.0, 1.0, 0.5),168percent(40),169),170ColorStop::new(171Color::hsl((hue_shift + 0.2) * 360.0 % 360.0, 1.0, 0.5),172percent(60),173),174ColorStop::new(175Color::hsl((hue_shift + 0.25) * 360.0 % 360.0, 1.0, 0.5),176percent(80),177),178ColorStop::new(179Color::hsl((hue_shift + 0.28) * 360.0 % 360.0, 1.0, 0.5),180percent(90),181),182];183}184}185}186187188